extend the PTRDIFF_MAX size check to mremap

This removes another way to obtain objects larger than PTRDIFF_MAX. The
only known remaining hole is now jemalloc's merging of virtual memory
spans.

Technically this could be wrapped in an __LP64__ ifndef since it can't
occur on 64-bit due to the 1:1 split. It doesn't really matter either
way.

Change-Id: Iab2af242b775bc98a59421994d87aca0433215bd
This commit is contained in:
Daniel Micay 2015-11-07 10:40:26 -05:00
parent 313632db57
commit c22a7de798
3 changed files with 25 additions and 0 deletions

View file

@ -27,6 +27,7 @@
*/
#include <errno.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>

View file

@ -26,12 +26,24 @@
* SUCH DAMAGE.
*/
#include <errno.h>
#include <sys/mman.h>
#include <stdarg.h>
#include <stdint.h>
#include <unistd.h>
#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.

View file

@ -219,3 +219,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 = 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));
}