summaryrefslogtreecommitdiff
path: root/Zend/zend_alloc.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-02-14 17:25:13 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-02-18 12:06:59 +0100
commit7d0d94e230b431e06937855e793ba5ffcfdad55e (patch)
tree94ec341aa15084330f37c4076a8e7c303e019bc9 /Zend/zend_alloc.c
parent3ef9f23fce327ab3d157c9d63c245f8a743e956d (diff)
downloadphp-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.c24
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;