diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-08-07 22:27:07 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-08 10:55:36 +0200 |
commit | 78e7ff008b51a9a0f4383107359b8bbc5f1d9cee (patch) | |
tree | 8fad314dbe5dc867a6af23addc591639f54e8f69 /Userland/Libraries/LibC/sys/mman.cpp | |
parent | 146dcf48561a8cc872f23e3f2a42bb4e2c4f9bf0 (diff) | |
download | serenity-78e7ff008b51a9a0f4383107359b8bbc5f1d9cee.zip |
LibC: Fix negation overflow UB in `sys/mman.cpp`
When the system calls return `NumericLimits<ptrdiff_t>::min()`, negating
the return code would produce `NumericLimits<ptrdiff_t>::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.
Diffstat (limited to 'Userland/Libraries/LibC/sys/mman.cpp')
-rw-r--r-- | Userland/Libraries/LibC/sys/mman.cpp | 6 |
1 files 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; } |