version 1.1, 2012/02/21 23:47:52
|
version 1.1.1.5, 2014/06/15 20:04:03
|
Line 2
|
Line 2
|
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Zend Engine | |
| Zend Engine | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) | | | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| This source file is subject to version 2.00 of the Zend license, | |
| This source file is subject to version 2.00 of the Zend license, | |
| that is bundled with this package in the file LICENSE, and is | |
| that is bundled with this package in the file LICENSE, and is | |
Line 32
|
Line 32
|
# include <unistd.h> |
# include <unistd.h> |
#endif |
#endif |
|
|
#if SUHOSIN_PATCH |
|
#include "suhosin_patch.h" |
|
#endif |
|
|
|
#ifdef ZEND_WIN32 |
#ifdef ZEND_WIN32 |
# include <wincrypt.h> |
# include <wincrypt.h> |
# include <process.h> |
# include <process.h> |
Line 63
|
Line 59
|
# define PTR_FMT "0x%0.8lx" |
# define PTR_FMT "0x%0.8lx" |
#endif |
#endif |
|
|
#ifndef SUHOSIN_MM_CLONE_FILE |
|
#if ZEND_DEBUG |
#if ZEND_DEBUG |
void zend_debug_alloc_output(char *format, ...) |
void zend_debug_alloc_output(char *format, ...) |
{ |
{ |
Line 81 void zend_debug_alloc_output(char *format, ...)
|
Line 76 void zend_debug_alloc_output(char *format, ...)
|
#endif |
#endif |
} |
} |
#endif |
#endif |
#endif |
|
|
|
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) |
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) |
static void zend_mm_panic(const char *message) __attribute__ ((noreturn)); |
static void zend_mm_panic(const char *message) __attribute__ ((noreturn)); |
Line 140 static void zend_mm_panic(const char *message)
|
Line 134 static void zend_mm_panic(const char *message)
|
# endif |
# endif |
#endif |
#endif |
|
|
static zend_intptr_t SUHOSIN_POINTER_GUARD = 0; |
|
|
|
static zend_mm_storage* zend_mm_mem_dummy_init(void *params) |
static zend_mm_storage* zend_mm_mem_dummy_init(void *params) |
{ |
{ |
return malloc(sizeof(zend_mm_storage)); |
return malloc(sizeof(zend_mm_storage)); |
Line 340 static const zend_mm_mem_handlers mem_handlers[] = {
|
Line 332 static const zend_mm_mem_handlers mem_handlers[] = {
|
#define MEM_BLOCK_GUARD 0x2A8FCC84 |
#define MEM_BLOCK_GUARD 0x2A8FCC84 |
#define MEM_BLOCK_LEAK 0x6C5E8F2D |
#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 */ |
/* mm block type */ |
typedef struct _zend_mm_block_info { |
typedef struct _zend_mm_block_info { |
#if ZEND_MM_COOKIES |
#if ZEND_MM_COOKIES |
size_t _cookie; |
size_t _cookie; |
#endif |
#endif |
#if SUHOSIN_MM_WITH_CANARY_PROTECTION | size_t _size; |
size_t canary_1; | size_t _prev; |
#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 | |
} zend_mm_block_info; |
} zend_mm_block_info; |
|
|
#if ZEND_DEBUG |
#if ZEND_DEBUG |
|
|
typedef struct _zend_mm_debug_info { |
typedef struct _zend_mm_debug_info { |
char *filename; | const char *filename; |
uint lineno; |
uint lineno; |
char *orig_filename; | const char *orig_filename; |
uint orig_lineno; |
uint orig_lineno; |
size_t size; |
size_t size; |
#if ZEND_MM_HEAP_PROTECTION |
#if ZEND_MM_HEAP_PROTECTION |
Line 435 typedef struct _zend_mm_free_block {
|
Line 412 typedef struct _zend_mm_free_block {
|
# define ZEND_MM_CACHE_STAT 0 |
# define ZEND_MM_CACHE_STAT 0 |
#endif |
#endif |
|
|
typedef struct _zend_mm_heap { | struct _zend_mm_heap { |
int use_zend_alloc; |
int use_zend_alloc; |
void *(*_malloc)(size_t); |
void *(*_malloc)(size_t); |
void (*_free)(void*); |
void (*_free)(void*); |
Line 462 typedef struct _zend_mm_heap {
|
Line 439 typedef struct _zend_mm_heap {
|
zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2]; |
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 *large_free_buckets[ZEND_MM_NUM_BUCKETS]; |
zend_mm_free_block *rest_buckets[2]; |
zend_mm_free_block *rest_buckets[2]; |
|
int rest_count; |
#if ZEND_MM_CACHE_STAT |
#if ZEND_MM_CACHE_STAT |
struct { |
struct { |
int count; |
int count; |
Line 470 typedef struct _zend_mm_heap {
|
Line 448 typedef struct _zend_mm_heap {
|
int miss; |
int miss; |
} cache_stat[ZEND_MM_NUM_BUCKETS+1]; |
} cache_stat[ZEND_MM_NUM_BUCKETS+1]; |
#endif |
#endif |
#if SUHOSIN_PATCH |
|
size_t canary_1,canary_2,canary_3; |
|
#endif |
|
}; |
}; |
|
|
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \ |
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \ |
Line 485 typedef struct _zend_mm_heap {
|
Line 460 typedef struct _zend_mm_heap {
|
sizeof(zend_mm_free_block*) * 2 - \ |
sizeof(zend_mm_free_block*) * 2 - \ |
sizeof(zend_mm_small_free_block)) |
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 |
#if ZEND_MM_COOKIES |
|
|
static unsigned int _zend_mm_cookie = 0; |
static unsigned int _zend_mm_cookie = 0; |
Line 546 static unsigned int _zend_mm_cookie = 0;
|
Line 525 static unsigned int _zend_mm_cookie = 0;
|
/* optimized access */ |
/* optimized access */ |
#define ZEND_MM_FREE_BLOCK_SIZE(b) (b)->info._size |
#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 */ |
/* 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_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_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_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_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) |
#define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE) |
|
|
#define ZEND_MM_TRUE_SIZE(size) ((size<ZEND_MM_MIN_SIZE)?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE):(ZEND_MM_ALIGNED_SIZE(size+ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE+CANARY_SIZE))) | #define ZEND_MM_TRUE_SIZE(size) ((size<ZEND_MM_MIN_SIZE)?(ZEND_MM_ALIGNED_MIN_HEADER_SIZE):(ZEND_MM_ALIGNED_SIZE(size+ZEND_MM_ALIGNED_HEADER_SIZE+END_MAGIC_SIZE))) |
|
|
#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2)) |
#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2)) |
|
|
Line 632 static unsigned int _zend_mm_cookie = 0;
|
Line 598 static unsigned int _zend_mm_cookie = 0;
|
|
|
#endif |
#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 |
#if ZEND_MM_HEAP_PROTECTION |
|
|
# define ZEND_MM_CHECK_PROTECTION(block) \ |
# define ZEND_MM_CHECK_PROTECTION(block) \ |
Line 736 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 664 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
|
|
static inline unsigned int zend_mm_high_bit(size_t _size) |
static inline unsigned int zend_mm_high_bit(size_t _size) |
{ |
{ |
#if defined(__GNUC__) && defined(i386) | #if defined(__GNUC__) && (defined(__native_client__) || defined(i386)) |
unsigned int n; |
unsigned int n; |
|
|
__asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
__asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
Line 744 static inline unsigned int zend_mm_high_bit(size_t _si
|
Line 672 static inline unsigned int zend_mm_high_bit(size_t _si
|
#elif defined(__GNUC__) && defined(__x86_64__) |
#elif defined(__GNUC__) && defined(__x86_64__) |
unsigned long n; |
unsigned long n; |
|
|
__asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm" (_size)); | __asm__("bsr %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
return (unsigned int)n; |
return (unsigned int)n; |
#elif defined(_MSC_VER) && defined(_M_IX86) |
#elif defined(_MSC_VER) && defined(_M_IX86) |
__asm { |
__asm { |
Line 762 static inline unsigned int zend_mm_high_bit(size_t _si
|
Line 690 static inline unsigned int zend_mm_high_bit(size_t _si
|
|
|
static inline unsigned int zend_mm_low_bit(size_t _size) |
static inline unsigned int zend_mm_low_bit(size_t _size) |
{ |
{ |
#if defined(__GNUC__) && defined(i386) | #if defined(__GNUC__) && (defined(__native_client__) || defined(i386)) |
unsigned int n; |
unsigned int n; |
|
|
__asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
__asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
Line 770 static inline unsigned int zend_mm_low_bit(size_t _siz
|
Line 698 static inline unsigned int zend_mm_low_bit(size_t _siz
|
#elif defined(__GNUC__) && defined(__x86_64__) |
#elif defined(__GNUC__) && defined(__x86_64__) |
unsigned long n; |
unsigned long n; |
|
|
__asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm" (_size)); | __asm__("bsf %1,%0\n\t" : "=r" (n) : "rm" (_size)); |
return (unsigned int)n; |
return (unsigned int)n; |
#elif defined(_MSC_VER) && defined(_M_IX86) |
#elif defined(_MSC_VER) && defined(_M_IX86) |
__asm { |
__asm { |
bsf eax, _size |
bsf eax, _size |
} | } |
#else |
#else |
static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}; |
static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}; |
unsigned int n; |
unsigned int n; |
Line 792 static inline unsigned int zend_mm_low_bit(size_t _siz
|
Line 720 static inline unsigned int zend_mm_low_bit(size_t _siz
|
#endif |
#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 size; |
size_t index; |
size_t index; |
|
|
Line 826 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
Line 737 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
if (!*p) { |
if (!*p) { |
*p = mm_block; |
*p = mm_block; |
mm_block->parent = p; |
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); |
heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index); |
} else { |
} else { |
size_t m; |
size_t m; |
Line 839 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
Line 750 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
if (!*p) { |
if (!*p) { |
*p = mm_block; |
*p = mm_block; |
mm_block->parent = p; |
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; |
break; |
} |
} |
} else { |
} 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); | prev->next_free_block = next->prev_free_block = mm_block; |
mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next); | mm_block->next_free_block = next; |
mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev); | mm_block->prev_free_block = prev; |
mm_block->parent = NULL; |
mm_block->parent = NULL; |
break; |
break; |
} |
} |
Line 859 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
Line 770 static void zend_mm_add_to_free_list(zend_mm_heap *hea
|
index = ZEND_MM_BUCKET_INDEX(size); |
index = ZEND_MM_BUCKET_INDEX(size); |
|
|
prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index); |
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); |
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->prev_free_block = prev; |
mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next); | mm_block->next_free_block = next; |
prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block); | 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 *prev = mm_block->prev_free_block; |
zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block); | zend_mm_free_block *next = mm_block->next_free_block; |
|
|
ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED); |
ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED); |
|
|
if (EXPECTED(prev == mm_block)) { |
if (EXPECTED(prev == mm_block)) { |
zend_mm_free_block **rp, **cp; |
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 ZEND_MM_SAFE_UNLINKING |
if (UNEXPECTED(next != mm_block)) { |
if (UNEXPECTED(next != mm_block)) { |
zend_mm_panic("zend_mm_heap corrupted"); |
zend_mm_panic("zend_mm_heap corrupted"); |
Line 924 subst_block:
|
Line 829 subst_block:
|
} |
} |
} else { |
} 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 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"); |
zend_mm_panic("zend_mm_heap corrupted"); |
} |
} |
#endif |
#endif |
|
|
prev->next_free_block = SUHOSIN_MANGLE_PTR(next); | prev->next_free_block = next; |
next->prev_free_block = SUHOSIN_MANGLE_PTR(prev); | next->prev_free_block = prev; |
|
|
if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) { |
if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) { |
if (EXPECTED(prev == next)) { |
if (EXPECTED(prev == next)) { |
Line 948 subst_block:
|
Line 846 subst_block:
|
heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index); |
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)) { |
} else if (UNEXPECTED(mm_block->parent != NULL)) { |
goto subst_block; |
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; |
zend_mm_free_block* p; |
int i; |
int i; |
|
|
Line 972 static void zend_mm_init(zend_mm_heap *heap)
|
Line 903 static void zend_mm_init(zend_mm_heap *heap)
|
#endif |
#endif |
p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); |
p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); |
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
p->next_free_block = SUHOSIN_MANGLE_PTR(p); | p->next_free_block = p; |
p->prev_free_block = SUHOSIN_MANGLE_PTR(p); | p->prev_free_block = p; |
p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2); |
p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2); |
heap->large_free_buckets[i] = NULL; |
heap->large_free_buckets[i] = NULL; |
} |
} |
heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap)); | heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap); |
#if SUHOSIN_PATCH | heap->rest_count = 0; |
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 | |
} |
} |
|
|
static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment) |
static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment) |
Line 1005 static void zend_mm_free_cache(zend_mm_heap *heap)
|
Line 930 static void zend_mm_free_cache(zend_mm_heap *heap)
|
int i; |
int i; |
|
|
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
/* NULL means NULL even MANGLED */ |
|
if (heap->cache[i]) { |
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) { |
while (mm_block) { |
size_t size = ZEND_MM_BLOCK_SIZE(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); |
zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block); |
|
|
heap->cached -= size; |
heap->cached -= size; |
Line 1107 static void zend_mm_random(unsigned char *buf, size_t
|
Line 1031 static void zend_mm_random(unsigned char *buf, size_t
|
/* }}} */ |
/* }}} */ |
#endif |
#endif |
|
|
|
|
/* Notes: |
/* Notes: |
* - This function may alter the block_sizes values to match platform alignment |
* - This function may alter the block_sizes values to match platform alignment |
* - This function does *not* perform sanity checks on the arguments |
* - This function does *not* perform sanity checks on the arguments |
*/ |
*/ |
#if SUHOSIN_MM_WITH_CANARY_PROTECTION | 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_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_mm_storage *storage; |
zend_mm_storage *storage; |
zend_mm_heap *heap; |
zend_mm_heap *heap; |
zend_mm_free_block *tmp; |
|
|
|
#if 0 |
#if 0 |
int i; |
int i; |
Line 1154 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
Line 1072 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
} |
} |
#endif |
#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)) { |
if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) { |
fprintf(stderr, "'block_size' must be a power of two\n"); |
fprintf(stderr, "'block_size' must be a power of two\n"); |
/* See http://support.microsoft.com/kb/190351 */ |
/* See http://support.microsoft.com/kb/190351 */ |
Line 1187 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
Line 1099 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
#endif |
#endif |
exit(255); |
exit(255); |
} |
} |
|
|
heap->storage = storage; |
heap->storage = storage; |
heap->block_size = block_size; |
heap->block_size = block_size; |
heap->compact_size = 0; |
heap->compact_size = 0; |
Line 1208 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
Line 1119 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
heap->reserve = NULL; |
heap->reserve = NULL; |
heap->reserve_size = reserve_size; |
heap->reserve_size = reserve_size; |
if (reserve_size > 0) { |
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) { |
if (internal) { |
int i; |
int i; |
zend_mm_free_block *p, *q, *orig; |
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; |
*mm_heap = *heap; |
|
|
Line 1221 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
Line 1132 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); |
orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0); |
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) { |
q = p; |
q = p; |
while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) { | while (q->prev_free_block != orig) { |
q = SUHOSIN_MANGLE_PTR(q->prev_free_block); | q = q->prev_free_block; |
} |
} |
q->prev_free_block = SUHOSIN_MANGLE_PTR(p); | q->prev_free_block = p; |
q = p; |
q = p; |
while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) { | while (q->next_free_block != orig) { |
q = SUHOSIN_MANGLE_PTR(q->next_free_block); | 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); |
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); |
orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2); |
if (mm_heap->large_free_buckets[i]) { |
if (mm_heap->large_free_buckets[i]) { |
mm_heap->large_free_buckets[i]->parent = &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); |
free(heap); |
heap = mm_heap; |
heap = mm_heap; |
Line 1244 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
Line 1156 static zend_mm_heap *__zend_mm_startup_ex(const zend_m
|
return heap; |
return heap; |
} |
} |
|
|
#if SUHOSIN_MM_WITH_CANARY_PROTECTION | ZEND_API zend_mm_heap *zend_mm_startup(void) |
zend_mm_heap *__zend_mm_startup_canary(void) | |
#else | |
static zend_mm_heap *__zend_mm_startup(void) | |
#endif | |
{ |
{ |
int i; |
int i; |
size_t seg_size; |
size_t seg_size; |
Line 1318 static zend_mm_heap *__zend_mm_startup(void)
|
Line 1226 static zend_mm_heap *__zend_mm_startup(void)
|
return heap; |
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 |
#if ZEND_DEBUG |
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b) |
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b) |
{ |
{ |
Line 1707 static int zend_mm_check_heap(zend_mm_heap *heap, int
|
Line 1594 static int zend_mm_check_heap(zend_mm_heap *heap, int
|
} |
} |
#endif |
#endif |
|
|
#if SUHOSIN_MM_WITH_CANARY_PROTECTION | ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC) |
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_mm_storage *storage; |
zend_mm_storage *storage; |
zend_mm_segment *segment; |
zend_mm_segment *segment; |
zend_mm_segment *prev; |
zend_mm_segment *prev; |
int internal; |
int internal; |
|
|
|
if (!heap->use_zend_alloc) { |
|
if (full_shutdown) { |
|
free(heap); |
|
} |
|
return; |
|
} |
|
|
if (heap->reserve) { |
if (heap->reserve) { |
#if ZEND_DEBUG |
#if ZEND_DEBUG |
if (!silent) { |
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 |
#endif |
heap->reserve = NULL; |
heap->reserve = NULL; |
Line 1782 static void __zend_mm_shutdown(zend_mm_heap *heap, int
|
Line 1672 static void __zend_mm_shutdown(zend_mm_heap *heap, int
|
internal = heap->internal; |
internal = heap->internal; |
storage = heap->storage; |
storage = heap->storage; |
segment = heap->segments_list; |
segment = heap->segments_list; |
while (segment) { |
|
prev = segment; |
|
segment = segment->next_segment; |
|
ZEND_MM_STORAGE_FREE(prev); |
|
} |
|
if (full_shutdown) { |
if (full_shutdown) { |
|
while (segment) { |
|
prev = segment; |
|
segment = segment->next_segment; |
|
ZEND_MM_STORAGE_FREE(prev); |
|
} |
|
heap->segments_list = NULL; |
storage->handlers->dtor(storage); |
storage->handlers->dtor(storage); |
if (!internal) { |
if (!internal) { |
free(heap); |
free(heap); |
} |
} |
} else { |
} 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 && |
if (heap->compact_size && |
heap->real_peak > heap->compact_size) { |
heap->real_peak > heap->compact_size) { |
storage->handlers->compact(storage); |
storage->handlers->compact(storage); |
} |
} |
heap->segments_list = NULL; |
|
zend_mm_init(heap); |
zend_mm_init(heap); |
heap->real_size = 0; | if (heap->segments_list) { |
heap->real_peak = 0; | 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->size = 0; |
heap->peak = 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) { |
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; |
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, |
static void zend_mm_safe_error(zend_mm_heap *heap, |
const char *format, |
const char *format, |
size_t limit, |
size_t limit, |
Line 1831 static void zend_mm_safe_error(zend_mm_heap *heap,
|
Line 1746 static void zend_mm_safe_error(zend_mm_heap *heap,
|
size_t size) |
size_t size) |
{ |
{ |
if (heap->reserve) { |
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); |
_zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); |
#endif |
|
heap->reserve = NULL; |
heap->reserve = NULL; |
} |
} |
if (heap->overflow == 0) { |
if (heap->overflow == 0) { |
char *error_filename; | const char *error_filename; |
uint error_lineno; |
uint error_lineno; |
TSRMLS_FETCH(); |
TSRMLS_FETCH(); |
if (zend_is_compiling(TSRMLS_C)) { |
if (zend_is_compiling(TSRMLS_C)) { |
Line 1910 static zend_mm_free_block *zend_mm_search_large_block(
|
Line 1821 static zend_mm_free_block *zend_mm_search_large_block(
|
p = heap->large_free_buckets[index]; |
p = heap->large_free_buckets[index]; |
for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) { |
for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) { |
if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) { |
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 && |
} else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size && |
ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { |
ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { |
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
Line 1934 static zend_mm_free_block *zend_mm_search_large_block(
|
Line 1845 static zend_mm_free_block *zend_mm_search_large_block(
|
|
|
for (p = rst; p; p = p->child[p->child[0] != NULL]) { |
for (p = rst; p; p = p->child[p->child[0] != NULL]) { |
if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) { |
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 && |
} else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size && |
ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { |
ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) { |
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
Line 1943 static zend_mm_free_block *zend_mm_search_large_block(
|
Line 1854 static zend_mm_free_block *zend_mm_search_large_block(
|
} |
} |
|
|
if (best_fit) { |
if (best_fit) { |
return SUHOSIN_MANGLE_PTR(best_fit->next_free_block); | return best_fit->next_free_block; |
} |
} |
bitmap = bitmap >> 1; |
bitmap = bitmap >> 1; |
if (!bitmap) { |
if (!bitmap) { |
Line 1959 static zend_mm_free_block *zend_mm_search_large_block(
|
Line 1870 static zend_mm_free_block *zend_mm_search_large_block(
|
best_fit = p; |
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) |
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; |
zend_mm_free_block *best_fit; |
Line 1974 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1882 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
size_t segment_size; |
size_t segment_size; |
zend_mm_segment *segment; |
zend_mm_segment *segment; |
int keep_rest = 0; |
int keep_rest = 0; |
| #ifdef ZEND_SIGNALS |
| TSRMLS_FETCH(); |
| #endif |
| |
| HANDLE_BLOCK_INTERRUPTIONS(); |
| |
if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) { |
if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) { |
size_t index = ZEND_MM_BUCKET_INDEX(true_size); |
size_t index = ZEND_MM_BUCKET_INDEX(true_size); |
size_t bitmap; |
size_t bitmap; |
Line 1989 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1902 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
heap->cache_stat[index].count--; |
heap->cache_stat[index].count--; |
heap->cache_stat[index].hit++; |
heap->cache_stat[index].hit++; |
#endif |
#endif |
best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]); | best_fit = heap->cache[index]; |
heap->cache[index] = best_fit->prev_free_block; |
heap->cache[index] = best_fit->prev_free_block; |
heap->cached -= true_size; |
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_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); |
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); |
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return ZEND_MM_DATA_OF(best_fit); |
return ZEND_MM_DATA_OF(best_fit); |
} |
} |
#if ZEND_MM_CACHE_STAT |
#if ZEND_MM_CACHE_STAT |
Line 2010 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1919 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
if (bitmap) { |
if (bitmap) { |
/* Found some "small" free block that can be used */ |
/* Found some "small" free block that can be used */ |
index += zend_mm_low_bit(bitmap); |
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 |
#if ZEND_MM_CACHE_STAT |
heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++; |
heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++; |
#endif |
#endif |
Line 2025 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1934 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
best_fit = zend_mm_search_large_block(heap, true_size); |
best_fit = zend_mm_search_large_block(heap, true_size); |
|
|
if (!best_fit && heap->real_size >= heap->limit - heap->block_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; |
size_t best_size = -1; |
|
|
while (p != ZEND_MM_REST_BUCKET(heap)) { |
while (p != ZEND_MM_REST_BUCKET(heap)) { |
Line 2037 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1946 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
best_size = ZEND_MM_FREE_BLOCK_SIZE(p); |
best_fit = p; |
best_fit = p; |
} |
} |
p = SUHOSIN_MANGLE_PTR(p->prev_free_block); | p = p->prev_free_block; |
} |
} |
} |
} |
|
|
Line 2052 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1961 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
segment_size = heap->block_size; |
segment_size = heap->block_size; |
} |
} |
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
|
if (segment_size < true_size || |
if (segment_size < true_size || |
heap->real_size + segment_size > heap->limit) { |
heap->real_size + segment_size > heap->limit) { |
/* Memory limit overflow */ |
/* Memory limit overflow */ |
Line 2075 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
Line 1982 static void *_zend_mm_alloc_int(zend_mm_heap *heap, si
|
#if ZEND_MM_CACHE |
#if ZEND_MM_CACHE |
zend_mm_free_cache(heap); |
zend_mm_free_cache(heap); |
#endif |
#endif |
HANDLE_UNBLOCK_INTERRUPTIONS(); |
|
out_of_memory: |
out_of_memory: |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
#if ZEND_DEBUG |
#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); |
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 |
#else |
Line 2104 out_of_memory:
|
Line 2011 out_of_memory:
|
} else { |
} else { |
zend_mm_finished_searching_for_block: |
zend_mm_finished_searching_for_block: |
/* remove from free list */ |
/* remove from free list */ |
HANDLE_BLOCK_INTERRUPTIONS(); |
|
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED); |
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED); |
ZEND_MM_CHECK_COOKIE(best_fit); |
ZEND_MM_CHECK_COOKIE(best_fit); |
ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit); |
ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit); |
Line 2136 zend_mm_finished_searching_for_block:
|
Line 2042 zend_mm_finished_searching_for_block:
|
|
|
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1); |
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; |
heap->size += true_size; |
if (heap->peak < heap->size) { |
if (heap->peak < heap->size) { |
heap->peak = heap->size; |
heap->peak = heap->size; |
} |
} |
|
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
HANDLE_UNBLOCK_INTERRUPTIONS(); |
| |
return ZEND_MM_DATA_OF(best_fit); |
return ZEND_MM_DATA_OF(best_fit); |
} |
} |
|
|
Line 2158 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
Line 2058 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
zend_mm_block *mm_block; |
zend_mm_block *mm_block; |
zend_mm_block *next_block; |
zend_mm_block *next_block; |
size_t size; |
size_t size; |
| #ifdef ZEND_SIGNALS |
| TSRMLS_FETCH(); |
| #endif |
if (!ZEND_MM_VALID_PTR(p)) { |
if (!ZEND_MM_VALID_PTR(p)) { |
return; |
return; |
} |
} |
|
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
mm_block = ZEND_MM_HEADER_OF(p); |
mm_block = ZEND_MM_HEADER_OF(p); |
size = ZEND_MM_BLOCK_SIZE(mm_block); |
size = ZEND_MM_BLOCK_SIZE(mm_block); |
#if SUHOSIN_PATCH |
|
SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()"); |
|
#endif |
|
ZEND_MM_CHECK_PROTECTION(mm_block); |
ZEND_MM_CHECK_PROTECTION(mm_block); |
|
|
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION |
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION |
memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size); |
memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size); |
#endif |
#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 ZEND_MM_CACHE |
if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) { |
if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) { |
size_t index = ZEND_MM_BUCKET_INDEX(size); |
size_t index = ZEND_MM_BUCKET_INDEX(size); |
zend_mm_free_block **cache = &heap->cache[index]; |
zend_mm_free_block **cache = &heap->cache[index]; |
|
|
((zend_mm_free_block*)mm_block)->prev_free_block = *cache; |
((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; |
heap->cached += size; |
ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED); |
ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED); |
#if ZEND_MM_CACHE_STAT |
#if ZEND_MM_CACHE_STAT |
Line 2192 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
Line 2089 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
heap->cache_stat[index].max_count = heap->cache_stat[index].count; |
heap->cache_stat[index].max_count = heap->cache_stat[index].count; |
} |
} |
#endif |
#endif |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return; |
return; |
} |
} |
#endif |
#endif |
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
|
heap->size -= size; |
heap->size -= size; |
|
|
next_block = ZEND_MM_BLOCK_AT(mm_block, size); |
next_block = ZEND_MM_BLOCK_AT(mm_block, size); |
Line 2220 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
Line 2116 static void _zend_mm_free_int(zend_mm_heap *heap, void
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
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) |
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); |
zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p); |
Line 2230 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2123 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
size_t true_size; |
size_t true_size; |
size_t orig_size; |
size_t orig_size; |
void *ptr; |
void *ptr; |
| #ifdef ZEND_SIGNALS |
| TSRMLS_FETCH(); |
| #endif |
if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) { |
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); |
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); |
mm_block = ZEND_MM_HEADER_OF(p); |
true_size = ZEND_MM_TRUE_SIZE(size); |
true_size = ZEND_MM_TRUE_SIZE(size); |
orig_size = ZEND_MM_BLOCK_SIZE(mm_block); |
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); |
ZEND_MM_CHECK_PROTECTION(mm_block); |
|
|
if (UNEXPECTED(true_size < size)) { |
if (UNEXPECTED(true_size < size)) { |
Line 2256 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2147 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { |
if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { |
zend_mm_free_block *new_free_block; |
zend_mm_free_block *new_free_block; |
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size); |
next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size); |
if (ZEND_MM_IS_FREE_BLOCK(next_block)) { |
if (ZEND_MM_IS_FREE_BLOCK(next_block)) { |
remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block); |
remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block); |
Line 2272 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2162 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
/* add the new free block to the free list */ |
/* add the new free block to the free list */ |
zend_mm_add_to_free_list(heap, new_free_block); |
zend_mm_add_to_free_list(heap, new_free_block); |
heap->size += (true_size - orig_size); |
heap->size += (true_size - orig_size); |
HANDLE_UNBLOCK_INTERRUPTIONS(); |
|
} |
} |
ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0); |
ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0); |
#if SUHOSIN_PATCH | HANDLE_UNBLOCK_INTERRUPTIONS(); |
SUHOSIN_MM_SET_CANARIES(mm_block); | |
((zend_mm_block*)mm_block)->info.size = size; | |
SUHOSIN_MM_SET_END_CANARY(mm_block); | |
#endif | |
return p; |
return p; |
} |
} |
|
|
Line 2295 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2180 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
heap->cache_stat[index].count--; |
heap->cache_stat[index].count--; |
heap->cache_stat[index].hit++; |
heap->cache_stat[index].hit++; |
#endif |
#endif |
best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]); | best_fit = heap->cache[index]; |
heap->cache[index] = best_fit->prev_free_block; |
heap->cache[index] = best_fit->prev_free_block; |
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); |
ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED); |
ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0); | 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 | |
| |
ptr = ZEND_MM_DATA_OF(best_fit); |
ptr = ZEND_MM_DATA_OF(best_fit); |
|
|
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION |
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION |
memcpy(ptr, p, mm_block->debug.size); |
memcpy(ptr, p, mm_block->debug.size); |
#else |
#else |
memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE); | memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE); |
#endif |
#endif |
|
|
heap->cached -= true_size - orig_size; |
heap->cached -= true_size - orig_size; |
Line 2319 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2199 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
cache = &heap->cache[index]; |
cache = &heap->cache[index]; |
|
|
((zend_mm_free_block*)mm_block)->prev_free_block = *cache; |
((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); |
ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED); |
#if ZEND_MM_CACHE_STAT |
#if ZEND_MM_CACHE_STAT |
if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) { |
if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) { |
heap->cache_stat[index].max_count = heap->cache_stat[index].count; |
heap->cache_stat[index].max_count = heap->cache_stat[index].count; |
} |
} |
#endif |
#endif |
|
|
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return ptr; |
return ptr; |
} |
} |
} |
} |
Line 2340 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2222 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 block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block); |
size_t remaining_size = block_size - true_size; |
size_t remaining_size = block_size - true_size; |
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block); |
zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block); |
|
|
if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { |
if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) { |
Line 2368 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2249 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
heap->peak = heap->size; |
heap->peak = heap->size; |
} |
} |
HANDLE_UNBLOCK_INTERRUPTIONS(); |
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; |
return p; |
} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) && |
} 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)))) { |
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); |
zend_mm_remove_from_free_list(heap, (zend_mm_free_block *) next_block); |
goto realloc_segment; |
goto realloc_segment; |
} |
} |
Line 2387 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
Line 2262 static void *_zend_mm_realloc_int(zend_mm_heap *heap,
|
size_t block_size; |
size_t block_size; |
size_t remaining_size; |
size_t remaining_size; |
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
realloc_segment: |
realloc_segment: |
/* segment size, size of block and size of guard block */ |
/* 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)) { |
if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) { |
Line 2420 realloc_segment:
|
Line 2294 realloc_segment:
|
#if ZEND_MM_CACHE |
#if ZEND_MM_CACHE |
zend_mm_free_cache(heap); |
zend_mm_free_cache(heap); |
#endif |
#endif |
HANDLE_UNBLOCK_INTERRUPTIONS(); |
|
out_of_memory: |
out_of_memory: |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
#if ZEND_DEBUG |
#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); |
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 |
#else |
Line 2475 out_of_memory:
|
Line 2349 out_of_memory:
|
} |
} |
|
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
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); |
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); |
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 |
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION |
memcpy(ptr, p, mm_block->debug.size); |
memcpy(ptr, p, mm_block->debug.size); |
#else |
#else |
memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE); | memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE); |
#endif |
#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); |
_zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
#endif | HANDLE_UNBLOCK_INTERRUPTIONS(); |
return ptr; |
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) |
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 | return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
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 | |
} |
} |
|
|
ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
{ |
{ |
#if SUHOSIN_PATCH | _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
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_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
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 | return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
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 | |
} |
} |
|
|
ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
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; |
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)) { |
if (!ZEND_MM_VALID_PTR(p)) { |
return 0; |
return 0; |
} |
} |
Line 2554 ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap
|
Line 2393 ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap
|
return ZEND_MM_BLOCK_SIZE(mm_block); |
return ZEND_MM_BLOCK_SIZE(mm_block); |
#endif |
#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 */ |
/* Allocation Manager */ |
/**********************/ |
/**********************/ |
Line 2589 static int alloc_globals_id;
|
Line 2410 static int alloc_globals_id;
|
static zend_alloc_globals alloc_globals; |
static zend_alloc_globals alloc_globals; |
#endif |
#endif |
|
|
#ifndef SUHOSIN_MM_CLONE_FILE |
|
ZEND_API int is_zend_mm(TSRMLS_D) |
ZEND_API int is_zend_mm(TSRMLS_D) |
{ |
{ |
return AG(mm_heap)->use_zend_alloc; |
return AG(mm_heap)->use_zend_alloc; |
Line 2602 ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC
|
Line 2422 ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC
|
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
return AG(mm_heap)->_malloc(size); |
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); |
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) |
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
Line 2619 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_
|
Line 2433 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_
|
AG(mm_heap)->_free(ptr); |
AG(mm_heap)->_free(ptr); |
return; |
return; |
} |
} |
#if SUHOSIN_PATCH | _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
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_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
Line 2635 ZEND_API void *_erealloc(void *ptr, size_t size, int a
|
Line 2443 ZEND_API void *_erealloc(void *ptr, size_t size, int a
|
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
return AG(mm_heap)->_realloc(ptr, size); |
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); |
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) |
ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
Line 2649 ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_
|
Line 2451 ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_
|
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) { |
return 0; |
return 0; |
} |
} |
#if SUHOSIN_PATCH | return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
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 | |
} |
} |
#endif |
|
|
|
#if defined(__GNUC__) && defined(i386) | #if defined(__GNUC__) && (defined(__native_client__) || defined(i386)) |
|
|
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) |
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset) |
{ |
{ |
size_t res = nmemb; |
size_t res = nmemb; |
unsigned long overflow = 0; |
unsigned long overflow = 0; |
|
|
__asm__ ("mull %3\n\taddl %4,%0\n\tadcl %1,%1" | __asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1" |
: "=&a"(res), "=&d" (overflow) |
: "=&a"(res), "=&d" (overflow) |
: "%0"(res), |
: "%0"(res), |
"rm"(size), |
"rm"(size), |
Line 2686 static inline size_t safe_address(size_t nmemb, size_t
|
Line 2481 static inline size_t safe_address(size_t nmemb, size_t
|
size_t res = nmemb; |
size_t res = nmemb; |
unsigned long overflow = 0; |
unsigned long overflow = 0; |
|
|
__asm__ ("mulq %3\n\taddq %4,%0\n\tadcq %1,%1" | #ifdef __ILP32__ /* x32 */ |
| # define LP_SUFF "l" |
| #else /* amd64 */ |
| # define LP_SUFF "q" |
| #endif |
| |
| __asm__ ("mul" LP_SUFF " %3\n\t" |
| "add %4,%0\n\t" |
| "adc $0,%1" |
: "=&a"(res), "=&d" (overflow) |
: "=&a"(res), "=&d" (overflow) |
: "%0"(res), |
: "%0"(res), |
"rm"(size), |
"rm"(size), |
"rm"(offset)); |
"rm"(offset)); |
|
|
|
#undef LP_SUFF |
|
|
if (UNEXPECTED(overflow)) { |
if (UNEXPECTED(overflow)) { |
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); |
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); |
return 0; |
return 0; |
Line 2728 static inline size_t safe_address(size_t nmemb, size_t
|
Line 2533 static inline size_t safe_address(size_t nmemb, size_t
|
} |
} |
#endif |
#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) |
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)); |
return emalloc_rel(safe_address(nmemb, size, offset)); |
Line 2753 ZEND_API void *_safe_realloc(void *ptr, size_t nmemb,
|
Line 2558 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) |
ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
{ |
{ |
void *p; |
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); |
p = _safe_emalloc(nmemb, size, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
if (UNEXPECTED(p == NULL)) { |
if (UNEXPECTED(p == NULL)) { |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
memset(p, 0, size * nmemb); |
memset(p, 0, size * nmemb); |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
|
|
Line 2766 ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_D
|
Line 2577 ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_D
|
{ |
{ |
int length; |
int length; |
char *p; |
char *p; |
|
#ifdef ZEND_SIGNALS |
|
TSRMLS_FETCH(); |
|
#endif |
|
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
length = strlen(s)+1; |
length = strlen(s)+1; |
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
p = (char *) _emalloc(length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
if (UNEXPECTED(p == NULL)) { |
if (UNEXPECTED(p == NULL)) { |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
memcpy(p, s, length); |
memcpy(p, s, length); |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
|
|
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) |
{ |
{ |
char *p; |
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); |
p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); |
if (UNEXPECTED(p == NULL)) { |
if (UNEXPECTED(p == NULL)) { |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
memcpy(p, s, length); |
memcpy(p, s, length); |
p[length] = 0; |
p[length] = 0; |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
|
|
Line 2793 ZEND_API char *_estrndup(const char *s, uint length ZE
|
Line 2618 ZEND_API char *_estrndup(const char *s, uint length ZE
|
ZEND_API char *zend_strndup(const char *s, uint length) |
ZEND_API char *zend_strndup(const char *s, uint length) |
{ |
{ |
char *p; |
char *p; |
|
#ifdef ZEND_SIGNALS |
|
TSRMLS_FETCH(); |
|
#endif |
|
|
|
HANDLE_BLOCK_INTERRUPTIONS(); |
|
|
p = (char *) malloc(length+1); |
p = (char *) malloc(length+1); |
if (UNEXPECTED(p == NULL)) { |
if (UNEXPECTED(p == NULL)) { |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
if (length) { |
if (length) { |
memcpy(p, s, length); |
memcpy(p, s, length); |
} |
} |
p[length] = 0; |
p[length] = 0; |
|
HANDLE_UNBLOCK_INTERRUPTIONS(); |
return p; |
return p; |
} |
} |
|
|
Line 2841 ZEND_API void shutdown_memory_manager(int silent, int
|
Line 2673 ZEND_API void shutdown_memory_manager(int silent, int
|
{ |
{ |
zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC); |
zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC); |
} |
} |
#endif |
|
|
|
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC) |
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC) |
{ |
{ |
char *tmp; | char *tmp = getenv("USE_ZEND_ALLOC"); |
alloc_globals->mm_heap = zend_mm_startup(); | |
|
|
tmp = getenv("USE_ZEND_ALLOC"); | if (tmp && !zend_atoi(tmp, 0)) { |
if (tmp) { | alloc_globals->mm_heap = malloc(sizeof(struct _zend_mm_heap)); |
alloc_globals->mm_heap->use_zend_alloc = zend_atoi(tmp, 0); | memset(alloc_globals->mm_heap, 0, sizeof(struct _zend_mm_heap)); |
if (!alloc_globals->mm_heap->use_zend_alloc) { | alloc_globals->mm_heap->use_zend_alloc = 0; |
alloc_globals->mm_heap->_malloc = malloc; | alloc_globals->mm_heap->_malloc = malloc; |
alloc_globals->mm_heap->_free = free; | alloc_globals->mm_heap->_free = free; |
alloc_globals->mm_heap->_realloc = realloc; | alloc_globals->mm_heap->_realloc = realloc; |
} | } else { |
| alloc_globals->mm_heap = zend_mm_startup(); |
} |
} |
} |
} |
|
|
Line 2866 static void alloc_globals_dtor(zend_alloc_globals *all
|
Line 2697 static void alloc_globals_dtor(zend_alloc_globals *all
|
} |
} |
#endif |
#endif |
|
|
#ifndef SUHOSIN_MM_CLONE_FILE |
|
ZEND_API void start_memory_manager(TSRMLS_D) |
ZEND_API void start_memory_manager(TSRMLS_D) |
{ |
{ |
#ifdef ZTS |
#ifdef ZTS |
Line 2930 ZEND_API void _full_mem_check(int silent ZEND_FILE_LIN
|
Line 2760 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("End of full memory check %s:%d (%d errors)\n" ZEND_FILE_LINE_RELAY_CC, errors); |
zend_debug_alloc_output("------------------------------------------------\n"); |
zend_debug_alloc_output("------------------------------------------------\n"); |
} |
} |
#endif |
|
#endif |
#endif |
|
|
/* |
/* |