@@ -296,6 +296,20 @@ static bool zend_mm_use_huge_pages = false;
296296 */
297297
298298struct _zend_mm_heap {
299+ union { /* This union contains security-relevant properties, and is thus made read-only at run-time. */
300+ struct {
301+ uintptr_t shadow_key ; /* free slot shadow ptr xor key */
302+ #if ZEND_MM_CUSTOM
303+ struct {
304+ void * (* _malloc )(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
305+ void (* _free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
306+ void * (* _realloc )(void * , size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
307+ } custom_heap ;
308+ #endif
309+ };
310+ char padding [ZEND_MM_PAGE_SIZE ];
311+ };
312+
299313#if ZEND_MM_CUSTOM
300314 int use_custom_heap ;
301315#endif
@@ -306,7 +320,6 @@ struct _zend_mm_heap {
306320 size_t size ; /* current memory usage */
307321 size_t peak ; /* peak memory usage */
308322#endif
309- uintptr_t shadow_key ; /* free slot shadow ptr xor key */
310323 zend_mm_free_slot * free_slot [ZEND_MM_BINS ]; /* free lists for small sizes */
311324#if ZEND_MM_STAT || ZEND_MM_LIMIT
312325 size_t real_size ; /* current size of allocated pages */
@@ -330,11 +343,6 @@ struct _zend_mm_heap {
330343 int last_chunks_delete_boundary ; /* number of chunks after last deletion */
331344 int last_chunks_delete_count ; /* number of deletion over the last boundary */
332345#if ZEND_MM_CUSTOM
333- struct {
334- void * (* _malloc )(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
335- void (* _free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
336- void * (* _realloc )(void * , size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
337- } custom_heap ;
338346 HashTable * tracked_allocs ;
339347#endif
340348 pid_t pid ;
@@ -2103,6 +2111,9 @@ static zend_mm_heap *zend_mm_init(void)
21032111#endif
21042112 heap -> huge_list = NULL ;
21052113 heap -> pid = getpid ();
2114+
2115+ mprotect (heap , ZEND_MM_PAGE_SIZE , PROT_READ );
2116+
21062117 return heap ;
21072118}
21082119
@@ -2440,7 +2451,9 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
24402451 zend_hash_destroy (heap -> tracked_allocs );
24412452 free (heap -> tracked_allocs );
24422453 /* Make sure the heap free below does not use tracked_free(). */
2454+ mprotect (heap , ZEND_MM_PAGE_SIZE , PROT_WRITE );
24432455 heap -> custom_heap ._free = __zend_free ;
2456+ mprotect (heap , ZEND_MM_PAGE_SIZE , PROT_READ );
24442457 }
24452458 heap -> size = 0 ;
24462459 }
@@ -3063,6 +3076,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
30633076 mm_heap -> limit = (size_t )Z_L (-1 ) >> 1 ;
30643077 mm_heap -> overflow = 0 ;
30653078
3079+ mprotect (mm_heap , ZEND_MM_PAGE_SIZE , PROT_WRITE );
30663080 if (!tracked ) {
30673081 /* Use system allocator. */
30683082 mm_heap -> custom_heap ._malloc = __zend_malloc ;
@@ -3076,6 +3090,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
30763090 mm_heap -> tracked_allocs = malloc (sizeof (HashTable ));
30773091 zend_hash_init (mm_heap -> tracked_allocs , 1024 , NULL , NULL , 1 );
30783092 }
3093+ mprotect (mm_heap , ZEND_MM_PAGE_SIZE , PROT_READ );
30793094 return ;
30803095 }
30813096#endif
@@ -3141,14 +3156,18 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
31413156#if ZEND_MM_CUSTOM
31423157 zend_mm_heap * _heap = (zend_mm_heap * )heap ;
31433158
3159+ mprotect (_heap , ZEND_MM_PAGE_SIZE , PROT_WRITE );
31443160 if (!_malloc && !_free && !_realloc ) {
31453161 _heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE ;
31463162 } else {
31473163 _heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD ;
3164+ mprotect (heap , ZEND_MM_PAGE_SIZE , PROT_WRITE );
31483165 _heap -> custom_heap ._malloc = _malloc ;
31493166 _heap -> custom_heap ._free = _free ;
31503167 _heap -> custom_heap ._realloc = _realloc ;
3168+ mprotect (heap , ZEND_MM_PAGE_SIZE , PROT_READ );
31513169 }
3170+ mprotect (_heap , ZEND_MM_PAGE_SIZE , PROT_READ );
31523171#endif
31533172}
31543173
0 commit comments