diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-14 17:25:13 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-02-18 12:06:59 +0100 |
commit | 7d0d94e230b431e06937855e793ba5ffcfdad55e (patch) | |
tree | 94ec341aa15084330f37c4076a8e7c303e019bc9 /Zend/zend_alloc.c | |
parent | 3ef9f23fce327ab3d157c9d63c245f8a743e956d (diff) | |
download | php-git-7d0d94e230b431e06937855e793ba5ffcfdad55e.tar.gz |
Use mremap in zend_mm_chunk_extend if available
As suggested by https://twitter.com/grsecurity. This saves an
mmap+munmap cycle in case the mapping cannot be extended in-place.
Diffstat (limited to 'Zend/zend_alloc.c')
-rw-r--r-- | Zend/zend_alloc.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 505201a98c..139fb694e7 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -84,11 +84,6 @@ #include <errno.h> #ifndef _WIN32 -# ifdef HAVE_MREMAP -# ifndef _GNU_SOURCE -# define _GNU_SOURCE -# endif -# endif # include <sys/mman.h> # ifndef MAP_ANON # ifdef MAP_ANONYMOUS @@ -114,6 +109,12 @@ static size_t _real_page_size = ZEND_MM_PAGE_SIZE; # define REAL_PAGE_SIZE ZEND_MM_PAGE_SIZE #endif +/* NetBSD has an mremap() function with a signature that is incompatible with Linux (WTF?), + * so pretend it doesn't exist. */ +#ifndef __linux__ +# undef HAVE_MREMAP +#endif + #ifndef ZEND_MM_STAT # define ZEND_MM_STAT 1 /* track current and peak memory usage */ #endif @@ -410,6 +411,7 @@ stderr_last_error(char *msg) /* OS Allocation */ /*****************/ +#ifndef HAVE_MREMAP static void *zend_mm_mmap_fixed(void *addr, size_t size) { #ifdef _WIN32 @@ -438,6 +440,7 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size) return ptr; #endif } +#endif static void *zend_mm_mmap(size_t size) { @@ -797,7 +800,16 @@ static int zend_mm_chunk_extend(zend_mm_heap *heap, void *addr, size_t old_size, } } #endif -#ifndef _WIN32 +#ifdef HAVE_MREMAP + /* We don't use MREMAP_MAYMOVE due to alignment requirements. */ + void *ptr = mremap(addr, old_size, new_size, 0); + if (ptr == MAP_FAILED) { + return 0; + } + /* Sanity check: The mapping shouldn't have moved. */ + ZEND_ASSERT(ptr == addr); + return 1; +#elif !defined(_WIN32) return (zend_mm_mmap_fixed((char*)addr + old_size, new_size - old_size) != NULL); #else return 0; |