@@ -217,6 +217,8 @@ typedef zend_mm_bitset zend_mm_page_map[ZEND_MM_PAGE_MAP_LEN]; /* 64B */
217
217
218
218
#define ZEND_MM_BINS 30
219
219
220
+ #define ZEND_MM_RO_HEAP (heap ) ((zend_mm_ro_heap*)((char*)(heap) + zend_mm_get_page_size()))
221
+
220
222
#if defined(_MSC_VER )
221
223
# if UINTPTR_MAX == UINT64_MAX
222
224
# define BSWAPPTR (u ) _byteswap_uint64(u)
@@ -263,6 +265,21 @@ typedef struct _zend_mm_huge_list zend_mm_huge_list;
263
265
264
266
static bool zend_mm_use_huge_pages = false;
265
267
268
+ static size_t zend_mm_get_page_size (void )
269
+ {
270
+ static size_t page_size = 0 ;
271
+
272
+ if (!page_size ) {
273
+ page_size = zend_get_page_size ();
274
+ if (!page_size || (page_size & (page_size - 1 ))) {
275
+ /* anyway, we have to return a valid result */
276
+ page_size = REAL_PAGE_SIZE ;
277
+ }
278
+ }
279
+
280
+ return page_size ;
281
+ }
282
+
266
283
/*
267
284
* Memory is retrieved from OS by chunks of fixed size 2MB.
268
285
* Inside chunk it's managed by pages of fixed size 4096B.
@@ -299,9 +316,6 @@ struct _zend_mm_heap {
299
316
#if ZEND_MM_CUSTOM
300
317
int use_custom_heap ;
301
318
#endif
302
- #if ZEND_MM_STORAGE
303
- zend_mm_storage * storage ;
304
- #endif
305
319
#if ZEND_MM_STAT
306
320
size_t size ; /* current memory usage */
307
321
size_t peak ; /* peak memory usage */
@@ -329,16 +343,27 @@ struct _zend_mm_heap {
329
343
double avg_chunks_count ; /* average number of chunks allocated per request */
330
344
int last_chunks_delete_boundary ; /* number of chunks after last deletion */
331
345
int last_chunks_delete_count ; /* number of deletion over the last boundary */
346
+ #if ZEND_MM_CUSTOM
347
+ HashTable * tracked_allocs ;
348
+ #endif
349
+
350
+ pid_t pid ;
351
+ zend_random_bytes_insecure_state rand_state ;
352
+ };
353
+
354
+ /* This contains security-sensitive data, and is thus mapped as read-only at run-time right after the _zend_mm_heap struct
355
+ * and accessed via the ZEND_MM_RO_HEAP macro.*/
356
+ struct _zend_mm_ro_heap {
357
+ #if ZEND_MM_STORAGE
358
+ zend_mm_storage * storage ;
359
+ #endif
332
360
#if ZEND_MM_CUSTOM
333
361
struct {
334
362
void * (* _malloc )(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
335
363
void (* _free )(void * ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
336
364
void * (* _realloc )(void * , size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC );
337
365
} custom_heap ;
338
- HashTable * tracked_allocs ;
339
366
#endif
340
- pid_t pid ;
341
- zend_random_bytes_insecure_state rand_state ;
342
367
};
343
368
344
369
struct _zend_mm_chunk {
@@ -349,7 +374,6 @@ struct _zend_mm_chunk {
349
374
uint32_t free_tail ; /* number of free pages at the end of chunk */
350
375
uint32_t num ;
351
376
char reserve [64 - (sizeof (void * ) * 3 + sizeof (uint32_t ) * 3 )];
352
- zend_mm_heap heap_slot ; /* used only in main chunk */
353
377
zend_mm_page_map free_map ; /* 512 bits or 64 bytes */
354
378
zend_mm_page_info map [ZEND_MM_PAGES ]; /* 2 KB = 512 * 4 */
355
379
};
@@ -837,8 +861,8 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
837
861
static void * zend_mm_chunk_alloc (zend_mm_heap * heap , size_t size , size_t alignment )
838
862
{
839
863
#if ZEND_MM_STORAGE
840
- if (UNEXPECTED (heap -> storage )) {
841
- void * ptr = heap -> storage -> handlers .chunk_alloc (heap -> storage , size , alignment );
864
+ if (UNEXPECTED (ZEND_MM_RO_HEAP ( heap ) -> storage )) {
865
+ void * ptr = ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_alloc (ZEND_MM_RO_HEAP ( heap ) -> storage , size , alignment );
842
866
ZEND_ASSERT (((uintptr_t )((char * )ptr + (alignment - 1 )) & (alignment - 1 )) == (uintptr_t )ptr );
843
867
return ptr ;
844
868
}
@@ -849,8 +873,8 @@ static void *zend_mm_chunk_alloc(zend_mm_heap *heap, size_t size, size_t alignme
849
873
static void zend_mm_chunk_free (zend_mm_heap * heap , void * addr , size_t size )
850
874
{
851
875
#if ZEND_MM_STORAGE
852
- if (UNEXPECTED (heap -> storage )) {
853
- heap -> storage -> handlers .chunk_free (heap -> storage , addr , size );
876
+ if (UNEXPECTED (ZEND_MM_RO_HEAP ( heap ) -> storage )) {
877
+ ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_free (ZEND_MM_RO_HEAP ( heap ) -> storage , addr , size );
854
878
return ;
855
879
}
856
880
#endif
@@ -860,9 +884,9 @@ static void zend_mm_chunk_free(zend_mm_heap *heap, void *addr, size_t size)
860
884
static int zend_mm_chunk_truncate (zend_mm_heap * heap , void * addr , size_t old_size , size_t new_size )
861
885
{
862
886
#if ZEND_MM_STORAGE
863
- if (UNEXPECTED (heap -> storage )) {
864
- if (heap -> storage -> handlers .chunk_truncate ) {
865
- return heap -> storage -> handlers .chunk_truncate (heap -> storage , addr , old_size , new_size );
887
+ if (UNEXPECTED (ZEND_MM_RO_HEAP ( heap ) -> storage )) {
888
+ if (ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_truncate ) {
889
+ return ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_truncate (ZEND_MM_RO_HEAP ( heap ) -> storage , addr , old_size , new_size );
866
890
} else {
867
891
return 0 ;
868
892
}
@@ -879,9 +903,9 @@ static int zend_mm_chunk_truncate(zend_mm_heap *heap, void *addr, size_t old_siz
879
903
static int zend_mm_chunk_extend (zend_mm_heap * heap , void * addr , size_t old_size , size_t new_size )
880
904
{
881
905
#if ZEND_MM_STORAGE
882
- if (UNEXPECTED (heap -> storage )) {
883
- if (heap -> storage -> handlers .chunk_extend ) {
884
- return heap -> storage -> handlers .chunk_extend (heap -> storage , addr , old_size , new_size );
906
+ if (UNEXPECTED (ZEND_MM_RO_HEAP ( heap ) -> storage )) {
907
+ if (ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_extend ) {
908
+ return ZEND_MM_RO_HEAP ( heap ) -> storage -> handlers .chunk_extend (ZEND_MM_RO_HEAP ( heap ) -> storage , addr , old_size , new_size );
885
909
} else {
886
910
return 0 ;
887
911
}
@@ -2045,7 +2069,7 @@ static void zend_mm_free_huge(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZE
2045
2069
2046
2070
static void zend_mm_refresh_key (zend_mm_heap * heap )
2047
2071
{
2048
- zend_random_bytes_insecure (& heap -> rand_state , & heap -> shadow_key , sizeof (heap -> shadow_key ));
2072
+ zend_random_bytes_insecure (& heap -> rand_state , & ( heap -> shadow_key ) , sizeof (heap -> shadow_key ));
2049
2073
}
2050
2074
2051
2075
static void zend_mm_init_key (zend_mm_heap * heap )
@@ -2056,16 +2080,22 @@ static void zend_mm_init_key(zend_mm_heap *heap)
2056
2080
2057
2081
static zend_mm_heap * zend_mm_init (void )
2058
2082
{
2083
+ zend_mm_heap * heap = (zend_mm_heap * )zend_mm_chunk_alloc_int (zend_mm_get_page_size () * 2 , zend_mm_get_page_size ());
2084
+ if (UNEXPECTED (heap == NULL )) {
2085
+ #if ZEND_MM_ERROR
2086
+ fprintf (stderr , "Can't initialize heap\n" );
2087
+ #endif
2088
+ return NULL ;
2089
+ }
2090
+
2059
2091
zend_mm_chunk * chunk = (zend_mm_chunk * )zend_mm_chunk_alloc_int (ZEND_MM_CHUNK_SIZE , ZEND_MM_CHUNK_SIZE );
2060
- zend_mm_heap * heap ;
2061
2092
2062
2093
if (UNEXPECTED (chunk == NULL )) {
2063
2094
#if ZEND_MM_ERROR
2064
2095
fprintf (stderr , "Can't initialize heap\n" );
2065
2096
#endif
2066
2097
return NULL ;
2067
2098
}
2068
- heap = & chunk -> heap_slot ;
2069
2099
chunk -> heap = heap ;
2070
2100
chunk -> next = chunk ;
2071
2101
chunk -> prev = chunk ;
@@ -2099,10 +2129,13 @@ static zend_mm_heap *zend_mm_init(void)
2099
2129
heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE ;
2100
2130
#endif
2101
2131
#if ZEND_MM_STORAGE
2102
- heap -> storage = NULL ;
2132
+ ZEND_MM_RO_HEAP ( heap ) -> storage = NULL ;
2103
2133
#endif
2104
2134
heap -> huge_list = NULL ;
2105
2135
heap -> pid = getpid ();
2136
+
2137
+ mprotect (ZEND_MM_RO_HEAP (heap ), zend_mm_get_page_size (), PROT_READ );
2138
+
2106
2139
return heap ;
2107
2140
}
2108
2141
@@ -2431,7 +2464,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2431
2464
2432
2465
#if ZEND_MM_CUSTOM
2433
2466
if (heap -> use_custom_heap ) {
2434
- if (heap -> custom_heap ._malloc == tracked_malloc ) {
2467
+ if (ZEND_MM_RO_HEAP ( heap ) -> custom_heap ._malloc == tracked_malloc ) {
2435
2468
if (silent ) {
2436
2469
tracked_free_all ();
2437
2470
}
@@ -2440,13 +2473,15 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2440
2473
zend_hash_destroy (heap -> tracked_allocs );
2441
2474
free (heap -> tracked_allocs );
2442
2475
/* Make sure the heap free below does not use tracked_free(). */
2443
- heap -> custom_heap ._free = __zend_free ;
2476
+ mprotect (ZEND_MM_RO_HEAP (heap ), zend_mm_get_page_size (), PROT_WRITE );
2477
+ ZEND_MM_RO_HEAP (heap )-> custom_heap ._free = __zend_free ;
2478
+ mprotect (ZEND_MM_RO_HEAP (heap ), zend_mm_get_page_size (), PROT_READ );
2444
2479
}
2445
2480
heap -> size = 0 ;
2446
2481
}
2447
2482
2448
2483
if (full ) {
2449
- heap -> custom_heap ._free (heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC );
2484
+ ZEND_MM_RO_HEAP ( heap ) -> custom_heap ._free (heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC );
2450
2485
}
2451
2486
return ;
2452
2487
}
@@ -2511,7 +2546,7 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent)
2511
2546
2512
2547
/* reinitialize the first chunk and heap */
2513
2548
p = heap -> main_chunk ;
2514
- p -> heap = & p -> heap_slot ;
2549
+ // p->heap = &p->heap_slot;
2515
2550
p -> next = p ;
2516
2551
p -> prev = p ;
2517
2552
p -> free_pages = ZEND_MM_PAGES - ZEND_MM_FIRST_PAGE ;
@@ -2575,7 +2610,7 @@ ZEND_API size_t ZEND_FASTCALL _zend_mm_block_size(zend_mm_heap *heap, void *ptr
2575
2610
{
2576
2611
#if ZEND_MM_CUSTOM
2577
2612
if (UNEXPECTED (heap -> use_custom_heap )) {
2578
- if (heap -> custom_heap ._malloc == tracked_malloc ) {
2613
+ if (ZEND_MM_RO_HEAP ( heap ) -> custom_heap ._malloc == tracked_malloc ) {
2579
2614
zend_ulong h = ((uintptr_t ) ptr ) >> ZEND_MM_ALIGNMENT_LOG2 ;
2580
2615
zval * size_zv = zend_hash_index_find (heap -> tracked_allocs , h );
2581
2616
if (size_zv ) {
@@ -2618,7 +2653,7 @@ ZEND_API bool is_zend_ptr(const void *ptr)
2618
2653
{
2619
2654
#if ZEND_MM_CUSTOM
2620
2655
if (AG (mm_heap )-> use_custom_heap ) {
2621
- if (AG (mm_heap )-> custom_heap ._malloc == tracked_malloc ) {
2656
+ if (ZEND_MM_RO_HEAP ( AG (mm_heap ) )-> custom_heap ._malloc == tracked_malloc ) {
2622
2657
zend_ulong h = ((uintptr_t ) ptr ) >> ZEND_MM_ALIGNMENT_LOG2 ;
2623
2658
zval * size_zv = zend_hash_index_find (AG (mm_heap )-> tracked_allocs , h );
2624
2659
if (size_zv ) {
@@ -2661,12 +2696,12 @@ ZEND_API bool is_zend_ptr(const void *ptr)
2661
2696
#if ZEND_MM_CUSTOM
2662
2697
# define ZEND_MM_CUSTOM_ALLOCATOR (size ) do { \
2663
2698
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \
2664
- return AG(mm_heap)->custom_heap._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2699
+ return ZEND_MM_RO_HEAP( AG(mm_heap) )->custom_heap._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2665
2700
} \
2666
2701
} while (0)
2667
2702
# define ZEND_MM_CUSTOM_DEALLOCATOR (ptr ) do { \
2668
2703
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \
2669
- AG(mm_heap)->custom_heap._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2704
+ ZEND_MM_RO_HEAP( AG(mm_heap) )->custom_heap._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2670
2705
return; \
2671
2706
} \
2672
2707
} while (0)
@@ -2762,7 +2797,7 @@ ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
2762
2797
{
2763
2798
#if ZEND_MM_CUSTOM
2764
2799
if (UNEXPECTED (AG (mm_heap )-> use_custom_heap )) {
2765
- return AG (mm_heap )-> custom_heap ._malloc (size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC ); \
2800
+ return ZEND_MM_RO_HEAP ( AG (mm_heap ) )-> custom_heap ._malloc (size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC ); \
2766
2801
}
2767
2802
#endif
2768
2803
return zend_mm_alloc_heap (AG (mm_heap ), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
@@ -2772,7 +2807,7 @@ ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_OR
2772
2807
{
2773
2808
#if ZEND_MM_CUSTOM
2774
2809
if (UNEXPECTED (AG (mm_heap )-> use_custom_heap )) {
2775
- AG (mm_heap )-> custom_heap ._free (ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2810
+ ZEND_MM_RO_HEAP ( AG (mm_heap ) )-> custom_heap ._free (ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2776
2811
return ;
2777
2812
}
2778
2813
#endif
@@ -2783,7 +2818,7 @@ ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC
2783
2818
{
2784
2819
#if ZEND_MM_CUSTOM
2785
2820
if (UNEXPECTED (AG (mm_heap )-> use_custom_heap )) {
2786
- return AG (mm_heap )-> custom_heap ._realloc (ptr , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2821
+ return ZEND_MM_RO_HEAP ( AG (mm_heap ) )-> custom_heap ._realloc (ptr , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2787
2822
}
2788
2823
#endif
2789
2824
return zend_mm_realloc_heap (AG (mm_heap ), ptr , size , 0 , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
@@ -2793,7 +2828,7 @@ ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size
2793
2828
{
2794
2829
#if ZEND_MM_CUSTOM
2795
2830
if (UNEXPECTED (AG (mm_heap )-> use_custom_heap )) {
2796
- return AG (mm_heap )-> custom_heap ._realloc (ptr , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2831
+ return ZEND_MM_RO_HEAP ( AG (mm_heap ) )-> custom_heap ._realloc (ptr , size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
2797
2832
}
2798
2833
#endif
2799
2834
return zend_mm_realloc_heap (AG (mm_heap ), ptr , size , 1 , copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC );
@@ -3057,25 +3092,28 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
3057
3092
tmp = getenv ("USE_ZEND_ALLOC" );
3058
3093
if (tmp && !ZEND_ATOL (tmp )) {
3059
3094
bool tracked = (tmp = getenv ("USE_TRACKED_ALLOC" )) && ZEND_ATOL (tmp );
3060
- zend_mm_heap * mm_heap = alloc_globals -> mm_heap = malloc (sizeof (zend_mm_heap ));
3095
+ ZEND_ASSERT (sizeof (zend_mm_heap ) <= zend_mm_get_page_size ());
3096
+ zend_mm_heap * mm_heap = alloc_globals -> mm_heap = malloc (zend_mm_get_page_size () * 2 );
3061
3097
memset (mm_heap , 0 , sizeof (zend_mm_heap ));
3062
3098
mm_heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD ;
3063
3099
mm_heap -> limit = (size_t )Z_L (-1 ) >> 1 ;
3064
3100
mm_heap -> overflow = 0 ;
3065
3101
3102
+ mprotect (ZEND_MM_RO_HEAP (mm_heap ), zend_mm_get_page_size (), PROT_WRITE );
3066
3103
if (!tracked ) {
3067
3104
/* Use system allocator. */
3068
- mm_heap -> custom_heap ._malloc = __zend_malloc ;
3069
- mm_heap -> custom_heap ._free = __zend_free ;
3070
- mm_heap -> custom_heap ._realloc = __zend_realloc ;
3105
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._malloc = __zend_malloc ;
3106
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._free = __zend_free ;
3107
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._realloc = __zend_realloc ;
3071
3108
} else {
3072
3109
/* Use system allocator and track allocations for auto-free. */
3073
- mm_heap -> custom_heap ._malloc = tracked_malloc ;
3074
- mm_heap -> custom_heap ._free = tracked_free ;
3075
- mm_heap -> custom_heap ._realloc = tracked_realloc ;
3110
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._malloc = tracked_malloc ;
3111
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._free = tracked_free ;
3112
+ ZEND_MM_RO_HEAP ( mm_heap ) -> custom_heap ._realloc = tracked_realloc ;
3076
3113
mm_heap -> tracked_allocs = malloc (sizeof (HashTable ));
3077
3114
zend_hash_init (mm_heap -> tracked_allocs , 1024 , NULL , NULL , 1 );
3078
3115
}
3116
+ mprotect (ZEND_MM_RO_HEAP (mm_heap ), zend_mm_get_page_size (), PROT_READ );
3079
3117
return ;
3080
3118
}
3081
3119
#endif
@@ -3145,9 +3183,11 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
3145
3183
_heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE ;
3146
3184
} else {
3147
3185
_heap -> use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD ;
3148
- _heap -> custom_heap ._malloc = _malloc ;
3149
- _heap -> custom_heap ._free = _free ;
3150
- _heap -> custom_heap ._realloc = _realloc ;
3186
+ mprotect (ZEND_MM_RO_HEAP (_heap ), zend_mm_get_page_size (), PROT_WRITE );
3187
+ ZEND_MM_RO_HEAP (_heap )-> custom_heap ._malloc = _malloc ;
3188
+ ZEND_MM_RO_HEAP (_heap )-> custom_heap ._free = _free ;
3189
+ ZEND_MM_RO_HEAP (_heap )-> custom_heap ._realloc = _realloc ;
3190
+ mprotect (ZEND_MM_RO_HEAP (_heap ), zend_mm_get_page_size (), PROT_READ );
3151
3191
}
3152
3192
#endif
3153
3193
}
@@ -3161,9 +3201,9 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3161
3201
zend_mm_heap * _heap = (zend_mm_heap * )heap ;
3162
3202
3163
3203
if (heap -> use_custom_heap ) {
3164
- * _malloc = _heap -> custom_heap ._malloc ;
3165
- * _free = _heap -> custom_heap ._free ;
3166
- * _realloc = _heap -> custom_heap ._realloc ;
3204
+ * _malloc = ZEND_MM_RO_HEAP ( _heap ) -> custom_heap ._malloc ;
3205
+ * _free = ZEND_MM_RO_HEAP ( _heap ) -> custom_heap ._free ;
3206
+ * _realloc = ZEND_MM_RO_HEAP ( _heap ) -> custom_heap ._realloc ;
3167
3207
} else {
3168
3208
* _malloc = NULL ;
3169
3209
* _free = NULL ;
@@ -3179,7 +3219,7 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
3179
3219
ZEND_API zend_mm_storage * zend_mm_get_storage (zend_mm_heap * heap )
3180
3220
{
3181
3221
#if ZEND_MM_STORAGE
3182
- return heap -> storage ;
3222
+ return ZEND_MM_RO_HEAP ( heap ) -> storage ;
3183
3223
#else
3184
3224
return NULL
3185
3225
#endif
@@ -3195,7 +3235,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3195
3235
#if ZEND_MM_STORAGE
3196
3236
zend_mm_storage tmp_storage , * storage ;
3197
3237
zend_mm_chunk * chunk ;
3198
- zend_mm_heap * heap ;
3238
+ zend_mm_heap * heap = ( zend_mm_heap * ) zend_mm_chunk_alloc_int ( REAL_PAGE_SIZE * 2 , REAL_PAGE_SIZE ) ;
3199
3239
3200
3240
memcpy ((zend_mm_handlers * )& tmp_storage .handlers , handlers , sizeof (zend_mm_handlers ));
3201
3241
tmp_storage .data = data ;
@@ -3206,7 +3246,6 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3206
3246
#endif
3207
3247
return NULL ;
3208
3248
}
3209
- heap = & chunk -> heap_slot ;
3210
3249
chunk -> heap = heap ;
3211
3250
chunk -> next = chunk ;
3212
3251
chunk -> prev = chunk ;
@@ -3239,7 +3278,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3239
3278
#if ZEND_MM_CUSTOM
3240
3279
heap -> use_custom_heap = 0 ;
3241
3280
#endif
3242
- heap -> storage = & tmp_storage ;
3281
+ ZEND_MM_RO_HEAP ( heap ) -> storage = & tmp_storage ;
3243
3282
heap -> huge_list = NULL ;
3244
3283
memset (heap -> free_slot , 0 , sizeof (heap -> free_slot ));
3245
3284
storage = _zend_mm_alloc (heap , sizeof (zend_mm_storage ) + data_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_CC );
@@ -3255,8 +3294,9 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3255
3294
storage -> data = (void * )(((char * )storage + sizeof (zend_mm_storage )));
3256
3295
memcpy (storage -> data , data , data_size );
3257
3296
}
3258
- heap -> storage = storage ;
3297
+ ZEND_MM_RO_HEAP ( heap ) -> storage = storage ;
3259
3298
heap -> pid = getpid ();
3299
+ mprotect (ZEND_MM_RO_HEAP (heap ), zend_mm_get_page_size (), PROT_READ );
3260
3300
return heap ;
3261
3301
#else
3262
3302
return NULL ;
0 commit comments