diff --git a/libc/bionic/mmap.cpp b/libc/bionic/mmap.cpp index 9bc80a27e..8301445e1 100644 --- a/libc/bionic/mmap.cpp +++ b/libc/bionic/mmap.cpp @@ -27,6 +27,7 @@ */ #include +#include #include #include diff --git a/libc/bionic/mremap.cpp b/libc/bionic/mremap.cpp index 4892b1dd9..6653d439f 100644 --- a/libc/bionic/mremap.cpp +++ b/libc/bionic/mremap.cpp @@ -26,12 +26,24 @@ * SUCH DAMAGE. */ +#include #include #include +#include +#include + +#include "private/bionic_macros.h" extern "C" void* ___mremap(void*, size_t, size_t, int, void*); void* mremap(void* old_address, size_t old_size, size_t new_size, int flags, ...) { + // prevent allocations large enough for `end - start` to overflow + size_t rounded = BIONIC_ALIGN(new_size, PAGE_SIZE); + if (rounded < new_size || rounded > PTRDIFF_MAX) { + errno = ENOMEM; + return MAP_FAILED; + } + void* new_address = nullptr; // The optional argument is only valid if the MREMAP_FIXED flag is set, // so we assume it's not present otherwise. diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp index dffb646a5..ddb6c77a5 100644 --- a/tests/sys_mman_test.cpp +++ b/tests/sys_mman_test.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -219,3 +220,15 @@ TEST(sys_mman, posix_madvise_POSIX_MADV_DONTNEED) { TEST(sys_mman, mremap) { ASSERT_EQ(MAP_FAILED, mremap(nullptr, 0, 0, 0)); } + +const size_t huge = size_t(PTRDIFF_MAX) + 1; + +TEST(sys_mman, mmap_PTRDIFF_MAX) { + ASSERT_EQ(MAP_FAILED, mmap(nullptr, huge, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); +} + +TEST(sys_mman, mremap_PTRDIFF_MAX) { + void* map = mmap(nullptr, PAGE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(MAP_FAILED, map); + ASSERT_EQ(MAP_FAILED, mremap(map, PAGE_SIZE, huge, MREMAP_MAYMOVE)); +}