Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libc/src/__support/OSUtil/linux/auxv.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ LIBC_INLINE void Vector::fallback_initialize_unsync() {
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// We do not proceed if mmap fails.
if (mmap_ret <= 0 && mmap_ret > -EXEC_PAGESIZE)
if (!linux_utils::is_valid_mmap(mmap_ret))
return;

// Initialize the auxv array with AT_NULL entries.
Expand Down
14 changes: 14 additions & 0 deletions libc/src/__support/OSUtil/linux/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ LIBC_INLINE R syscall_impl(long __number, Ts... ts) {
return cpp::bit_or_static_cast<R>(syscall_impl(__number, (long)ts...));
}

// Linux-specific function for checking
namespace linux_utils {
LIBC_INLINE_VAR constexpr unsigned long MAX_ERRNO = 4095;
// Ideally, this should be defined using PAGE_OFFSET
// However, that is a configurable parameter. We mimic kernel's behavior
// by checking against MAX_ERRNO.
template <typename PointerLike>
LIBC_INLINE constexpr bool is_valid_mmap(PointerLike ptr) {
long addr = cpp::bit_cast<long>(ptr);
return __builtin_expect(addr > 0 || addr < -cpp::bit_cast<long>(MAX_ERRNO),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use LIBC_LIKELY from https://github.com/llvm/llvm-project/blob/main/libc/src/__support/macros/optimization.h#L27
and for casting signed / unsigned integers, static_cast should be good enough.

true);
}
} // namespace linux_utils

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_H
2 changes: 1 addition & 1 deletion libc/src/__support/threads/linux/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ LIBC_INLINE ErrorOr<void *> alloc_stack(size_t stacksize, size_t guardsize) {
-1, // Not backed by any file
0 // No offset
);
if (mmap_result < 0 && (uintptr_t(mmap_result) >= UINTPTR_MAX - size))
if (!linux_utils::is_valid_mmap(mmap_result))
return Error{int(-mmap_result)};

if (guardsize) {
Expand Down
2 changes: 1 addition & 1 deletion libc/src/sys/mman/linux/mmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ LLVM_LIBC_FUNCTION(void *, mmap,
// However, since a valid return address cannot be within the last page, a
// return value corresponding to a location in the last page is an error
// value.
if (ret < 0 && ret > -EXEC_PAGESIZE) {
if (!linux_utils::is_valid_mmap(ret)) {
libc_errno = static_cast<int>(-ret);
return MAP_FAILED;
}
Expand Down
2 changes: 1 addition & 1 deletion libc/startup/linux/aarch64/tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// We cannot check the return value with MAP_FAILED as that is the return
// of the mmap function and not the mmap syscall.
if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size)
if (!linux_utils::is_valid_mmap(mmap_ret_val))
syscall_impl<long>(SYS_exit, 1);
uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val));
uintptr_t tls_addr = thread_ptr + size_of_pointers + padding;
Expand Down
2 changes: 1 addition & 1 deletion libc/startup/linux/riscv/tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// We cannot check the return value with MAP_FAILED as that is the return
// of the mmap function and not the mmap syscall.
if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size)
if (!linux_utils::is_valid_mmap(mmap_ret_val))
syscall_impl<long>(SYS_exit, 1);
uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val));
uintptr_t tls_addr = thread_ptr + size_of_pointers + padding;
Expand Down
2 changes: 1 addition & 1 deletion libc/startup/linux/x86_64/tls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// We cannot check the return value with MAP_FAILED as that is the return
// of the mmap function and not the mmap syscall.
if (mmap_retval < 0 && static_cast<uintptr_t>(mmap_retval) > -app.page_size)
if (!linux_utils::is_valid_mmap(mmap_retval))
syscall_impl<long>(SYS_exit, 1);
uintptr_t *tls_addr = reinterpret_cast<uintptr_t *>(mmap_retval);

Expand Down
Loading