From 78e7ff008b51a9a0f4383107359b8bbc5f1d9cee Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 7 Aug 2021 22:27:07 +0200 Subject: [PATCH] LibC: Fix negation overflow UB in `sys/mman.cpp` When the system calls return `NumericLimits::min()`, negating the return code would produce `NumericLimits::max() + 1` since we are on a two's complement architecture. Because this value cannot be stored, signed overflow occurs which is UB. This can be fixed by applying the negation to `EMAXERRNO` since that's known to contain a relatively small value. Found when running tests with Clang. --- Userland/Libraries/LibC/sys/mman.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibC/sys/mman.cpp b/Userland/Libraries/LibC/sys/mman.cpp index 3f361e50a8..457ddd4393 100644 --- a/Userland/Libraries/LibC/sys/mman.cpp +++ b/Userland/Libraries/LibC/sys/mman.cpp @@ -17,7 +17,7 @@ void* serenity_mmap(void* addr, size_t size, int prot, int flags, int fd, off_t { Syscall::SC_mmap_params params { (uintptr_t)addr, size, alignment, prot, flags, fd, offset, { name, name ? strlen(name) : 0 } }; ptrdiff_t rc = syscall(SC_mmap, ¶ms); - if (rc < 0 && -rc < EMAXERRNO) { + if (rc < 0 && rc > -EMAXERRNO) { errno = -rc; return MAP_FAILED; } @@ -38,7 +38,7 @@ void* mremap(void* old_address, size_t old_size, size_t new_size, int flags) { Syscall::SC_mremap_params params { (uintptr_t)old_address, old_size, new_size, flags }; ptrdiff_t rc = syscall(SC_mremap, ¶ms); - if (rc < 0 && -rc < EMAXERRNO) { + if (rc < 0 && rc > -EMAXERRNO) { errno = -rc; return MAP_FAILED; } @@ -77,7 +77,7 @@ int madvise(void* address, size_t size, int advice) void* allocate_tls(const char* initial_data, size_t size) { ptrdiff_t rc = syscall(SC_allocate_tls, initial_data, size); - if (rc < 0 && -rc < EMAXERRNO) { + if (rc < 0 && rc > -EMAXERRNO) { errno = -rc; return MAP_FAILED; }