--- embedaddon/php/Zend/zend_alloc.c 2012/02/21 23:47:52 1.1.1.1 +++ embedaddon/php/Zend/zend_alloc.c 2012/05/29 12:34:35 1.1.1.2 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_alloc.c,v 1.1.1.1 2012/02/21 23:47:52 misho Exp $ */ +/* $Id: zend_alloc.c,v 1.1.1.2 2012/05/29 12:34:35 misho Exp $ */ #include "zend.h" #include "zend_alloc.h" @@ -32,10 +32,6 @@ # include #endif -#if SUHOSIN_PATCH -#include "suhosin_patch.h" -#endif - #ifdef ZEND_WIN32 # include # include @@ -63,7 +59,6 @@ # define PTR_FMT "0x%0.8lx" #endif -#ifndef SUHOSIN_MM_CLONE_FILE #if ZEND_DEBUG void zend_debug_alloc_output(char *format, ...) { @@ -81,7 +76,6 @@ void zend_debug_alloc_output(char *format, ...) #endif } #endif -#endif #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) static void zend_mm_panic(const char *message) __attribute__ ((noreturn)); @@ -140,8 +134,6 @@ static void zend_mm_panic(const char *message) # endif #endif -static zend_intptr_t SUHOSIN_POINTER_GUARD = 0; - static zend_mm_storage* zend_mm_mem_dummy_init(void *params) { return malloc(sizeof(zend_mm_storage)); @@ -340,36 +332,21 @@ static const zend_mm_mem_handlers mem_handlers[] = { #define MEM_BLOCK_GUARD 0x2A8FCC84 #define MEM_BLOCK_LEAK 0x6C5E8F2D -#if SUHOSIN_MM_WITH_CANARY_PROTECTION -# define CANARY_SIZE sizeof(size_t) -#else -# define CANARY_SIZE 0 -#endif - /* mm block type */ typedef struct _zend_mm_block_info { #if ZEND_MM_COOKIES size_t _cookie; #endif -#if SUHOSIN_MM_WITH_CANARY_PROTECTION - size_t canary_1; -#endif - size_t _size; - size_t _prev; -#if SUHOSIN_PATCH - size_t size; -#if SUHOSIN_MM_WITH_CANARY_PROTECTION - size_t canary_2; -#endif -#endif + size_t _size; + size_t _prev; } zend_mm_block_info; #if ZEND_DEBUG typedef struct _zend_mm_debug_info { - char *filename; + const char *filename; uint lineno; - char *orig_filename; + const char *orig_filename; uint orig_lineno; size_t size; #if ZEND_MM_HEAP_PROTECTION @@ -435,7 +412,7 @@ typedef struct _zend_mm_free_block { # define ZEND_MM_CACHE_STAT 0 #endif -typedef struct _zend_mm_heap { +struct _zend_mm_heap { int use_zend_alloc; void *(*_malloc)(size_t); void (*_free)(void*); @@ -462,6 +439,7 @@ typedef struct _zend_mm_heap { zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2]; zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS]; zend_mm_free_block *rest_buckets[2]; + int rest_count; #if ZEND_MM_CACHE_STAT struct { int count; @@ -470,9 +448,6 @@ typedef struct _zend_mm_heap { int miss; } cache_stat[ZEND_MM_NUM_BUCKETS+1]; #endif -#if SUHOSIN_PATCH - size_t canary_1,canary_2,canary_3; -#endif }; #define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \ @@ -485,6 +460,10 @@ typedef struct _zend_mm_heap { sizeof(zend_mm_free_block*) * 2 - \ sizeof(zend_mm_small_free_block)) +#define ZEND_MM_REST_BLOCK ((zend_mm_free_block**)(zend_uintptr_t)(1)) + +#define ZEND_MM_MAX_REST_BLOCKS 16 + #if ZEND_MM_COOKIES static unsigned int _zend_mm_cookie = 0; @@ -546,31 +525,18 @@ static unsigned int _zend_mm_cookie = 0; /* optimized access */ #define ZEND_MM_FREE_BLOCK_SIZE(b) (b)->info._size -#ifndef ZEND_MM_ALIGNMENT -# define ZEND_MM_ALIGNMENT 8 -# define ZEND_MM_ALIGNMENT_LOG2 3 -#elif ZEND_MM_ALIGNMENT < 4 -# undef ZEND_MM_ALIGNMENT -# undef ZEND_MM_ALIGNMENT_LOG2 -# define ZEND_MM_ALIGNMENT 4 -# define ZEND_MM_ALIGNMENT_LOG2 2 -#endif - -#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1) - /* Aligned header size */ -#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK) #define ZEND_MM_ALIGNED_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block)) #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block)) -#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE) +#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE) #define ZEND_MM_ALIGNED_MIN_HEADER_SIZE (ZEND_MM_MIN_ALLOC_BLOCK_SIZE>ZEND_MM_ALIGNED_FREE_HEADER_SIZE?ZEND_MM_MIN_ALLOC_BLOCK_SIZE:ZEND_MM_ALIGNED_FREE_HEADER_SIZE) #define ZEND_MM_ALIGNED_SEGMENT_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment)) -#define ZEND_MM_MIN_SIZE ((ZEND_MM_ALIGNED_MIN_HEADER_SIZE>(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE))?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE-(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE)):0) +#define ZEND_MM_MIN_SIZE ((ZEND_MM_ALIGNED_MIN_HEADER_SIZE>(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE))?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE-(ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE)):0) #define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2)) @@ -632,45 +598,7 @@ static unsigned int _zend_mm_cookie = 0; #endif -#if SUHOSIN_MM_WITH_CANARY_PROTECTION -# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \ - char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \ - if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \ - canary_mismatch: \ - zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \ - if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { (block)->info.canary_1 = heap->canary_1; (block)->info.canary_2 = heap->canary_2; }\ - } \ - memcpy(&check, p, CANARY_SIZE); \ - if (check != heap->canary_3) { \ - zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \ - if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \ - } \ - } while (0) - -# define SUHOSIN_MM_SET_CANARIES(block) do { \ - (block)->info.canary_1 = heap->canary_1; \ - (block)->info.canary_2 = heap->canary_2; \ - } while (0) - -# define SUHOSIN_MM_END_CANARY_PTR(block) \ - (char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block*)(block))->info.size + END_MAGIC_SIZE) - -# define SUHOSIN_MM_SET_END_CANARY(block) do { \ - char *p = SUHOSIN_MM_END_CANARY_PTR(block); \ - memcpy(p, &heap->canary_3, CANARY_SIZE); \ - } while (0) - -#else - -# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) -# define SUHOSIN_MM_SET_CANARIES(block) -# define SUHOSIN_MM_END_CANARY_PTR(block) -# define SUHOSIN_MM_SET_END_CANARY(block) - -#endif - - #if ZEND_MM_HEAP_PROTECTION # define ZEND_MM_CHECK_PROTECTION(block) \ @@ -792,25 +720,8 @@ static inline unsigned int zend_mm_low_bit(size_t _siz #endif } -static void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) +static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) { - zend_mm_free_block *prev, *next; - - ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED); - - if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) { - mm_block->parent = NULL; - } - - prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]); - next = SUHOSIN_MANGLE_PTR(prev->next_free_block); - mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev); - mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next); - prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block); -} - -static void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) -{ size_t size; size_t index; @@ -826,7 +737,7 @@ static void zend_mm_add_to_free_list(zend_mm_heap *hea if (!*p) { *p = mm_block; mm_block->parent = p; - mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block); + mm_block->prev_free_block = mm_block->next_free_block = mm_block; heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index); } else { size_t m; @@ -839,15 +750,15 @@ static void zend_mm_add_to_free_list(zend_mm_heap *hea if (!*p) { *p = mm_block; mm_block->parent = p; - mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block); + mm_block->prev_free_block = mm_block->next_free_block = mm_block; break; } } else { - zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(prev->next_free_block); + zend_mm_free_block *next = prev->next_free_block; - prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block); - mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next); - mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev); + prev->next_free_block = next->prev_free_block = mm_block; + mm_block->next_free_block = next; + mm_block->prev_free_block = prev; mm_block->parent = NULL; break; } @@ -859,33 +770,27 @@ static void zend_mm_add_to_free_list(zend_mm_heap *hea index = ZEND_MM_BUCKET_INDEX(size); prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index); - if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) { + if (prev->prev_free_block == prev) { heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index); } - next = SUHOSIN_MANGLE_PTR(prev->next_free_block); + next = prev->next_free_block; - mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev); - mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next); - prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block); + mm_block->prev_free_block = prev; + mm_block->next_free_block = next; + prev->next_free_block = next->prev_free_block = mm_block; } } -static void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) +static inline void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) { - zend_mm_free_block *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block); - zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block); + zend_mm_free_block *prev = mm_block->prev_free_block; + zend_mm_free_block *next = mm_block->next_free_block; ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED); if (EXPECTED(prev == mm_block)) { zend_mm_free_block **rp, **cp; -#if SUHOSIN_PATCH - if (next != mm_block) { - zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block); - _exit(1); - } -#endif #if ZEND_MM_SAFE_UNLINKING if (UNEXPECTED(next != mm_block)) { zend_mm_panic("zend_mm_heap corrupted"); @@ -924,21 +829,14 @@ subst_block: } } else { -#if SUHOSIN_PATCH - if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) { - zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block); - _exit(1); - } -#endif - #if ZEND_MM_SAFE_UNLINKING - if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) { + if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block != mm_block)) { zend_mm_panic("zend_mm_heap corrupted"); } #endif - prev->next_free_block = SUHOSIN_MANGLE_PTR(next); - next->prev_free_block = SUHOSIN_MANGLE_PTR(prev); + prev->next_free_block = next; + next->prev_free_block = prev; if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) { if (EXPECTED(prev == next)) { @@ -948,14 +846,47 @@ subst_block: heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index); } } + } else if (UNEXPECTED(mm_block->parent == ZEND_MM_REST_BLOCK)) { + heap->rest_count--; } else if (UNEXPECTED(mm_block->parent != NULL)) { goto subst_block; } } } -static void zend_mm_init(zend_mm_heap *heap) +static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block) { + zend_mm_free_block *prev, *next; + + while (heap->rest_count >= ZEND_MM_MAX_REST_BLOCKS) { + zend_mm_free_block *p = heap->rest_buckets[1]; + + if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(p))) { + heap->rest_count--; + } + prev = p->prev_free_block; + next = p->next_free_block; + prev->next_free_block = next; + next->prev_free_block = prev; + zend_mm_add_to_free_list(heap, p); + } + + if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) { + mm_block->parent = ZEND_MM_REST_BLOCK; + heap->rest_count++; + } + + ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED); + + prev = heap->rest_buckets[0]; + next = prev->next_free_block; + mm_block->prev_free_block = prev; + mm_block->next_free_block = next; + prev->next_free_block = next->prev_free_block = mm_block; +} + +static inline void zend_mm_init(zend_mm_heap *heap) +{ zend_mm_free_block* p; int i; @@ -972,19 +903,13 @@ static void zend_mm_init(zend_mm_heap *heap) #endif p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { - p->next_free_block = SUHOSIN_MANGLE_PTR(p); - p->prev_free_block = SUHOSIN_MANGLE_PTR(p); + p->next_free_block = p; + p->prev_free_block = p; p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2); heap->large_free_buckets[i] = NULL; } - heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap)); -#if SUHOSIN_PATCH - if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) { - zend_canary(&heap->canary_1, sizeof(heap->canary_1)); - zend_canary(&heap->canary_2, sizeof(heap->canary_2)); - zend_canary(&heap->canary_3, sizeof(heap->canary_3)); - } -#endif + heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap); + heap->rest_count = 0; } static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment) @@ -1005,13 +930,12 @@ static void zend_mm_free_cache(zend_mm_heap *heap) int i; for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { - /* NULL means NULL even MANGLED */ if (heap->cache[i]) { - zend_mm_free_block *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]); + zend_mm_free_block *mm_block = heap->cache[i]; while (mm_block) { size_t size = ZEND_MM_BLOCK_SIZE(mm_block); - zend_mm_free_block *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block); + zend_mm_free_block *q = mm_block->prev_free_block; zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block); heap->cached -= size; @@ -1107,20 +1031,14 @@ static void zend_mm_random(unsigned char *buf, size_t /* }}} */ #endif - /* Notes: * - This function may alter the block_sizes values to match platform alignment * - This function does *not* perform sanity checks on the arguments */ -#if SUHOSIN_MM_WITH_CANARY_PROTECTION -zend_mm_heap *__zend_mm_startup_canary_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) -#else -static zend_mm_heap *__zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) -#endif +ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) { zend_mm_storage *storage; zend_mm_heap *heap; - zend_mm_free_block *tmp; #if 0 int i; @@ -1154,12 +1072,6 @@ static zend_mm_heap *__zend_mm_startup_ex(const zend_m } #endif - /* get the pointer guardian and ensure low 3 bits are 1 */ - if (SUHOSIN_POINTER_GUARD == 0) { - zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD)); - SUHOSIN_POINTER_GUARD |= 7; - } - if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) { fprintf(stderr, "'block_size' must be a power of two\n"); /* See http://support.microsoft.com/kb/190351 */ @@ -1187,7 +1099,6 @@ static zend_mm_heap *__zend_mm_startup_ex(const zend_m #endif exit(255); } - heap->storage = storage; heap->block_size = block_size; heap->compact_size = 0; @@ -1208,12 +1119,12 @@ static zend_mm_heap *__zend_mm_startup_ex(const zend_m heap->reserve = NULL; heap->reserve_size = reserve_size; if (reserve_size > 0) { - heap->reserve = _zend_mm_alloc(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); + heap->reserve = _zend_mm_alloc_int(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); } if (internal) { int i; zend_mm_free_block *p, *q, *orig; - zend_mm_heap *mm_heap = _zend_mm_alloc(heap, sizeof(zend_mm_heap) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); + zend_mm_heap *mm_heap = _zend_mm_alloc_int(heap, sizeof(zend_mm_heap) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); *mm_heap = *heap; @@ -1221,22 +1132,23 @@ static zend_mm_heap *__zend_mm_startup_ex(const zend_m orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { q = p; - while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) { - q = SUHOSIN_MANGLE_PTR(q->prev_free_block); + while (q->prev_free_block != orig) { + q = q->prev_free_block; } - q->prev_free_block = SUHOSIN_MANGLE_PTR(p); + q->prev_free_block = p; q = p; - while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) { - q = SUHOSIN_MANGLE_PTR(q->next_free_block); + while (q->next_free_block != orig) { + q = q->next_free_block; } - q->next_free_block = SUHOSIN_MANGLE_PTR(p); + q->next_free_block = p; p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2); orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2); if (mm_heap->large_free_buckets[i]) { mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i]; } } - mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap)); + mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(mm_heap); + mm_heap->rest_count = 0; free(heap); heap = mm_heap; @@ -1244,11 +1156,7 @@ static zend_mm_heap *__zend_mm_startup_ex(const zend_m return heap; } -#if SUHOSIN_MM_WITH_CANARY_PROTECTION -zend_mm_heap *__zend_mm_startup_canary(void) -#else -static zend_mm_heap *__zend_mm_startup(void) -#endif +ZEND_API zend_mm_heap *zend_mm_startup(void) { int i; size_t seg_size; @@ -1318,27 +1226,6 @@ static zend_mm_heap *__zend_mm_startup(void) return heap; } -#ifndef SUHOSIN_MM_CLONE_FILE -zend_mm_heap_canary *__zend_mm_startup_canary_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params); -zend_mm_heap_canary *__zend_mm_startup_canary(void); - -ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers, size_t block_size, size_t reserve_size, int internal, void *params) -{ - if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) { - return (zend_mm_heap *)__zend_mm_startup_canary_ex(handlers, block_size, reserve_size, internal, params); - } - return __zend_mm_startup_ex(handlers, block_size, reserve_size, internal, params); -} -ZEND_API zend_mm_heap *zend_mm_startup(void) -{ - if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) { - return (zend_mm_heap *)__zend_mm_startup_canary(); - } - return __zend_mm_startup(); -} - -#endif - #if ZEND_DEBUG static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b) { @@ -1707,21 +1594,24 @@ static int zend_mm_check_heap(zend_mm_heap *heap, int } #endif -#if SUHOSIN_MM_WITH_CANARY_PROTECTION -void __zend_mm_shutdown_canary(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) -#else -static void __zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) -#endif +ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) { zend_mm_storage *storage; zend_mm_segment *segment; zend_mm_segment *prev; int internal; + if (!heap->use_zend_alloc) { + if (full_shutdown) { + free(heap); + } + return; + } + if (heap->reserve) { #if ZEND_DEBUG if (!silent) { - _zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); + _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); } #endif heap->reserve = NULL; @@ -1782,45 +1672,70 @@ static void __zend_mm_shutdown(zend_mm_heap *heap, int internal = heap->internal; storage = heap->storage; segment = heap->segments_list; - while (segment) { - prev = segment; - segment = segment->next_segment; - ZEND_MM_STORAGE_FREE(prev); - } if (full_shutdown) { + while (segment) { + prev = segment; + segment = segment->next_segment; + ZEND_MM_STORAGE_FREE(prev); + } + heap->segments_list = NULL; storage->handlers->dtor(storage); if (!internal) { free(heap); } } else { + if (segment) { +#ifndef ZEND_WIN32 + if (heap->reserve_size) { + while (segment->next_segment) { + prev = segment; + segment = segment->next_segment; + ZEND_MM_STORAGE_FREE(prev); + } + heap->segments_list = segment; + } else { +#endif + do { + prev = segment; + segment = segment->next_segment; + ZEND_MM_STORAGE_FREE(prev); + } while (segment); + heap->segments_list = NULL; +#ifndef ZEND_WIN32 + } +#endif + } if (heap->compact_size && heap->real_peak > heap->compact_size) { storage->handlers->compact(storage); } - heap->segments_list = NULL; zend_mm_init(heap); - heap->real_size = 0; - heap->real_peak = 0; + if (heap->segments_list) { + heap->real_size = heap->segments_list->size; + heap->real_peak = heap->segments_list->size; + } else { + heap->real_size = 0; + heap->real_peak = 0; + } heap->size = 0; heap->peak = 0; + if (heap->segments_list) { + /* mark segment as a free block */ + zend_mm_free_block *b = (zend_mm_free_block*)((char*)heap->segments_list + ZEND_MM_ALIGNED_SEGMENT_SIZE); + size_t block_size = heap->segments_list->size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE; + + ZEND_MM_MARK_FIRST_BLOCK(b); + ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(b, block_size)); + ZEND_MM_BLOCK(b, ZEND_MM_FREE_BLOCK, block_size); + zend_mm_add_to_free_list(heap, b); + } if (heap->reserve_size) { - heap->reserve = _zend_mm_alloc(heap, heap->reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); + heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); } heap->overflow = 0; } } -#ifndef SUHOSIN_MM_CLONE_FILE -ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) -{ - if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) { - __zend_mm_shutdown_canary(heap, full_shutdown, silent TSRMLS_CC); - return; - } - __zend_mm_shutdown(heap, full_shutdown, silent TSRMLS_CC); -} -#endif - static void zend_mm_safe_error(zend_mm_heap *heap, const char *format, size_t limit, @@ -1831,15 +1746,11 @@ static void zend_mm_safe_error(zend_mm_heap *heap, size_t size) { if (heap->reserve) { -#if SUHOSIN_MM_WITH_CANARY_PROTECTION - _zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); -#else _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); -#endif heap->reserve = NULL; } if (heap->overflow == 0) { - char *error_filename; + const char *error_filename; uint error_lineno; TSRMLS_FETCH(); if (zend_is_compiling(TSRMLS_C)) { @@ -1910,7 +1821,7 @@ static zend_mm_free_block *zend_mm_search_large_block( p = heap->large_free_buckets[index]; for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) { if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) { - return SUHOSIN_MANGLE_PTR(p->next_free_block); + return p->next_free_block; } else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size && ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { best_size = ZEND_MM_FREE_BLOCK_SIZE(p); @@ -1934,7 +1845,7 @@ static zend_mm_free_block *zend_mm_search_large_block( for (p = rst; p; p = p->child[p->child[0] != NULL]) { if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) { - return SUHOSIN_MANGLE_PTR(p->next_free_block); + return p->next_free_block; } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size && ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { best_size = ZEND_MM_FREE_BLOCK_SIZE(p); @@ -1943,7 +1854,7 @@ static zend_mm_free_block *zend_mm_search_large_block( } if (best_fit) { - return SUHOSIN_MANGLE_PTR(best_fit->next_free_block); + return best_fit->next_free_block; } bitmap = bitmap >> 1; if (!bitmap) { @@ -1959,12 +1870,9 @@ static zend_mm_free_block *zend_mm_search_large_block( best_fit = p; } } - return SUHOSIN_MANGLE_PTR(best_fit->next_free_block); + return best_fit->next_free_block; } -#if SUHOSIN_PATCH -void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); -#endif static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { zend_mm_free_block *best_fit; @@ -1974,7 +1882,12 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si size_t segment_size; zend_mm_segment *segment; int keep_rest = 0; - +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif + + HANDLE_BLOCK_INTERRUPTIONS(); + if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) { size_t index = ZEND_MM_BUCKET_INDEX(true_size); size_t bitmap; @@ -1989,16 +1902,12 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si heap->cache_stat[index].count--; heap->cache_stat[index].hit++; #endif - best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]); + best_fit = heap->cache[index]; heap->cache[index] = best_fit->prev_free_block; heap->cached -= true_size; -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(best_fit); - ((zend_mm_block*)best_fit)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(best_fit); -#endif ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); + HANDLE_UNBLOCK_INTERRUPTIONS(); return ZEND_MM_DATA_OF(best_fit); } #if ZEND_MM_CACHE_STAT @@ -2010,7 +1919,7 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si if (bitmap) { /* Found some "small" free block that can be used */ index += zend_mm_low_bit(bitmap); - best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]); + best_fit = heap->free_buckets[index*2]; #if ZEND_MM_CACHE_STAT heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++; #endif @@ -2025,7 +1934,7 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si best_fit = zend_mm_search_large_block(heap, true_size); if (!best_fit && heap->real_size >= heap->limit - heap->block_size) { - zend_mm_free_block *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]); + zend_mm_free_block *p = heap->rest_buckets[0]; size_t best_size = -1; while (p != ZEND_MM_REST_BUCKET(heap)) { @@ -2037,7 +1946,7 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si best_size = ZEND_MM_FREE_BLOCK_SIZE(p); best_fit = p; } - p = SUHOSIN_MANGLE_PTR(p->prev_free_block); + p = p->prev_free_block; } } @@ -2052,8 +1961,6 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si segment_size = heap->block_size; } - HANDLE_BLOCK_INTERRUPTIONS(); - if (segment_size < true_size || heap->real_size + segment_size > heap->limit) { /* Memory limit overflow */ @@ -2075,8 +1982,8 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, si #if ZEND_MM_CACHE zend_mm_free_cache(heap); #endif - HANDLE_UNBLOCK_INTERRUPTIONS(); out_of_memory: + HANDLE_UNBLOCK_INTERRUPTIONS(); #if ZEND_DEBUG zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %lu bytes)", heap->real_size, __zend_filename, __zend_lineno, size); #else @@ -2104,7 +2011,6 @@ out_of_memory: } else { zend_mm_finished_searching_for_block: /* remove from free list */ - HANDLE_BLOCK_INTERRUPTIONS(); ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED); ZEND_MM_CHECK_COOKIE(best_fit); ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit); @@ -2136,19 +2042,13 @@ zend_mm_finished_searching_for_block: ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1); -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(best_fit); - ((zend_mm_block*)best_fit)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(best_fit); -#endif - heap->size += true_size; if (heap->peak < heap->size) { heap->peak = heap->size; } HANDLE_UNBLOCK_INTERRUPTIONS(); - + return ZEND_MM_DATA_OF(best_fit); } @@ -2158,33 +2058,30 @@ static void _zend_mm_free_int(zend_mm_heap *heap, void zend_mm_block *mm_block; zend_mm_block *next_block; size_t size; - +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif if (!ZEND_MM_VALID_PTR(p)) { return; } + HANDLE_BLOCK_INTERRUPTIONS(); + mm_block = ZEND_MM_HEADER_OF(p); size = ZEND_MM_BLOCK_SIZE(mm_block); -#if SUHOSIN_PATCH - SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()"); -#endif ZEND_MM_CHECK_PROTECTION(mm_block); #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size); #endif -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) { - memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size); - } -#endif + #if ZEND_MM_CACHE if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) { size_t index = ZEND_MM_BUCKET_INDEX(size); zend_mm_free_block **cache = &heap->cache[index]; ((zend_mm_free_block*)mm_block)->prev_free_block = *cache; - *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block); + *cache = (zend_mm_free_block*)mm_block; heap->cached += size; ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED); #if ZEND_MM_CACHE_STAT @@ -2192,12 +2089,11 @@ static void _zend_mm_free_int(zend_mm_heap *heap, void heap->cache_stat[index].max_count = heap->cache_stat[index].count; } #endif + HANDLE_UNBLOCK_INTERRUPTIONS(); return; } #endif - HANDLE_BLOCK_INTERRUPTIONS(); - heap->size -= size; next_block = ZEND_MM_BLOCK_AT(mm_block, size); @@ -2220,9 +2116,6 @@ static void _zend_mm_free_int(zend_mm_heap *heap, void HANDLE_UNBLOCK_INTERRUPTIONS(); } -#if SUHOSIN_PATCH -void *_zend_mm_realloc_canary_int(zend_mm_heap_canary *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); -#endif static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p); @@ -2230,20 +2123,18 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, size_t true_size; size_t orig_size; void *ptr; - +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) { -#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION - return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#else return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif } + + HANDLE_BLOCK_INTERRUPTIONS(); + mm_block = ZEND_MM_HEADER_OF(p); true_size = ZEND_MM_TRUE_SIZE(size); orig_size = ZEND_MM_BLOCK_SIZE(mm_block); -#if SUHOSIN_PATCH - SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()"); -#endif ZEND_MM_CHECK_PROTECTION(mm_block); if (UNEXPECTED(true_size < size)) { @@ -2256,7 +2147,6 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { zend_mm_free_block *new_free_block; - HANDLE_BLOCK_INTERRUPTIONS(); next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size); if (ZEND_MM_IS_FREE_BLOCK(next_block)) { remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block); @@ -2272,14 +2162,9 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, /* add the new free block to the free list */ zend_mm_add_to_free_list(heap, new_free_block); heap->size += (true_size - orig_size); - HANDLE_UNBLOCK_INTERRUPTIONS(); } ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0); -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(mm_block); - ((zend_mm_block*)mm_block)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(mm_block); -#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } @@ -2295,22 +2180,17 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, heap->cache_stat[index].count--; heap->cache_stat[index].hit++; #endif - best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]); + best_fit = heap->cache[index]; heap->cache[index] = best_fit->prev_free_block; ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); - ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(best_fit); - ((zend_mm_block*)best_fit)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(best_fit); -#endif - + ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); + ptr = ZEND_MM_DATA_OF(best_fit); #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION memcpy(ptr, p, mm_block->debug.size); #else - memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE); + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE); #endif heap->cached -= true_size - orig_size; @@ -2319,13 +2199,15 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, cache = &heap->cache[index]; ((zend_mm_free_block*)mm_block)->prev_free_block = *cache; - *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block); + *cache = (zend_mm_free_block*)mm_block; ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED); #if ZEND_MM_CACHE_STAT if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) { heap->cache_stat[index].max_count = heap->cache_stat[index].count; } #endif + + HANDLE_UNBLOCK_INTERRUPTIONS(); return ptr; } } @@ -2340,7 +2222,6 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block); size_t remaining_size = block_size - true_size; - HANDLE_BLOCK_INTERRUPTIONS(); zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block); if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { @@ -2368,15 +2249,9 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, heap->peak = heap->size; } HANDLE_UNBLOCK_INTERRUPTIONS(); -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(mm_block); - ((zend_mm_block*)mm_block)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(mm_block); -#endif return p; } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) && ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) { - HANDLE_BLOCK_INTERRUPTIONS(); zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block); goto realloc_segment; } @@ -2387,7 +2262,6 @@ static void *_zend_mm_realloc_int(zend_mm_heap *heap, size_t block_size; size_t remaining_size; - HANDLE_BLOCK_INTERRUPTIONS(); realloc_segment: /* segment size, size of block and size of guard block */ if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) { @@ -2420,8 +2294,8 @@ realloc_segment: #if ZEND_MM_CACHE zend_mm_free_cache(heap); #endif - HANDLE_UNBLOCK_INTERRUPTIONS(); out_of_memory: + HANDLE_UNBLOCK_INTERRUPTIONS(); #if ZEND_DEBUG zend_mm_safe_error(heap, "Out of memory (allocated %ld) at %s:%d (tried to allocate %ld bytes)", heap->real_size, __zend_filename, __zend_lineno, size); #else @@ -2475,74 +2349,39 @@ out_of_memory: } HANDLE_UNBLOCK_INTERRUPTIONS(); -#if SUHOSIN_PATCH - SUHOSIN_MM_SET_CANARIES(mm_block); - ((zend_mm_block*)mm_block)->info.size = size; - SUHOSIN_MM_SET_END_CANARY(mm_block); -#endif return ZEND_MM_DATA_OF(mm_block); } -#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION - ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#else ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION memcpy(ptr, p, mm_block->debug.size); #else - memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE); + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE); #endif -#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION - _zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#else _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + HANDLE_UNBLOCK_INTERRUPTIONS(); return ptr; } -#ifndef SUHOSIN_MM_CLONE_FILE ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif - return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if SUHOSIN_PATCH - return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif - { _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; } -#if SUHOSIN_PATCH - _zend_mm_free_canary_int((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif - return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if SUHOSIN_PATCH - return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { zend_mm_block *mm_block; - if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) != 0) { - return _zend_mm_block_size_canary((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); - } - if (!ZEND_MM_VALID_PTR(p)) { return 0; } @@ -2554,25 +2393,7 @@ ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap return ZEND_MM_BLOCK_SIZE(mm_block); #endif } -#else -ZEND_API size_t _zend_mm_block_size_canary(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) -{ - zend_mm_block *mm_block; - if (!ZEND_MM_VALID_PTR(p)) { - return 0; - } - mm_block = ZEND_MM_HEADER_OF(p); - ZEND_MM_CHECK_PROTECTION(mm_block); -#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION - return mm_block->debug.size; -#else - return ZEND_MM_BLOCK_SIZE(mm_block); -#endif -} - -#endif - /**********************/ /* Allocation Manager */ /**********************/ @@ -2589,7 +2410,6 @@ static int alloc_globals_id; static zend_alloc_globals alloc_globals; #endif -#ifndef SUHOSIN_MM_CLONE_FILE ZEND_API int is_zend_mm(TSRMLS_D) { return AG(mm_heap)->use_zend_alloc; @@ -2602,13 +2422,7 @@ ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { return AG(mm_heap)->_malloc(size); } -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if SUHOSIN_PATCH - return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif } ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -2619,13 +2433,7 @@ ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_ AG(mm_heap)->_free(ptr); return; } -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif - { _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; } -#if SUHOSIN_PATCH - _zend_mm_free_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -2635,13 +2443,7 @@ ZEND_API void *_erealloc(void *ptr, size_t size, int a if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { return AG(mm_heap)->_realloc(ptr, size); } -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if SUHOSIN_PATCH - return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif } ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) @@ -2649,15 +2451,8 @@ ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_ if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { return 0; } -#if SUHOSIN_PATCH - if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0)) -#endif - return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#if SUHOSIN_PATCH - return _zend_mm_block_size_canary((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); -#endif + return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } -#endif #if defined(__GNUC__) && defined(i386) @@ -2728,7 +2523,7 @@ static inline size_t safe_address(size_t nmemb, size_t } #endif -#ifndef SUHOSIN_MM_CLONE_FILE + ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { return emalloc_rel(safe_address(nmemb, size, offset)); @@ -2753,12 +2548,18 @@ ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { void *p; +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif + HANDLE_BLOCK_INTERRUPTIONS(); p = _safe_emalloc(nmemb, size, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } memset(p, 0, size * nmemb); + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } @@ -2766,26 +2567,40 @@ ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_D { int length; char *p; +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif + HANDLE_BLOCK_INTERRUPTIONS(); + length = strlen(s)+1; p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } memcpy(p, s, length); + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { char *p; +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif + HANDLE_BLOCK_INTERRUPTIONS(); + p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); if (UNEXPECTED(p == NULL)) { + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } memcpy(p, s, length); p[length] = 0; + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } @@ -2793,15 +2608,22 @@ ZEND_API char *_estrndup(const char *s, uint length ZE ZEND_API char *zend_strndup(const char *s, uint length) { char *p; +#ifdef ZEND_SIGNALS + TSRMLS_FETCH(); +#endif + HANDLE_BLOCK_INTERRUPTIONS(); + p = (char *) malloc(length+1); if (UNEXPECTED(p == NULL)) { + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } if (length) { memcpy(p, s, length); } p[length] = 0; + HANDLE_UNBLOCK_INTERRUPTIONS(); return p; } @@ -2841,21 +2663,20 @@ ZEND_API void shutdown_memory_manager(int silent, int { zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC); } -#endif static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC) { - char *tmp; - alloc_globals->mm_heap = zend_mm_startup(); + char *tmp = getenv("USE_ZEND_ALLOC"); - tmp = getenv("USE_ZEND_ALLOC"); - if (tmp) { - alloc_globals->mm_heap->use_zend_alloc = zend_atoi(tmp, 0); - if (!alloc_globals->mm_heap->use_zend_alloc) { - alloc_globals->mm_heap->_malloc = malloc; - alloc_globals->mm_heap->_free = free; - alloc_globals->mm_heap->_realloc = realloc; - } + if (tmp && !zend_atoi(tmp, 0)) { + alloc_globals->mm_heap = malloc(sizeof(struct _zend_mm_heap)); + memset(alloc_globals->mm_heap, 0, sizeof(struct _zend_mm_heap)); + alloc_globals->mm_heap->use_zend_alloc = 0; + alloc_globals->mm_heap->_malloc = malloc; + alloc_globals->mm_heap->_free = free; + alloc_globals->mm_heap->_realloc = realloc; + } else { + alloc_globals->mm_heap = zend_mm_startup(); } } @@ -2866,7 +2687,6 @@ static void alloc_globals_dtor(zend_alloc_globals *all } #endif -#ifndef SUHOSIN_MM_CLONE_FILE ZEND_API void start_memory_manager(TSRMLS_D) { #ifdef ZTS @@ -2930,7 +2750,6 @@ ZEND_API void _full_mem_check(int silent ZEND_FILE_LIN zend_debug_alloc_output("End of full memory check %s:%d (%d errors)\n" ZEND_FILE_LINE_RELAY_CC, errors); zend_debug_alloc_output("------------------------------------------------\n"); } -#endif #endif /*