Magellan Linux

Annotation of /trunk/php/patches/php-5.3.9-suhosin-0.9.10.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1712 - (hide annotations) (download)
Fri Mar 23 13:04:18 2012 UTC (12 years, 1 month ago) by niro
File size: 196666 byte(s)
-added new suhosin patch
1 niro 1712 diff -Nura php-5.3.9/Zend/Makefile.am suhosin-patch-5.3.9-0.9.10/Zend/Makefile.am
2     --- php-5.3.9/Zend/Makefile.am 2009-03-18 11:18:10.000000000 +0100
3     +++ suhosin-patch-5.3.9-0.9.10/Zend/Makefile.am 2012-01-11 19:29:07.000000000 +0100
4     @@ -17,7 +17,7 @@
5     zend_objects_API.c zend_ts_hash.c zend_stream.c \
6     zend_default_classes.c \
7     zend_iterators.c zend_interfaces.c zend_exceptions.c \
8     - zend_strtod.c zend_closures.c zend_float.c
9     + zend_strtod.c zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c
10    
11     libZend_la_LDFLAGS =
12     libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
13     diff -Nura php-5.3.9/Zend/Zend.dsp suhosin-patch-5.3.9-0.9.10/Zend/Zend.dsp
14     --- php-5.3.9/Zend/Zend.dsp 2009-03-18 11:18:10.000000000 +0100
15     +++ suhosin-patch-5.3.9-0.9.10/Zend/Zend.dsp 2012-01-11 19:29:07.000000000 +0100
16     @@ -247,6 +247,14 @@
17     # End Source File
18     # Begin Source File
19    
20     +SOURCE=.\zend_canary.c
21     +# End Source File
22     +# Begin Source File
23     +
24     +SOURCE=.\zend_alloc_canary.c
25     +# End Source File
26     +# Begin Source File
27     +
28     SOURCE=.\zend_ts_hash.c
29     # End Source File
30     # Begin Source File
31     diff -Nura php-5.3.9/Zend/ZendTS.dsp suhosin-patch-5.3.9-0.9.10/Zend/ZendTS.dsp
32     --- php-5.3.9/Zend/ZendTS.dsp 2008-07-14 11:49:03.000000000 +0200
33     +++ suhosin-patch-5.3.9-0.9.10/Zend/ZendTS.dsp 2012-01-11 19:29:07.000000000 +0100
34     @@ -277,6 +277,14 @@
35     # End Source File
36     # Begin Source File
37    
38     +SOURCE=.\zend_canary.c
39     +# End Source File
40     +# Begin Source File
41     +
42     +SOURCE=.\zend_alloc_canary.c
43     +# End Source File
44     +# Begin Source File
45     +
46     SOURCE=.\zend_ts_hash.c
47     # End Source File
48     # Begin Source File
49     diff -Nura php-5.3.9/Zend/zend.c suhosin-patch-5.3.9-0.9.10/Zend/zend.c
50     --- php-5.3.9/Zend/zend.c 2012-01-01 14:15:04.000000000 +0100
51     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend.c 2012-01-11 19:29:07.000000000 +0100
52     @@ -60,6 +60,10 @@
53     ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
54     ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
55    
56     +#if SUHOSIN_PATCH
57     +ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
58     +#endif
59     +
60     void (*zend_on_timeout)(int seconds TSRMLS_DC);
61    
62     static void (*zend_message_dispatcher_p)(long message, void *data TSRMLS_DC);
63     @@ -88,6 +92,74 @@
64     }
65     /* }}} */
66    
67     +#if SUHOSIN_PATCH
68     +static ZEND_INI_MH(OnUpdateSuhosin_log_syslog)
69     +{
70     + if (!new_value) {
71     + SPG(log_syslog) = S_ALL & ~S_SQL | S_MEMORY;
72     + } else {
73     + SPG(log_syslog) = atoi(new_value) | S_MEMORY;
74     + }
75     + return SUCCESS;
76     +}
77     +static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_facility)
78     +{
79     + if (!new_value) {
80     + SPG(log_syslog_facility) = LOG_USER;
81     + } else {
82     + SPG(log_syslog_facility) = atoi(new_value);
83     + }
84     + return SUCCESS;
85     +}
86     +static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_priority)
87     +{
88     + if (!new_value) {
89     + SPG(log_syslog_priority) = LOG_ALERT;
90     + } else {
91     + SPG(log_syslog_priority) = atoi(new_value);
92     + }
93     + return SUCCESS;
94     +}
95     +static ZEND_INI_MH(OnUpdateSuhosin_log_sapi)
96     +{
97     + if (!new_value) {
98     + SPG(log_sapi) = S_ALL & ~S_SQL;
99     + } else {
100     + SPG(log_sapi) = atoi(new_value);
101     + }
102     + return SUCCESS;
103     +}
104     +static ZEND_INI_MH(OnUpdateSuhosin_log_script)
105     +{
106     + if (!new_value) {
107     + SPG(log_script) = S_ALL & ~S_MEMORY;
108     + } else {
109     + SPG(log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
110     + }
111     + return SUCCESS;
112     +}
113     +static ZEND_INI_MH(OnUpdateSuhosin_log_scriptname)
114     +{
115     + if (SPG(log_scriptname)) {
116     + pefree(SPG(log_scriptname),1);
117     + }
118     + SPG(log_scriptname) = NULL;
119     + if (new_value) {
120     + SPG(log_scriptname) = pestrdup(new_value,1);
121     + }
122     + return SUCCESS;
123     +}
124     +static ZEND_INI_MH(OnUpdateSuhosin_log_phpscript)
125     +{
126     + if (!new_value) {
127     + SPG(log_phpscript) = S_ALL & ~S_MEMORY;
128     + } else {
129     + SPG(log_phpscript) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
130     + }
131     + return SUCCESS;
132     +}
133     +#endif
134     +
135     ZEND_INI_BEGIN()
136     ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
137     STD_ZEND_INI_BOOLEAN("zend.enable_gc", "1", ZEND_INI_ALL, OnUpdateGCEnabled, gc_enabled, zend_gc_globals, gc_globals)
138     diff -Nura php-5.3.9/Zend/zend.h suhosin-patch-5.3.9-0.9.10/Zend/zend.h
139     --- php-5.3.9/Zend/zend.h 2012-01-01 14:15:04.000000000 +0100
140     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend.h 2012-01-11 19:29:07.000000000 +0100
141     @@ -627,6 +627,9 @@
142     extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
143     extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
144     extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
145     +#if SUHOSIN_PATCH
146     +extern ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
147     +#endif
148    
149     ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
150    
151     @@ -774,6 +777,16 @@
152     #define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
153     #define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1)
154    
155     +#if SUHOSIN_PATCH
156     +#include "suhosin_globals.h"
157     +#include "suhosin_patch.h"
158     +#include "php_syslog.h"
159     +
160     +ZEND_API void zend_canary(void *buf, int len);
161     +ZEND_API char suhosin_get_config(int element);
162     +
163     +#endif
164     +
165     #endif /* ZEND_H */
166    
167     /*
168     diff -Nura php-5.3.9/Zend/zend_alloc.c suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc.c
169     --- php-5.3.9/Zend/zend_alloc.c 2012-01-01 14:15:04.000000000 +0100
170     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc.c 2012-01-11 19:29:07.000000000 +0100
171     @@ -32,6 +32,10 @@
172     # include <unistd.h>
173     #endif
174    
175     +#if SUHOSIN_PATCH
176     +#include "suhosin_patch.h"
177     +#endif
178     +
179     #ifdef ZEND_WIN32
180     # include <wincrypt.h>
181     # include <process.h>
182     @@ -59,6 +63,7 @@
183     # define PTR_FMT "0x%0.8lx"
184     #endif
185    
186     +#ifndef SUHOSIN_MM_CLONE_FILE
187     #if ZEND_DEBUG
188     void zend_debug_alloc_output(char *format, ...)
189     {
190     @@ -76,6 +81,7 @@
191     #endif
192     }
193     #endif
194     +#endif
195    
196     #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
197     static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
198     @@ -134,6 +140,8 @@
199     # endif
200     #endif
201    
202     +static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
203     +
204     static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
205     {
206     return malloc(sizeof(zend_mm_storage));
207     @@ -332,13 +340,28 @@
208     #define MEM_BLOCK_GUARD 0x2A8FCC84
209     #define MEM_BLOCK_LEAK 0x6C5E8F2D
210    
211     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
212     +# define CANARY_SIZE sizeof(size_t)
213     +#else
214     +# define CANARY_SIZE 0
215     +#endif
216     +
217     /* mm block type */
218     typedef struct _zend_mm_block_info {
219     #if ZEND_MM_COOKIES
220     size_t _cookie;
221     #endif
222     - size_t _size;
223     - size_t _prev;
224     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
225     + size_t canary_1;
226     +#endif
227     + size_t _size;
228     + size_t _prev;
229     +#if SUHOSIN_PATCH
230     + size_t size;
231     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
232     + size_t canary_2;
233     +#endif
234     +#endif
235     } zend_mm_block_info;
236    
237     #if ZEND_DEBUG
238     @@ -412,7 +435,7 @@
239     # define ZEND_MM_CACHE_STAT 0
240     #endif
241    
242     -struct _zend_mm_heap {
243     +typedef struct _zend_mm_heap {
244     int use_zend_alloc;
245     void *(*_malloc)(size_t);
246     void (*_free)(void*);
247     @@ -447,6 +470,9 @@
248     int miss;
249     } cache_stat[ZEND_MM_NUM_BUCKETS+1];
250     #endif
251     +#if SUHOSIN_PATCH
252     + size_t canary_1,canary_2,canary_3;
253     +#endif
254     };
255    
256     #define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
257     @@ -520,18 +546,31 @@
258     /* optimized access */
259     #define ZEND_MM_FREE_BLOCK_SIZE(b) (b)->info._size
260    
261     +#ifndef ZEND_MM_ALIGNMENT
262     +# define ZEND_MM_ALIGNMENT 8
263     +# define ZEND_MM_ALIGNMENT_LOG2 3
264     +#elif ZEND_MM_ALIGNMENT < 4
265     +# undef ZEND_MM_ALIGNMENT
266     +# undef ZEND_MM_ALIGNMENT_LOG2
267     +# define ZEND_MM_ALIGNMENT 4
268     +# define ZEND_MM_ALIGNMENT_LOG2 2
269     +#endif
270     +
271     +#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
272     +
273     /* Aligned header size */
274     +#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
275     #define ZEND_MM_ALIGNED_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
276     #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
277     -#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE)
278     +#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)
279     #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)
280     #define ZEND_MM_ALIGNED_SEGMENT_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
281    
282     -#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)
283     +#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)
284    
285     #define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
286    
287     -#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)))
288     +#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)))
289    
290     #define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
291    
292     @@ -593,6 +632,44 @@
293    
294     #endif
295    
296     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
297     +
298     +# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \
299     + char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \
300     + if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \
301     + canary_mismatch: \
302     + zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
303     + 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; }\
304     + } \
305     + memcpy(&check, p, CANARY_SIZE); \
306     + if (check != heap->canary_3) { \
307     + zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
308     + if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \
309     + } \
310     + } while (0)
311     +
312     +# define SUHOSIN_MM_SET_CANARIES(block) do { \
313     + (block)->info.canary_1 = heap->canary_1; \
314     + (block)->info.canary_2 = heap->canary_2; \
315     + } while (0)
316     +
317     +# define SUHOSIN_MM_END_CANARY_PTR(block) \
318     + (char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block*)(block))->info.size + END_MAGIC_SIZE)
319     +
320     +# define SUHOSIN_MM_SET_END_CANARY(block) do { \
321     + char *p = SUHOSIN_MM_END_CANARY_PTR(block); \
322     + memcpy(p, &heap->canary_3, CANARY_SIZE); \
323     + } while (0)
324     +
325     +#else
326     +
327     +# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION)
328     +# define SUHOSIN_MM_SET_CANARIES(block)
329     +# define SUHOSIN_MM_END_CANARY_PTR(block)
330     +# define SUHOSIN_MM_SET_END_CANARY(block)
331     +
332     +#endif
333     +
334    
335     #if ZEND_MM_HEAP_PROTECTION
336    
337     @@ -715,7 +792,7 @@
338     #endif
339     }
340    
341     -static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
342     +static void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
343     {
344     zend_mm_free_block *prev, *next;
345    
346     @@ -725,14 +802,14 @@
347     mm_block->parent = NULL;
348     }
349    
350     - prev = heap->rest_buckets[0];
351     - next = prev->next_free_block;
352     - mm_block->prev_free_block = prev;
353     - mm_block->next_free_block = next;
354     - prev->next_free_block = next->prev_free_block = mm_block;
355     + prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
356     + next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
357     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
358     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
359     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
360     }
361    
362     -static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
363     +static void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
364     {
365     size_t size;
366     size_t index;
367     @@ -749,7 +826,7 @@
368     if (!*p) {
369     *p = mm_block;
370     mm_block->parent = p;
371     - mm_block->prev_free_block = mm_block->next_free_block = mm_block;
372     + mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
373     heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
374     } else {
375     size_t m;
376     @@ -762,15 +839,15 @@
377     if (!*p) {
378     *p = mm_block;
379     mm_block->parent = p;
380     - mm_block->prev_free_block = mm_block->next_free_block = mm_block;
381     + mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
382     break;
383     }
384     } else {
385     - zend_mm_free_block *next = prev->next_free_block;
386     + zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
387    
388     - prev->next_free_block = next->prev_free_block = mm_block;
389     - mm_block->next_free_block = next;
390     - mm_block->prev_free_block = prev;
391     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
392     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
393     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
394     mm_block->parent = NULL;
395     break;
396     }
397     @@ -782,27 +859,33 @@
398     index = ZEND_MM_BUCKET_INDEX(size);
399    
400     prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
401     - if (prev->prev_free_block == prev) {
402     + if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) {
403     heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
404     }
405     - next = prev->next_free_block;
406     + next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
407    
408     - mm_block->prev_free_block = prev;
409     - mm_block->next_free_block = next;
410     - prev->next_free_block = next->prev_free_block = mm_block;
411     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
412     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
413     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
414     }
415     }
416    
417     -static inline void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
418     +static void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
419     {
420     - zend_mm_free_block *prev = mm_block->prev_free_block;
421     - zend_mm_free_block *next = mm_block->next_free_block;
422     + zend_mm_free_block *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
423     + zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block);
424    
425     ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
426    
427     if (EXPECTED(prev == mm_block)) {
428     zend_mm_free_block **rp, **cp;
429    
430     +#if SUHOSIN_PATCH
431     + if (next != mm_block) {
432     + zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block);
433     + _exit(1);
434     + }
435     +#endif
436     #if ZEND_MM_SAFE_UNLINKING
437     if (UNEXPECTED(next != mm_block)) {
438     zend_mm_panic("zend_mm_heap corrupted");
439     @@ -841,14 +924,21 @@
440     }
441     } else {
442    
443     +#if SUHOSIN_PATCH
444     + if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) {
445     + zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block);
446     + _exit(1);
447     + }
448     +#endif
449     +
450     #if ZEND_MM_SAFE_UNLINKING
451     - if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block != mm_block)) {
452     + if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) {
453     zend_mm_panic("zend_mm_heap corrupted");
454     }
455     #endif
456    
457     - prev->next_free_block = next;
458     - next->prev_free_block = prev;
459     + prev->next_free_block = SUHOSIN_MANGLE_PTR(next);
460     + next->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
461    
462     if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
463     if (EXPECTED(prev == next)) {
464     @@ -864,7 +954,7 @@
465     }
466     }
467    
468     -static inline void zend_mm_init(zend_mm_heap *heap)
469     +static void zend_mm_init(zend_mm_heap *heap)
470     {
471     zend_mm_free_block* p;
472     int i;
473     @@ -882,12 +972,19 @@
474     #endif
475     p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
476     for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
477     - p->next_free_block = p;
478     - p->prev_free_block = p;
479     + p->next_free_block = SUHOSIN_MANGLE_PTR(p);
480     + p->prev_free_block = SUHOSIN_MANGLE_PTR(p);
481     p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
482     heap->large_free_buckets[i] = NULL;
483     }
484     - heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
485     + heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap));
486     +#if SUHOSIN_PATCH
487     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
488     + zend_canary(&heap->canary_1, sizeof(heap->canary_1));
489     + zend_canary(&heap->canary_2, sizeof(heap->canary_2));
490     + zend_canary(&heap->canary_3, sizeof(heap->canary_3));
491     + }
492     +#endif
493     }
494    
495     static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
496     @@ -908,12 +1005,13 @@
497     int i;
498    
499     for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
500     + /* NULL means NULL even MANGLED */
501     if (heap->cache[i]) {
502     - zend_mm_free_block *mm_block = heap->cache[i];
503     + zend_mm_free_block *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]);
504    
505     while (mm_block) {
506     size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
507     - zend_mm_free_block *q = mm_block->prev_free_block;
508     + zend_mm_free_block *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
509     zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
510    
511     heap->cached -= size;
512     @@ -1009,14 +1107,20 @@
513     /* }}} */
514     #endif
515    
516     +
517     /* Notes:
518     * - This function may alter the block_sizes values to match platform alignment
519     * - This function does *not* perform sanity checks on the arguments
520     */
521     -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)
522     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
523     +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)
524     +#else
525     +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)
526     +#endif
527     {
528     zend_mm_storage *storage;
529     zend_mm_heap *heap;
530     + zend_mm_free_block *tmp;
531    
532     #if 0
533     int i;
534     @@ -1050,6 +1154,12 @@
535     }
536     #endif
537    
538     + /* get the pointer guardian and ensure low 3 bits are 1 */
539     + if (SUHOSIN_POINTER_GUARD == 0) {
540     + zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
541     + SUHOSIN_POINTER_GUARD |= 7;
542     + }
543     +
544     if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
545     fprintf(stderr, "'block_size' must be a power of two\n");
546     /* See http://support.microsoft.com/kb/190351 */
547     @@ -1077,6 +1187,7 @@
548     #endif
549     exit(255);
550     }
551     +
552     heap->storage = storage;
553     heap->block_size = block_size;
554     heap->compact_size = 0;
555     @@ -1097,12 +1208,12 @@
556     heap->reserve = NULL;
557     heap->reserve_size = reserve_size;
558     if (reserve_size > 0) {
559     - heap->reserve = _zend_mm_alloc_int(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
560     + heap->reserve = _zend_mm_alloc(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
561     }
562     if (internal) {
563     int i;
564     zend_mm_free_block *p, *q, *orig;
565     - zend_mm_heap *mm_heap = _zend_mm_alloc_int(heap, sizeof(zend_mm_heap) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
566     + zend_mm_heap *mm_heap = _zend_mm_alloc(heap, sizeof(zend_mm_heap) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
567    
568     *mm_heap = *heap;
569    
570     @@ -1110,22 +1221,22 @@
571     orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
572     for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
573     q = p;
574     - while (q->prev_free_block != orig) {
575     - q = q->prev_free_block;
576     + while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) {
577     + q = SUHOSIN_MANGLE_PTR(q->prev_free_block);
578     }
579     - q->prev_free_block = p;
580     + q->prev_free_block = SUHOSIN_MANGLE_PTR(p);
581     q = p;
582     - while (q->next_free_block != orig) {
583     - q = q->next_free_block;
584     + while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) {
585     + q = SUHOSIN_MANGLE_PTR(q->next_free_block);
586     }
587     - q->next_free_block = p;
588     + q->next_free_block = SUHOSIN_MANGLE_PTR(p);
589     p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
590     orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2);
591     if (mm_heap->large_free_buckets[i]) {
592     mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
593     }
594     }
595     - mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(mm_heap);
596     + mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap));
597    
598     free(heap);
599     heap = mm_heap;
600     @@ -1133,7 +1244,11 @@
601     return heap;
602     }
603    
604     -ZEND_API zend_mm_heap *zend_mm_startup(void)
605     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
606     +zend_mm_heap *__zend_mm_startup_canary(void)
607     +#else
608     +static zend_mm_heap *__zend_mm_startup(void)
609     +#endif
610     {
611     int i;
612     size_t seg_size;
613     @@ -1203,6 +1318,27 @@
614     return heap;
615     }
616    
617     +#ifndef SUHOSIN_MM_CLONE_FILE
618     +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);
619     +zend_mm_heap_canary *__zend_mm_startup_canary(void);
620     +
621     +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)
622     +{
623     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
624     + return (zend_mm_heap *)__zend_mm_startup_canary_ex(handlers, block_size, reserve_size, internal, params);
625     + }
626     + return __zend_mm_startup_ex(handlers, block_size, reserve_size, internal, params);
627     +}
628     +ZEND_API zend_mm_heap *zend_mm_startup(void)
629     +{
630     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
631     + return (zend_mm_heap *)__zend_mm_startup_canary();
632     + }
633     + return __zend_mm_startup();
634     +}
635     +
636     +#endif
637     +
638     #if ZEND_DEBUG
639     static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
640     {
641     @@ -1571,7 +1707,11 @@
642     }
643     #endif
644    
645     -ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
646     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
647     +void __zend_mm_shutdown_canary(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
648     +#else
649     +static void __zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
650     +#endif
651     {
652     zend_mm_storage *storage;
653     zend_mm_segment *segment;
654     @@ -1581,7 +1721,7 @@
655     if (heap->reserve) {
656     #if ZEND_DEBUG
657     if (!silent) {
658     - _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
659     + _zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
660     }
661     #endif
662     heap->reserve = NULL;
663     @@ -1664,12 +1804,23 @@
664     heap->size = 0;
665     heap->peak = 0;
666     if (heap->reserve_size) {
667     - heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
668     + heap->reserve = _zend_mm_alloc(heap, heap->reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
669     }
670     heap->overflow = 0;
671     }
672     }
673    
674     +#ifndef SUHOSIN_MM_CLONE_FILE
675     +ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
676     +{
677     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
678     + __zend_mm_shutdown_canary(heap, full_shutdown, silent TSRMLS_CC);
679     + return;
680     + }
681     + __zend_mm_shutdown(heap, full_shutdown, silent TSRMLS_CC);
682     +}
683     +#endif
684     +
685     static void zend_mm_safe_error(zend_mm_heap *heap,
686     const char *format,
687     size_t limit,
688     @@ -1680,7 +1831,11 @@
689     size_t size)
690     {
691     if (heap->reserve) {
692     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
693     + _zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
694     +#else
695     _zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
696     +#endif
697     heap->reserve = NULL;
698     }
699     if (heap->overflow == 0) {
700     @@ -1755,7 +1910,7 @@
701     p = heap->large_free_buckets[index];
702     for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
703     if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
704     - return p->next_free_block;
705     + return SUHOSIN_MANGLE_PTR(p->next_free_block);
706     } else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
707     ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
708     best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
709     @@ -1779,7 +1934,7 @@
710    
711     for (p = rst; p; p = p->child[p->child[0] != NULL]) {
712     if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
713     - return p->next_free_block;
714     + return SUHOSIN_MANGLE_PTR(p->next_free_block);
715     } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
716     ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
717     best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
718     @@ -1788,7 +1943,7 @@
719     }
720    
721     if (best_fit) {
722     - return best_fit->next_free_block;
723     + return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
724     }
725     bitmap = bitmap >> 1;
726     if (!bitmap) {
727     @@ -1804,9 +1959,12 @@
728     best_fit = p;
729     }
730     }
731     - return best_fit->next_free_block;
732     + return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
733     }
734    
735     +#if SUHOSIN_PATCH
736     +void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
737     +#endif
738     static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
739     {
740     zend_mm_free_block *best_fit;
741     @@ -1816,7 +1974,7 @@
742     size_t segment_size;
743     zend_mm_segment *segment;
744     int keep_rest = 0;
745     -
746     +
747     if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
748     size_t index = ZEND_MM_BUCKET_INDEX(true_size);
749     size_t bitmap;
750     @@ -1831,9 +1989,14 @@
751     heap->cache_stat[index].count--;
752     heap->cache_stat[index].hit++;
753     #endif
754     - best_fit = heap->cache[index];
755     + best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
756     heap->cache[index] = best_fit->prev_free_block;
757     heap->cached -= true_size;
758     +#if SUHOSIN_PATCH
759     + SUHOSIN_MM_SET_CANARIES(best_fit);
760     + ((zend_mm_block*)best_fit)->info.size = size;
761     + SUHOSIN_MM_SET_END_CANARY(best_fit);
762     +#endif
763     ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
764     ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
765     return ZEND_MM_DATA_OF(best_fit);
766     @@ -1847,7 +2010,7 @@
767     if (bitmap) {
768     /* Found some "small" free block that can be used */
769     index += zend_mm_low_bit(bitmap);
770     - best_fit = heap->free_buckets[index*2];
771     + best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]);
772     #if ZEND_MM_CACHE_STAT
773     heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
774     #endif
775     @@ -1862,7 +2025,7 @@
776     best_fit = zend_mm_search_large_block(heap, true_size);
777    
778     if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
779     - zend_mm_free_block *p = heap->rest_buckets[0];
780     + zend_mm_free_block *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
781     size_t best_size = -1;
782    
783     while (p != ZEND_MM_REST_BUCKET(heap)) {
784     @@ -1874,7 +2037,7 @@
785     best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
786     best_fit = p;
787     }
788     - p = p->prev_free_block;
789     + p = SUHOSIN_MANGLE_PTR(p->prev_free_block);
790     }
791     }
792    
793     @@ -1973,13 +2136,19 @@
794    
795     ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
796    
797     +#if SUHOSIN_PATCH
798     + SUHOSIN_MM_SET_CANARIES(best_fit);
799     + ((zend_mm_block*)best_fit)->info.size = size;
800     + SUHOSIN_MM_SET_END_CANARY(best_fit);
801     +#endif
802     +
803     heap->size += true_size;
804     if (heap->peak < heap->size) {
805     heap->peak = heap->size;
806     }
807    
808     HANDLE_UNBLOCK_INTERRUPTIONS();
809     -
810     +
811     return ZEND_MM_DATA_OF(best_fit);
812     }
813    
814     @@ -1996,19 +2165,26 @@
815    
816     mm_block = ZEND_MM_HEADER_OF(p);
817     size = ZEND_MM_BLOCK_SIZE(mm_block);
818     +#if SUHOSIN_PATCH
819     + SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()");
820     +#endif
821     ZEND_MM_CHECK_PROTECTION(mm_block);
822    
823     #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
824     memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
825     #endif
826     -
827     +#if SUHOSIN_PATCH
828     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) {
829     + memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size);
830     + }
831     +#endif
832     #if ZEND_MM_CACHE
833     if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
834     size_t index = ZEND_MM_BUCKET_INDEX(size);
835     zend_mm_free_block **cache = &heap->cache[index];
836    
837     ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
838     - *cache = (zend_mm_free_block*)mm_block;
839     + *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);
840     heap->cached += size;
841     ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
842     #if ZEND_MM_CACHE_STAT
843     @@ -2044,6 +2220,9 @@
844     HANDLE_UNBLOCK_INTERRUPTIONS();
845     }
846    
847     +#if SUHOSIN_PATCH
848     +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);
849     +#endif
850     static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
851     {
852     zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);
853     @@ -2053,11 +2232,18 @@
854     void *ptr;
855    
856     if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
857     +#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
858     + return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
859     +#else
860     return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
861     +#endif
862     }
863     mm_block = ZEND_MM_HEADER_OF(p);
864     true_size = ZEND_MM_TRUE_SIZE(size);
865     orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
866     +#if SUHOSIN_PATCH
867     + SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()");
868     +#endif
869     ZEND_MM_CHECK_PROTECTION(mm_block);
870    
871     if (UNEXPECTED(true_size < size)) {
872     @@ -2089,6 +2275,11 @@
873     HANDLE_UNBLOCK_INTERRUPTIONS();
874     }
875     ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
876     +#if SUHOSIN_PATCH
877     + SUHOSIN_MM_SET_CANARIES(mm_block);
878     + ((zend_mm_block*)mm_block)->info.size = size;
879     + SUHOSIN_MM_SET_END_CANARY(mm_block);
880     +#endif
881     return p;
882     }
883    
884     @@ -2104,17 +2295,22 @@
885     heap->cache_stat[index].count--;
886     heap->cache_stat[index].hit++;
887     #endif
888     - best_fit = heap->cache[index];
889     + best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
890     heap->cache[index] = best_fit->prev_free_block;
891     ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
892     - ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
893     -
894     + ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
895     +#if SUHOSIN_PATCH
896     + SUHOSIN_MM_SET_CANARIES(best_fit);
897     + ((zend_mm_block*)best_fit)->info.size = size;
898     + SUHOSIN_MM_SET_END_CANARY(best_fit);
899     +#endif
900     +
901     ptr = ZEND_MM_DATA_OF(best_fit);
902    
903     #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
904     memcpy(ptr, p, mm_block->debug.size);
905     #else
906     - memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
907     + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
908     #endif
909    
910     heap->cached -= true_size - orig_size;
911     @@ -2123,14 +2319,13 @@
912     cache = &heap->cache[index];
913    
914     ((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
915     - *cache = (zend_mm_free_block*)mm_block;
916     + *cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);
917     ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
918     #if ZEND_MM_CACHE_STAT
919     if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
920     heap->cache_stat[index].max_count = heap->cache_stat[index].count;
921     }
922     #endif
923     -
924     return ptr;
925     }
926     }
927     @@ -2173,6 +2368,11 @@
928     heap->peak = heap->size;
929     }
930     HANDLE_UNBLOCK_INTERRUPTIONS();
931     +#if SUHOSIN_PATCH
932     + SUHOSIN_MM_SET_CANARIES(mm_block);
933     + ((zend_mm_block*)mm_block)->info.size = size;
934     + SUHOSIN_MM_SET_END_CANARY(mm_block);
935     +#endif
936     return p;
937     } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
938     ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
939     @@ -2275,38 +2475,74 @@
940     }
941    
942     HANDLE_UNBLOCK_INTERRUPTIONS();
943     +#if SUHOSIN_PATCH
944     + SUHOSIN_MM_SET_CANARIES(mm_block);
945     + ((zend_mm_block*)mm_block)->info.size = size;
946     + SUHOSIN_MM_SET_END_CANARY(mm_block);
947     +#endif
948     return ZEND_MM_DATA_OF(mm_block);
949     }
950    
951     +#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
952     + ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
953     +#else
954     ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
955     +#endif
956     #if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
957     memcpy(ptr, p, mm_block->debug.size);
958     #else
959     - memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
960     + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
961     #endif
962     +#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
963     + _zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
964     +#else
965     _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
966     +#endif
967     return ptr;
968     }
969    
970     +#ifndef SUHOSIN_MM_CLONE_FILE
971     ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
972     {
973     - return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
974     +#if SUHOSIN_PATCH
975     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
976     +#endif
977     + return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
978     +#if SUHOSIN_PATCH
979     + return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
980     +#endif
981     }
982    
983     ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
984     {
985     - _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
986     +#if SUHOSIN_PATCH
987     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
988     +#endif
989     + { _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; }
990     +#if SUHOSIN_PATCH
991     + _zend_mm_free_canary_int((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
992     +#endif
993     }
994    
995     ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
996     {
997     - return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
998     +#if SUHOSIN_PATCH
999     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
1000     +#endif
1001     + return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1002     +#if SUHOSIN_PATCH
1003     + return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1004     +#endif
1005     }
1006    
1007     ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1008     {
1009     zend_mm_block *mm_block;
1010    
1011     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) != 0) {
1012     + return _zend_mm_block_size_canary((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1013     + }
1014     +
1015     if (!ZEND_MM_VALID_PTR(p)) {
1016     return 0;
1017     }
1018     @@ -2318,6 +2554,24 @@
1019     return ZEND_MM_BLOCK_SIZE(mm_block);
1020     #endif
1021     }
1022     +#else
1023     +ZEND_API size_t _zend_mm_block_size_canary(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1024     +{
1025     + zend_mm_block *mm_block;
1026     +
1027     + if (!ZEND_MM_VALID_PTR(p)) {
1028     + return 0;
1029     + }
1030     + mm_block = ZEND_MM_HEADER_OF(p);
1031     + ZEND_MM_CHECK_PROTECTION(mm_block);
1032     +#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
1033     + return mm_block->debug.size;
1034     +#else
1035     + return ZEND_MM_BLOCK_SIZE(mm_block);
1036     +#endif
1037     +}
1038     +
1039     +#endif
1040    
1041     /**********************/
1042     /* Allocation Manager */
1043     @@ -2335,6 +2589,7 @@
1044     static zend_alloc_globals alloc_globals;
1045     #endif
1046    
1047     +#ifndef SUHOSIN_MM_CLONE_FILE
1048     ZEND_API int is_zend_mm(TSRMLS_D)
1049     {
1050     return AG(mm_heap)->use_zend_alloc;
1051     @@ -2347,7 +2602,13 @@
1052     if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
1053     return AG(mm_heap)->_malloc(size);
1054     }
1055     +#if SUHOSIN_PATCH
1056     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
1057     +#endif
1058     return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1059     +#if SUHOSIN_PATCH
1060     + 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);
1061     +#endif
1062     }
1063    
1064     ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1065     @@ -2358,7 +2619,13 @@
1066     AG(mm_heap)->_free(ptr);
1067     return;
1068     }
1069     - _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1070     +#if SUHOSIN_PATCH
1071     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
1072     +#endif
1073     + { _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; }
1074     +#if SUHOSIN_PATCH
1075     + _zend_mm_free_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1076     +#endif
1077     }
1078    
1079     ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1080     @@ -2368,7 +2635,13 @@
1081     if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
1082     return AG(mm_heap)->_realloc(ptr, size);
1083     }
1084     +#if SUHOSIN_PATCH
1085     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
1086     +#endif
1087     return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1088     +#if SUHOSIN_PATCH
1089     + 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);
1090     +#endif
1091     }
1092    
1093     ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1094     @@ -2376,8 +2649,15 @@
1095     if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
1096     return 0;
1097     }
1098     - return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1099     +#if SUHOSIN_PATCH
1100     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
1101     +#endif
1102     + return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1103     +#if SUHOSIN_PATCH
1104     + 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);
1105     +#endif
1106     }
1107     +#endif
1108    
1109     #if defined(__GNUC__) && defined(i386)
1110    
1111     @@ -2448,7 +2728,7 @@
1112     }
1113     #endif
1114    
1115     -
1116     +#ifndef SUHOSIN_MM_CLONE_FILE
1117     ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1118     {
1119     return emalloc_rel(safe_address(nmemb, size, offset));
1120     @@ -2561,6 +2841,7 @@
1121     {
1122     zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC);
1123     }
1124     +#endif
1125    
1126     static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC)
1127     {
1128     @@ -2585,6 +2866,7 @@
1129     }
1130     #endif
1131    
1132     +#ifndef SUHOSIN_MM_CLONE_FILE
1133     ZEND_API void start_memory_manager(TSRMLS_D)
1134     {
1135     #ifdef ZTS
1136     @@ -2649,6 +2931,7 @@
1137     zend_debug_alloc_output("------------------------------------------------\n");
1138     }
1139     #endif
1140     +#endif
1141    
1142     /*
1143     * Local variables:
1144     diff -Nura php-5.3.9/Zend/zend_alloc.h suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc.h
1145     --- php-5.3.9/Zend/zend_alloc.h 2012-01-01 14:15:04.000000000 +0100
1146     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc.h 2012-01-11 19:29:07.000000000 +0100
1147     @@ -203,6 +203,8 @@
1148    
1149     /* Heap functions */
1150     typedef struct _zend_mm_heap zend_mm_heap;
1151     +typedef struct _zend_mm_heap_canary zend_mm_heap_canary;
1152     +
1153    
1154     ZEND_API zend_mm_heap *zend_mm_startup(void);
1155     ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC);
1156     diff -Nura php-5.3.9/Zend/zend_alloc_canary.c suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc_canary.c
1157     --- php-5.3.9/Zend/zend_alloc_canary.c 1970-01-01 01:00:00.000000000 +0100
1158     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_alloc_canary.c 2012-01-11 19:30:47.000000000 +0100
1159     @@ -0,0 +1,2509 @@
1160     +/*
1161     + +----------------------------------------------------------------------+
1162     + | Suhosin-Patch for PHP |
1163     + +----------------------------------------------------------------------+
1164     + | Copyright (c) 2004-2011 Stefan Esser |
1165     + +----------------------------------------------------------------------+
1166     + | This source file is subject to version 2.02 of the PHP license, |
1167     + | that is bundled with this package in the file LICENSE, and is |
1168     + | available at through the world-wide-web at |
1169     + | http://www.php.net/license/2_02.txt. |
1170     + | If you did not receive a copy of the PHP license and are unable to |
1171     + | obtain it through the world-wide-web, please send a note to |
1172     + | license@php.net so we can mail you a copy immediately. |
1173     + +----------------------------------------------------------------------+
1174     + | Author: Stefan Esser <stefan.esser@sektioneins.de> |
1175     + +----------------------------------------------------------------------+
1176     + */
1177     +/* $Id: zend_alloc_canary.c, $ */
1178     +
1179     +#include "zend.h"
1180     +#include "zend_alloc.h"
1181     +#include "zend_globals.h"
1182     +#include "zend_operators.h"
1183     +
1184     +#ifdef HAVE_SIGNAL_H
1185     +# include <signal.h>
1186     +#endif
1187     +#ifdef HAVE_UNISTD_H
1188     +# include <unistd.h>
1189     +#endif
1190     +
1191     +#if SUHOSIN_PATCH
1192     +#include "suhosin_patch.h"
1193     +#endif
1194     +
1195     +#ifdef ZEND_WIN32
1196     +# include <wincrypt.h>
1197     +# include <process.h>
1198     +#endif
1199     +
1200     +#ifndef ZEND_MM_HEAP_PROTECTION
1201     +# define ZEND_MM_HEAP_PROTECTION ZEND_DEBUG
1202     +#endif
1203     +
1204     +#ifndef ZEND_MM_SAFE_UNLINKING
1205     +# define ZEND_MM_SAFE_UNLINKING 1
1206     +#endif
1207     +
1208     +#ifndef ZEND_MM_COOKIES
1209     +# define ZEND_MM_COOKIES ZEND_DEBUG
1210     +#endif
1211     +
1212     +#ifdef _WIN64
1213     +# define PTR_FMT "0x%0.16I64x"
1214     +/*
1215     +#elif sizeof(long) == 8
1216     +# define PTR_FMT "0x%0.16lx"
1217     +*/
1218     +#else
1219     +# define PTR_FMT "0x%0.8lx"
1220     +#endif
1221     +
1222     +#define SUHOSIN_MM_WITH_CANARY_PROTECTION 1
1223     +
1224     +#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
1225     +static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
1226     +#endif
1227     +
1228     +static void zend_mm_panic(const char *message)
1229     +{
1230     + fprintf(stderr, "%s\n", message);
1231     +/* See http://support.microsoft.com/kb/190351 */
1232     +#ifdef PHP_WIN32
1233     + fflush(stderr);
1234     +#endif
1235     +#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
1236     + kill(getpid(), SIGSEGV);
1237     +#endif
1238     + exit(1);
1239     +}
1240     +
1241     +/*******************/
1242     +/* Storage Manager */
1243     +/*******************/
1244     +
1245     +#ifdef ZEND_WIN32
1246     +# define HAVE_MEM_WIN32 /* use VirtualAlloc() to allocate memory */
1247     +#endif
1248     +#define HAVE_MEM_MALLOC /* use malloc() to allocate segments */
1249     +
1250     +#include <sys/types.h>
1251     +#include <sys/stat.h>
1252     +#if HAVE_LIMITS_H
1253     +#include <limits.h>
1254     +#endif
1255     +#include <fcntl.h>
1256     +#include <errno.h>
1257     +
1258     +#if defined(HAVE_MEM_MMAP_ANON) || defined(HAVE_MEM_MMAP_ZERO)
1259     +# ifdef HAVE_MREMAP
1260     +# ifndef _GNU_SOURCE
1261     +# define _GNU_SOURCE
1262     +# endif
1263     +# ifndef __USE_GNU
1264     +# define __USE_GNU
1265     +# endif
1266     +# endif
1267     +# include <sys/mman.h>
1268     +# ifndef MAP_ANON
1269     +# ifdef MAP_ANONYMOUS
1270     +# define MAP_ANON MAP_ANONYMOUS
1271     +# endif
1272     +# endif
1273     +# ifndef MREMAP_MAYMOVE
1274     +# define MREMAP_MAYMOVE 0
1275     +# endif
1276     +# ifndef MAP_FAILED
1277     +# define MAP_FAILED ((void*)-1)
1278     +# endif
1279     +#endif
1280     +
1281     +static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
1282     +
1283     +static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
1284     +{
1285     + return malloc(sizeof(zend_mm_storage));
1286     +}
1287     +
1288     +static void zend_mm_mem_dummy_dtor(zend_mm_storage *storage)
1289     +{
1290     + free(storage);
1291     +}
1292     +
1293     +static void zend_mm_mem_dummy_compact(zend_mm_storage *storage)
1294     +{
1295     +}
1296     +
1297     +#if defined(HAVE_MEM_MMAP_ANON) || defined(HAVE_MEM_MMAP_ZERO)
1298     +
1299     +static zend_mm_segment* zend_mm_mem_mmap_realloc(zend_mm_storage *storage, zend_mm_segment* segment, size_t size)
1300     +{
1301     + zend_mm_segment *ret;
1302     +#ifdef HAVE_MREMAP
1303     +#if defined(__NetBSD__)
1304     + /* NetBSD 5 supports mremap but takes an extra newp argument */
1305     + ret = (zend_mm_segment*)mremap(segment, segment->size, segment, size, MREMAP_MAYMOVE);
1306     +#else
1307     + ret = (zend_mm_segment*)mremap(segment, segment->size, size, MREMAP_MAYMOVE);
1308     +#endif
1309     + if (ret == MAP_FAILED) {
1310     +#endif
1311     + ret = storage->handlers->_alloc(storage, size);
1312     + if (ret) {
1313     + memcpy(ret, segment, size > segment->size ? segment->size : size);
1314     + storage->handlers->_free(storage, segment);
1315     + }
1316     +#ifdef HAVE_MREMAP
1317     + }
1318     +#endif
1319     + return ret;
1320     +}
1321     +
1322     +static void zend_mm_mem_mmap_free(zend_mm_storage *storage, zend_mm_segment* segment)
1323     +{
1324     + munmap((void*)segment, segment->size);
1325     +}
1326     +
1327     +#endif
1328     +
1329     +#ifdef HAVE_MEM_MMAP_ANON
1330     +
1331     +static zend_mm_segment* zend_mm_mem_mmap_anon_alloc(zend_mm_storage *storage, size_t size)
1332     +{
1333     + zend_mm_segment *ret = (zend_mm_segment*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
1334     + if (ret == MAP_FAILED) {
1335     + ret = NULL;
1336     + }
1337     + return ret;
1338     +}
1339     +
1340     +# define ZEND_MM_MEM_MMAP_ANON_DSC {"mmap_anon", zend_mm_mem_dummy_init, zend_mm_mem_dummy_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_mmap_anon_alloc, zend_mm_mem_mmap_realloc, zend_mm_mem_mmap_free}
1341     +
1342     +#endif
1343     +
1344     +#ifdef HAVE_MEM_MMAP_ZERO
1345     +
1346     +static int zend_mm_dev_zero_fd = -1;
1347     +
1348     +static zend_mm_storage* zend_mm_mem_mmap_zero_init(void *params)
1349     +{
1350     + if (zend_mm_dev_zero_fd != -1) {
1351     + zend_mm_dev_zero_fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
1352     + }
1353     + if (zend_mm_dev_zero_fd >= 0) {
1354     + return malloc(sizeof(zend_mm_storage));
1355     + } else {
1356     + return NULL;
1357     + }
1358     +}
1359     +
1360     +static void zend_mm_mem_mmap_zero_dtor(zend_mm_storage *storage)
1361     +{
1362     + close(zend_mm_dev_zero_fd);
1363     + free(storage);
1364     +}
1365     +
1366     +static zend_mm_segment* zend_mm_mem_mmap_zero_alloc(zend_mm_storage *storage, size_t size)
1367     +{
1368     + zend_mm_segment *ret = (zend_mm_segment*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zend_mm_dev_zero_fd, 0);
1369     + if (ret == MAP_FAILED) {
1370     + ret = NULL;
1371     + }
1372     + return ret;
1373     +}
1374     +
1375     +# define ZEND_MM_MEM_MMAP_ZERO_DSC {"mmap_zero", zend_mm_mem_mmap_zero_init, zend_mm_mem_mmap_zero_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_mmap_zero_alloc, zend_mm_mem_mmap_realloc, zend_mm_mem_mmap_free}
1376     +
1377     +#endif
1378     +
1379     +#ifdef HAVE_MEM_WIN32
1380     +
1381     +static zend_mm_storage* zend_mm_mem_win32_init(void *params)
1382     +{
1383     + HANDLE heap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
1384     + zend_mm_storage* storage;
1385     +
1386     + if (heap == NULL) {
1387     + return NULL;
1388     + }
1389     + storage = (zend_mm_storage*)malloc(sizeof(zend_mm_storage));
1390     + if (storage == NULL) {
1391     + HeapDestroy(heap);
1392     + return NULL;
1393     + }
1394     + storage->data = (void*) heap;
1395     + return storage;
1396     +}
1397     +
1398     +static void zend_mm_mem_win32_dtor(zend_mm_storage *storage)
1399     +{
1400     + HeapDestroy((HANDLE)storage->data);
1401     + free(storage);
1402     +}
1403     +
1404     +static void zend_mm_mem_win32_compact(zend_mm_storage *storage)
1405     +{
1406     + HeapDestroy((HANDLE)storage->data);
1407     + storage->data = (void*)HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
1408     +}
1409     +
1410     +static zend_mm_segment* zend_mm_mem_win32_alloc(zend_mm_storage *storage, size_t size)
1411     +{
1412     + return (zend_mm_segment*) HeapAlloc((HANDLE)storage->data, HEAP_NO_SERIALIZE, size);
1413     +}
1414     +
1415     +static void zend_mm_mem_win32_free(zend_mm_storage *storage, zend_mm_segment* segment)
1416     +{
1417     + HeapFree((HANDLE)storage->data, HEAP_NO_SERIALIZE, segment);
1418     +}
1419     +
1420     +static zend_mm_segment* zend_mm_mem_win32_realloc(zend_mm_storage *storage, zend_mm_segment* segment, size_t size)
1421     +{
1422     + return (zend_mm_segment*) HeapReAlloc((HANDLE)storage->data, HEAP_NO_SERIALIZE, segment, size);
1423     +}
1424     +
1425     +# define ZEND_MM_MEM_WIN32_DSC {"win32", zend_mm_mem_win32_init, zend_mm_mem_win32_dtor, zend_mm_mem_win32_compact, zend_mm_mem_win32_alloc, zend_mm_mem_win32_realloc, zend_mm_mem_win32_free}
1426     +
1427     +#endif
1428     +
1429     +#ifdef HAVE_MEM_MALLOC
1430     +
1431     +static zend_mm_segment* zend_mm_mem_malloc_alloc(zend_mm_storage *storage, size_t size)
1432     +{
1433     + return (zend_mm_segment*)malloc(size);
1434     +}
1435     +
1436     +static zend_mm_segment* zend_mm_mem_malloc_realloc(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size)
1437     +{
1438     + return (zend_mm_segment*)realloc(ptr, size);
1439     +}
1440     +
1441     +static void zend_mm_mem_malloc_free(zend_mm_storage *storage, zend_mm_segment *ptr)
1442     +{
1443     + free(ptr);
1444     +}
1445     +
1446     +# define ZEND_MM_MEM_MALLOC_DSC {"malloc", zend_mm_mem_dummy_init, zend_mm_mem_dummy_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_malloc_alloc, zend_mm_mem_malloc_realloc, zend_mm_mem_malloc_free}
1447     +
1448     +#endif
1449     +
1450     +static const zend_mm_mem_handlers mem_handlers[] = {
1451     +#ifdef HAVE_MEM_WIN32
1452     + ZEND_MM_MEM_WIN32_DSC,
1453     +#endif
1454     +#ifdef HAVE_MEM_MALLOC
1455     + ZEND_MM_MEM_MALLOC_DSC,
1456     +#endif
1457     +#ifdef HAVE_MEM_MMAP_ANON
1458     + ZEND_MM_MEM_MMAP_ANON_DSC,
1459     +#endif
1460     +#ifdef HAVE_MEM_MMAP_ZERO
1461     + ZEND_MM_MEM_MMAP_ZERO_DSC,
1462     +#endif
1463     + {NULL, NULL, NULL, NULL, NULL, NULL}
1464     +};
1465     +
1466     +# define ZEND_MM_STORAGE_DTOR() heap->storage->handlers->dtor(heap->storage)
1467     +# define ZEND_MM_STORAGE_ALLOC(size) heap->storage->handlers->_alloc(heap->storage, size)
1468     +# define ZEND_MM_STORAGE_REALLOC(ptr, size) heap->storage->handlers->_realloc(heap->storage, ptr, size)
1469     +# define ZEND_MM_STORAGE_FREE(ptr) heap->storage->handlers->_free(heap->storage, ptr)
1470     +
1471     +/****************/
1472     +/* Heap Manager */
1473     +/****************/
1474     +
1475     +#define MEM_BLOCK_VALID 0x7312F8DC
1476     +#define MEM_BLOCK_FREED 0x99954317
1477     +#define MEM_BLOCK_CACHED 0xFB8277DC
1478     +#define MEM_BLOCK_GUARD 0x2A8FCC84
1479     +#define MEM_BLOCK_LEAK 0x6C5E8F2D
1480     +
1481     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1482     +# define CANARY_SIZE sizeof(size_t)
1483     +#else
1484     +# define CANARY_SIZE 0
1485     +#endif
1486     +
1487     +/* mm block type */
1488     +typedef struct _zend_mm_block_info_canary {
1489     +#if ZEND_MM_COOKIES
1490     + size_t _cookie;
1491     +#endif
1492     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1493     + size_t canary_1;
1494     +#endif
1495     + size_t _size;
1496     + size_t _prev;
1497     +#if SUHOSIN_PATCH
1498     + size_t size;
1499     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1500     + size_t canary_2;
1501     +#endif
1502     +#endif
1503     +} zend_mm_block_info_canary;
1504     +
1505     +#if ZEND_DEBUG
1506     +
1507     +typedef struct _zend_mm_debug_info_canary {
1508     + char *filename;
1509     + uint lineno;
1510     + char *orig_filename;
1511     + uint orig_lineno;
1512     + size_t size;
1513     +#if ZEND_MM_HEAP_PROTECTION
1514     + unsigned int start_magic;
1515     +#endif
1516     +} zend_mm_debug_info_canary;
1517     +
1518     +#elif ZEND_MM_HEAP_PROTECTION
1519     +
1520     +typedef struct _zend_mm_debug_info_canary {
1521     + size_t size;
1522     + unsigned int start_magic;
1523     +} zend_mm_debug_info_canary;
1524     +
1525     +#endif
1526     +
1527     +typedef struct _zend_mm_block_canary {
1528     + zend_mm_block_info_canary info;
1529     +#if ZEND_DEBUG
1530     + unsigned int magic;
1531     +# ifdef ZTS
1532     + THREAD_T thread_id;
1533     +# endif
1534     + zend_mm_debug_info_canary debug;
1535     +#elif ZEND_MM_HEAP_PROTECTION
1536     + zend_mm_debug_info_canary debug;
1537     +#endif
1538     +} zend_mm_block_canary;
1539     +
1540     +typedef struct _zend_mm_small_free_block_canary {
1541     + zend_mm_block_info_canary info;
1542     +#if ZEND_DEBUG
1543     + unsigned int magic;
1544     +# ifdef ZTS
1545     + THREAD_T thread_id;
1546     +# endif
1547     +#endif
1548     + struct _zend_mm_free_block_canary *prev_free_block;
1549     + struct _zend_mm_free_block_canary *next_free_block;
1550     +} zend_mm_small_free_block_canary;
1551     +
1552     +typedef struct _zend_mm_free_block_canary {
1553     + zend_mm_block_info_canary info;
1554     +#if ZEND_DEBUG
1555     + unsigned int magic;
1556     +# ifdef ZTS
1557     + THREAD_T thread_id;
1558     +# endif
1559     +#endif
1560     + struct _zend_mm_free_block_canary *prev_free_block;
1561     + struct _zend_mm_free_block_canary *next_free_block;
1562     +
1563     + struct _zend_mm_free_block_canary **parent;
1564     + struct _zend_mm_free_block_canary *child[2];
1565     +} zend_mm_free_block_canary;
1566     +
1567     +#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)
1568     +
1569     +#define ZEND_MM_CACHE 1
1570     +#define ZEND_MM_CACHE_SIZE (ZEND_MM_NUM_BUCKETS * 4 * 1024)
1571     +
1572     +#ifndef ZEND_MM_CACHE_STAT
1573     +# define ZEND_MM_CACHE_STAT 0
1574     +#endif
1575     +
1576     +typedef struct _zend_mm_heap_canary {
1577     + int use_zend_alloc;
1578     + void *(*_malloc)(size_t);
1579     + void (*_free)(void*);
1580     + void *(*_realloc)(void*, size_t);
1581     + size_t free_bitmap;
1582     + size_t large_free_bitmap;
1583     + size_t block_size;
1584     + size_t compact_size;
1585     + zend_mm_segment *segments_list;
1586     + zend_mm_storage *storage;
1587     + size_t real_size;
1588     + size_t real_peak;
1589     + size_t limit;
1590     + size_t size;
1591     + size_t peak;
1592     + size_t reserve_size;
1593     + void *reserve;
1594     + int overflow;
1595     + int internal;
1596     +#if ZEND_MM_CACHE
1597     + unsigned int cached;
1598     + zend_mm_free_block_canary *cache[ZEND_MM_NUM_BUCKETS];
1599     +#endif
1600     + zend_mm_free_block_canary *free_buckets[ZEND_MM_NUM_BUCKETS*2];
1601     + zend_mm_free_block_canary *large_free_buckets[ZEND_MM_NUM_BUCKETS];
1602     + zend_mm_free_block_canary *rest_buckets[2];
1603     +#if ZEND_MM_CACHE_STAT
1604     + struct {
1605     + int count;
1606     + int max_count;
1607     + int hit;
1608     + int miss;
1609     + } cache_stat[ZEND_MM_NUM_BUCKETS+1];
1610     +#endif
1611     +#if SUHOSIN_PATCH
1612     + size_t canary_1,canary_2,canary_3;
1613     +#endif
1614     +};
1615     +
1616     +#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
1617     + (zend_mm_free_block_canary*) ((char*)&heap->free_buckets[index * 2] + \
1618     + sizeof(zend_mm_free_block_canary*) * 2 - \
1619     + sizeof(zend_mm_small_free_block_canary))
1620     +
1621     +#define ZEND_MM_REST_BUCKET(heap) \
1622     + (zend_mm_free_block_canary*)((char*)&heap->rest_buckets[0] + \
1623     + sizeof(zend_mm_free_block_canary*) * 2 - \
1624     + sizeof(zend_mm_small_free_block_canary))
1625     +
1626     +#if ZEND_MM_COOKIES
1627     +
1628     +static unsigned int _zend_mm_cookie = 0;
1629     +
1630     +# define ZEND_MM_COOKIE(block) \
1631     + (((size_t)(block)) ^ _zend_mm_cookie)
1632     +# define ZEND_MM_SET_COOKIE(block) \
1633     + (block)->info._cookie = ZEND_MM_COOKIE(block)
1634     +# define ZEND_MM_CHECK_COOKIE(block) \
1635     + if (UNEXPECTED((block)->info._cookie != ZEND_MM_COOKIE(block))) { \
1636     + zend_mm_panic("zend_mm_heap corrupted"); \
1637     + }
1638     +#else
1639     +# define ZEND_MM_SET_COOKIE(block)
1640     +# define ZEND_MM_CHECK_COOKIE(block)
1641     +#endif
1642     +
1643     +/* Default memory segment size */
1644     +#define ZEND_MM_SEG_SIZE (256 * 1024)
1645     +
1646     +/* Reserved space for error reporting in case of memory overflow */
1647     +#define ZEND_MM_RESERVE_SIZE (8*1024)
1648     +
1649     +#ifdef _WIN64
1650     +# define ZEND_MM_LONG_CONST(x) (x##i64)
1651     +#else
1652     +# define ZEND_MM_LONG_CONST(x) (x##L)
1653     +#endif
1654     +
1655     +#define ZEND_MM_TYPE_MASK ZEND_MM_LONG_CONST(0x3)
1656     +
1657     +#define ZEND_MM_FREE_BLOCK ZEND_MM_LONG_CONST(0x0)
1658     +#define ZEND_MM_USED_BLOCK ZEND_MM_LONG_CONST(0x1)
1659     +#define ZEND_MM_GUARD_BLOCK ZEND_MM_LONG_CONST(0x3)
1660     +
1661     +#define ZEND_MM_BLOCK(b, type, size) do { \
1662     + size_t _size = (size); \
1663     + (b)->info._size = (type) | _size; \
1664     + ZEND_MM_BLOCK_AT(b, _size)->info._prev = (type) | _size; \
1665     + ZEND_MM_SET_COOKIE(b); \
1666     + } while (0);
1667     +#define ZEND_MM_LAST_BLOCK(b) do { \
1668     + (b)->info._size = ZEND_MM_GUARD_BLOCK | ZEND_MM_ALIGNED_HEADER_SIZE; \
1669     + ZEND_MM_SET_MAGIC(b, MEM_BLOCK_GUARD); \
1670     + } while (0);
1671     +#define ZEND_MM_BLOCK_SIZE(b) ((b)->info._size & ~ZEND_MM_TYPE_MASK)
1672     +#define ZEND_MM_IS_FREE_BLOCK(b) (!((b)->info._size & ZEND_MM_USED_BLOCK))
1673     +#define ZEND_MM_IS_USED_BLOCK(b) ((b)->info._size & ZEND_MM_USED_BLOCK)
1674     +#define ZEND_MM_IS_GUARD_BLOCK(b) (((b)->info._size & ZEND_MM_TYPE_MASK) == ZEND_MM_GUARD_BLOCK)
1675     +
1676     +#define ZEND_MM_NEXT_BLOCK(b) ZEND_MM_BLOCK_AT(b, ZEND_MM_BLOCK_SIZE(b))
1677     +#define ZEND_MM_PREV_BLOCK(b) ZEND_MM_BLOCK_AT(b, -(ssize_t)((b)->info._prev & ~ZEND_MM_TYPE_MASK))
1678     +
1679     +#define ZEND_MM_PREV_BLOCK_IS_FREE(b) (!((b)->info._prev & ZEND_MM_USED_BLOCK))
1680     +
1681     +#define ZEND_MM_MARK_FIRST_BLOCK(b) ((b)->info._prev = ZEND_MM_GUARD_BLOCK)
1682     +#define ZEND_MM_IS_FIRST_BLOCK(b) ((b)->info._prev == ZEND_MM_GUARD_BLOCK)
1683     +
1684     +/* optimized access */
1685     +#define ZEND_MM_FREE_BLOCK_SIZE(b) (b)->info._size
1686     +
1687     +#ifndef ZEND_MM_ALIGNMENT
1688     +# define ZEND_MM_ALIGNMENT 8
1689     +# define ZEND_MM_ALIGNMENT_LOG2 3
1690     +#elif ZEND_MM_ALIGNMENT < 4
1691     +# undef ZEND_MM_ALIGNMENT
1692     +# undef ZEND_MM_ALIGNMENT_LOG2
1693     +# define ZEND_MM_ALIGNMENT 4
1694     +# define ZEND_MM_ALIGNMENT_LOG2 2
1695     +#endif
1696     +
1697     +#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
1698     +
1699     +/* Aligned header size */
1700     +#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
1701     +#define ZEND_MM_ALIGNED_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block_canary))
1702     +#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block_canary))
1703     +#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)
1704     +#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)
1705     +#define ZEND_MM_ALIGNED_SEGMENT_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
1706     +
1707     +#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)
1708     +
1709     +#define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
1710     +
1711     +#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)))
1712     +
1713     +#define ZEND_MM_BUCKET_INDEX(true_size) ((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
1714     +
1715     +#define ZEND_MM_SMALL_SIZE(true_size) (true_size < ZEND_MM_MAX_SMALL_SIZE)
1716     +
1717     +/* Memory calculations */
1718     +#define ZEND_MM_BLOCK_AT(blk, offset) ((zend_mm_block_canary *) (((char *) (blk))+(offset)))
1719     +#define ZEND_MM_DATA_OF(p) ((void *) (((char *) (p))+ZEND_MM_ALIGNED_HEADER_SIZE))
1720     +#define ZEND_MM_HEADER_OF(blk) ZEND_MM_BLOCK_AT(blk, -(int)ZEND_MM_ALIGNED_HEADER_SIZE)
1721     +
1722     +/* Debug output */
1723     +#if ZEND_DEBUG
1724     +
1725     +# ifdef ZTS
1726     +# define ZEND_MM_SET_THREAD_ID(block) \
1727     + ((zend_mm_block_canary*)(block))->thread_id = tsrm_thread_id()
1728     +# define ZEND_MM_BAD_THREAD_ID(block) ((block)->thread_id != tsrm_thread_id())
1729     +# else
1730     +# define ZEND_MM_SET_THREAD_ID(block)
1731     +# define ZEND_MM_BAD_THREAD_ID(block) 0
1732     +# endif
1733     +
1734     +# define ZEND_MM_VALID_PTR(block) \
1735     + zend_mm_check_ptr(heap, block, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)
1736     +
1737     +# define ZEND_MM_SET_MAGIC(block, val) do { \
1738     + (block)->magic = (val); \
1739     + } while (0)
1740     +
1741     +# define ZEND_MM_CHECK_MAGIC(block, val) do { \
1742     + if ((block)->magic != (val)) { \
1743     + zend_mm_panic("zend_mm_heap corrupted"); \
1744     + } \
1745     + } while (0)
1746     +
1747     +# define ZEND_MM_SET_DEBUG_INFO(block, __size, set_valid, set_thread) do { \
1748     + ((zend_mm_block_canary*)(block))->debug.filename = __zend_filename; \
1749     + ((zend_mm_block_canary*)(block))->debug.lineno = __zend_lineno; \
1750     + ((zend_mm_block_canary*)(block))->debug.orig_filename = __zend_orig_filename; \
1751     + ((zend_mm_block_canary*)(block))->debug.orig_lineno = __zend_orig_lineno; \
1752     + ZEND_MM_SET_BLOCK_SIZE(block, __size); \
1753     + if (set_valid) { \
1754     + ZEND_MM_SET_MAGIC(block, MEM_BLOCK_VALID); \
1755     + } \
1756     + if (set_thread) { \
1757     + ZEND_MM_SET_THREAD_ID(block); \
1758     + } \
1759     + } while (0)
1760     +
1761     +#else
1762     +
1763     +# define ZEND_MM_VALID_PTR(ptr) EXPECTED(ptr != NULL)
1764     +
1765     +# define ZEND_MM_SET_MAGIC(block, val)
1766     +
1767     +# define ZEND_MM_CHECK_MAGIC(block, val)
1768     +
1769     +# define ZEND_MM_SET_DEBUG_INFO(block, __size, set_valid, set_thread) ZEND_MM_SET_BLOCK_SIZE(block, __size)
1770     +
1771     +#endif
1772     +
1773     +#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1774     +
1775     +# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \
1776     + char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \
1777     + if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \
1778     + canary_mismatch: \
1779     + zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
1780     + 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; }\
1781     + } \
1782     + memcpy(&check, p, CANARY_SIZE); \
1783     + if (check != heap->canary_3) { \
1784     + zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
1785     + if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \
1786     + } \
1787     + } while (0)
1788     +
1789     +# define SUHOSIN_MM_SET_CANARIES(block) do { \
1790     + (block)->info.canary_1 = heap->canary_1; \
1791     + (block)->info.canary_2 = heap->canary_2; \
1792     + } while (0)
1793     +
1794     +# define SUHOSIN_MM_END_CANARY_PTR(block) \
1795     + (char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block_canary*)(block))->info.size + END_MAGIC_SIZE)
1796     +
1797     +# define SUHOSIN_MM_SET_END_CANARY(block) do { \
1798     + char *p = SUHOSIN_MM_END_CANARY_PTR(block); \
1799     + memcpy(p, &heap->canary_3, CANARY_SIZE); \
1800     + } while (0)
1801     +
1802     +#else
1803     +
1804     +# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION)
1805     +# define SUHOSIN_MM_SET_CANARIES(block)
1806     +# define SUHOSIN_MM_END_CANARY_PTR(block)
1807     +# define SUHOSIN_MM_SET_END_CANARY(block)
1808     +
1809     +#endif
1810     +
1811     +
1812     +#if ZEND_MM_HEAP_PROTECTION
1813     +
1814     +# define ZEND_MM_CHECK_PROTECTION(block) \
1815     + do { \
1816     + if ((block)->debug.start_magic != _mem_block_start_magic || \
1817     + memcmp(ZEND_MM_END_MAGIC_PTR(block), &_mem_block_end_magic, END_MAGIC_SIZE) != 0) { \
1818     + zend_mm_panic("zend_mm_heap corrupted"); \
1819     + } \
1820     + } while (0)
1821     +
1822     +# define ZEND_MM_END_MAGIC_PTR(block) \
1823     + (((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block_canary*)(block))->debug.size)
1824     +
1825     +# define END_MAGIC_SIZE sizeof(unsigned int)
1826     +
1827     +# define ZEND_MM_SET_BLOCK_SIZE(block, __size) do { \
1828     + char *p; \
1829     + ((zend_mm_block_canary*)(block))->debug.size = (__size); \
1830     + p = ZEND_MM_END_MAGIC_PTR(block); \
1831     + ((zend_mm_block_canary*)(block))->debug.start_magic = _mem_block_start_magic; \
1832     + memcpy(p, &_mem_block_end_magic, END_MAGIC_SIZE); \
1833     + } while (0)
1834     +
1835     +static unsigned int _mem_block_start_magic = 0;
1836     +static unsigned int _mem_block_end_magic = 0;
1837     +
1838     +#else
1839     +
1840     +# if ZEND_DEBUG
1841     +# define ZEND_MM_SET_BLOCK_SIZE(block, _size) \
1842     + ((zend_mm_block_canary*)(block))->debug.size = (_size)
1843     +# else
1844     +# define ZEND_MM_SET_BLOCK_SIZE(block, _size)
1845     +# endif
1846     +
1847     +# define ZEND_MM_CHECK_PROTECTION(block)
1848     +
1849     +# define END_MAGIC_SIZE 0
1850     +
1851     +#endif
1852     +
1853     +#if ZEND_MM_SAFE_UNLINKING
1854     +# define ZEND_MM_CHECK_BLOCK_LINKAGE(block) \
1855     + if (UNEXPECTED((block)->info._size != ZEND_MM_BLOCK_AT(block, ZEND_MM_FREE_BLOCK_SIZE(block))->info._prev) || \
1856     + UNEXPECTED(!UNEXPECTED(ZEND_MM_IS_FIRST_BLOCK(block)) && \
1857     + UNEXPECTED(ZEND_MM_PREV_BLOCK(block)->info._size != (block)->info._prev))) { \
1858     + zend_mm_panic("zend_mm_heap corrupted"); \
1859     + }
1860     +#define ZEND_MM_CHECK_TREE(block) \
1861     + if (UNEXPECTED(*((block)->parent) != (block))) { \
1862     + zend_mm_panic("zend_mm_heap corrupted"); \
1863     + }
1864     +#else
1865     +# define ZEND_MM_CHECK_BLOCK_LINKAGE(block)
1866     +# define ZEND_MM_CHECK_TREE(block)
1867     +#endif
1868     +
1869     +#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
1870     +
1871     +void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
1872     +void _zend_mm_free_canary_int(zend_mm_heap_canary *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
1873     +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);
1874     +
1875     +
1876     +static inline unsigned int zend_mm_high_bit(size_t _size)
1877     +{
1878     +#if defined(__GNUC__) && defined(i386)
1879     + unsigned int n;
1880     +
1881     + __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size));
1882     + return n;
1883     +#elif defined(__GNUC__) && defined(__x86_64__)
1884     + unsigned long n;
1885     +
1886     + __asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm" (_size));
1887     + return (unsigned int)n;
1888     +#elif defined(_MSC_VER) && defined(_M_IX86)
1889     + __asm {
1890     + bsr eax, _size
1891     + }
1892     +#else
1893     + unsigned int n = 0;
1894     + while (_size != 0) {
1895     + _size = _size >> 1;
1896     + n++;
1897     + }
1898     + return n-1;
1899     +#endif
1900     +}
1901     +
1902     +static inline unsigned int zend_mm_low_bit(size_t _size)
1903     +{
1904     +#if defined(__GNUC__) && defined(i386)
1905     + unsigned int n;
1906     +
1907     + __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size));
1908     + return n;
1909     +#elif defined(__GNUC__) && defined(__x86_64__)
1910     + unsigned long n;
1911     +
1912     + __asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm" (_size));
1913     + return (unsigned int)n;
1914     +#elif defined(_MSC_VER) && defined(_M_IX86)
1915     + __asm {
1916     + bsf eax, _size
1917     + }
1918     +#else
1919     + static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
1920     + unsigned int n;
1921     + unsigned int index = 0;
1922     +
1923     + n = offset[_size & 15];
1924     + while (n == 4) {
1925     + _size >>= 4;
1926     + index += n;
1927     + n = offset[_size & 15];
1928     + }
1929     +
1930     + return index + n;
1931     +#endif
1932     +}
1933     +
1934     +static void zend_mm_add_to_rest_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
1935     +{
1936     + zend_mm_free_block_canary *prev, *next;
1937     +
1938     + ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
1939     +
1940     + if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {
1941     + mm_block->parent = NULL;
1942     + }
1943     +
1944     + prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
1945     + next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
1946     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
1947     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
1948     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
1949     +}
1950     +
1951     +static void zend_mm_add_to_free_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
1952     +{
1953     + size_t size;
1954     + size_t index;
1955     +
1956     + ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
1957     +
1958     + size = ZEND_MM_FREE_BLOCK_SIZE(mm_block);
1959     + if (EXPECTED(!ZEND_MM_SMALL_SIZE(size))) {
1960     + zend_mm_free_block_canary **p;
1961     +
1962     + index = ZEND_MM_LARGE_BUCKET_INDEX(size);
1963     + p = &heap->large_free_buckets[index];
1964     + mm_block->child[0] = mm_block->child[1] = NULL;
1965     + if (!*p) {
1966     + *p = mm_block;
1967     + mm_block->parent = p;
1968     + mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
1969     + heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
1970     + } else {
1971     + size_t m;
1972     +
1973     + for (m = size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
1974     + zend_mm_free_block_canary *prev = *p;
1975     +
1976     + if (ZEND_MM_FREE_BLOCK_SIZE(prev) != size) {
1977     + p = &prev->child[(m >> (ZEND_MM_NUM_BUCKETS-1)) & 1];
1978     + if (!*p) {
1979     + *p = mm_block;
1980     + mm_block->parent = p;
1981     + mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
1982     + break;
1983     + }
1984     + } else {
1985     + zend_mm_free_block_canary *next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
1986     +
1987     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
1988     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
1989     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
1990     + mm_block->parent = NULL;
1991     + break;
1992     + }
1993     + }
1994     + }
1995     + } else {
1996     + zend_mm_free_block_canary *prev, *next;
1997     +
1998     + index = ZEND_MM_BUCKET_INDEX(size);
1999     +
2000     + prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
2001     + if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) {
2002     + heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
2003     + }
2004     + next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
2005     +
2006     + mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
2007     + mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
2008     + prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
2009     + }
2010     +}
2011     +
2012     +static void zend_mm_remove_from_free_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
2013     +{
2014     + zend_mm_free_block_canary *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
2015     + zend_mm_free_block_canary *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block);
2016     +
2017     + ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
2018     +
2019     + if (EXPECTED(prev == mm_block)) {
2020     + zend_mm_free_block_canary **rp, **cp;
2021     +
2022     +#if SUHOSIN_PATCH
2023     + if (next != mm_block) {
2024     + zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block);
2025     + _exit(1);
2026     + }
2027     +#endif
2028     +#if ZEND_MM_SAFE_UNLINKING
2029     + if (UNEXPECTED(next != mm_block)) {
2030     + zend_mm_panic("zend_mm_heap corrupted");
2031     + }
2032     +#endif
2033     +
2034     + rp = &mm_block->child[mm_block->child[1] != NULL];
2035     + prev = *rp;
2036     + if (EXPECTED(prev == NULL)) {
2037     + size_t index = ZEND_MM_LARGE_BUCKET_INDEX(ZEND_MM_FREE_BLOCK_SIZE(mm_block));
2038     +
2039     + ZEND_MM_CHECK_TREE(mm_block);
2040     + *mm_block->parent = NULL;
2041     + if (mm_block->parent == &heap->large_free_buckets[index]) {
2042     + heap->large_free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
2043     + }
2044     + } else {
2045     + while (*(cp = &(prev->child[prev->child[1] != NULL])) != NULL) {
2046     + prev = *cp;
2047     + rp = cp;
2048     + }
2049     + *rp = NULL;
2050     +
2051     +subst_block:
2052     + ZEND_MM_CHECK_TREE(mm_block);
2053     + *mm_block->parent = prev;
2054     + prev->parent = mm_block->parent;
2055     + if ((prev->child[0] = mm_block->child[0])) {
2056     + ZEND_MM_CHECK_TREE(prev->child[0]);
2057     + prev->child[0]->parent = &prev->child[0];
2058     + }
2059     + if ((prev->child[1] = mm_block->child[1])) {
2060     + ZEND_MM_CHECK_TREE(prev->child[1]);
2061     + prev->child[1]->parent = &prev->child[1];
2062     + }
2063     + }
2064     + } else {
2065     +
2066     +#if SUHOSIN_PATCH
2067     + if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) {
2068     + zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block);
2069     + _exit(1);
2070     + }
2071     +#endif
2072     +
2073     +#if ZEND_MM_SAFE_UNLINKING
2074     + if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) {
2075     + zend_mm_panic("zend_mm_heap corrupted");
2076     + }
2077     +#endif
2078     +
2079     + prev->next_free_block = SUHOSIN_MANGLE_PTR(next);
2080     + next->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
2081     +
2082     + if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
2083     + if (EXPECTED(prev == next)) {
2084     + size_t index = ZEND_MM_BUCKET_INDEX(ZEND_MM_FREE_BLOCK_SIZE(mm_block));
2085     +
2086     + if (EXPECTED(heap->free_buckets[index*2] == heap->free_buckets[index*2+1])) {
2087     + heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
2088     + }
2089     + }
2090     + } else if (UNEXPECTED(mm_block->parent != NULL)) {
2091     + goto subst_block;
2092     + }
2093     + }
2094     +}
2095     +
2096     +static void zend_mm_init(zend_mm_heap_canary *heap)
2097     +{
2098     + zend_mm_free_block_canary* p;
2099     + int i;
2100     +
2101     + heap->free_bitmap = 0;
2102     + heap->large_free_bitmap = 0;
2103     +#if ZEND_MM_CACHE
2104     + heap->cached = 0;
2105     + memset(heap->cache, 0, sizeof(heap->cache));
2106     +#endif
2107     +#if ZEND_MM_CACHE_STAT
2108     + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
2109     + heap->cache_stat[i].count = 0;
2110     + }
2111     +#endif
2112     + p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
2113     + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
2114     + p->next_free_block = SUHOSIN_MANGLE_PTR(p);
2115     + p->prev_free_block = SUHOSIN_MANGLE_PTR(p);
2116     + p = (zend_mm_free_block_canary*)((char*)p + sizeof(zend_mm_free_block_canary*) * 2);
2117     + heap->large_free_buckets[i] = NULL;
2118     + }
2119     + heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap));
2120     +#if SUHOSIN_PATCH
2121     + if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
2122     + zend_canary(&heap->canary_1, sizeof(heap->canary_1));
2123     + zend_canary(&heap->canary_2, sizeof(heap->canary_2));
2124     + zend_canary(&heap->canary_3, sizeof(heap->canary_3));
2125     + }
2126     +#endif
2127     +}
2128     +
2129     +static void zend_mm_del_segment(zend_mm_heap_canary *heap, zend_mm_segment *segment)
2130     +{
2131     + zend_mm_segment **p = &heap->segments_list;
2132     +
2133     + while (*p != segment) {
2134     + p = &(*p)->next_segment;
2135     + }
2136     + *p = segment->next_segment;
2137     + heap->real_size -= segment->size;
2138     + ZEND_MM_STORAGE_FREE(segment);
2139     +}
2140     +
2141     +#if ZEND_MM_CACHE
2142     +static void zend_mm_free_cache(zend_mm_heap_canary *heap)
2143     +{
2144     + int i;
2145     +
2146     + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
2147     + /* SUHOSIN_MANGLE_PTR should NOT affect NULL pointers */
2148     + if (heap->cache[i]) {
2149     + zend_mm_free_block_canary *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]);
2150     +
2151     + while (mm_block) {
2152     + size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
2153     + zend_mm_free_block_canary *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
2154     + zend_mm_block_canary *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
2155     +
2156     + heap->cached -= size;
2157     +
2158     + if (ZEND_MM_PREV_BLOCK_IS_FREE(mm_block)) {
2159     + mm_block = (zend_mm_free_block_canary*)ZEND_MM_PREV_BLOCK(mm_block);
2160     + size += ZEND_MM_FREE_BLOCK_SIZE(mm_block);
2161     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) mm_block);
2162     + }
2163     + if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
2164     + size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
2165     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
2166     + }
2167     + ZEND_MM_BLOCK(mm_block, ZEND_MM_FREE_BLOCK, size);
2168     +
2169     + if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2170     + ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_NEXT_BLOCK(mm_block))) {
2171     + zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE));
2172     + } else {
2173     + zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) mm_block);
2174     + }
2175     +
2176     + mm_block = q;
2177     + }
2178     + heap->cache[i] = NULL;
2179     +#if ZEND_MM_CACHE_STAT
2180     + heap->cache_stat[i].count = 0;
2181     +#endif
2182     + }
2183     + }
2184     +}
2185     +#endif
2186     +
2187     +#if ZEND_MM_HEAP_PROTECTION || ZEND_MM_COOKIES
2188     +static void zend_mm_random(unsigned char *buf, size_t size) /* {{{ */
2189     +{
2190     + size_t i = 0;
2191     + unsigned char t;
2192     +
2193     +#ifdef ZEND_WIN32
2194     + HCRYPTPROV hCryptProv;
2195     + int has_context = 0;
2196     +
2197     + if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
2198     + /* Could mean that the key container does not exist, let try
2199     + again by asking for a new one */
2200     + if (GetLastError() == NTE_BAD_KEYSET) {
2201     + if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
2202     + has_context = 1;
2203     + }
2204     + }
2205     + } else {
2206     + has_context = 1;
2207     + }
2208     + if (has_context) {
2209     + do {
2210     + BOOL ret = CryptGenRandom(hCryptProv, size, buf);
2211     + CryptReleaseContext(hCryptProv, 0);
2212     + if (ret) {
2213     + while (i < size && buf[i] != 0) {
2214     + i++;
2215     + }
2216     + if (i == size) {
2217     + return;
2218     + }
2219     + }
2220     + } while (0);
2221     + }
2222     +#elif defined(HAVE_DEV_URANDOM)
2223     + int fd = open("/dev/urandom", 0);
2224     +
2225     + if (fd >= 0) {
2226     + if (read(fd, buf, size) == size) {
2227     + while (i < size && buf[i] != 0) {
2228     + i++;
2229     + }
2230     + if (i == size) {
2231     + close(fd);
2232     + return;
2233     + }
2234     + }
2235     + close(fd);
2236     + }
2237     +#endif
2238     + t = (unsigned char)getpid();
2239     + while (i < size) {
2240     + do {
2241     + buf[i] = ((unsigned char)rand()) ^ t;
2242     + } while (buf[i] == 0);
2243     + t = buf[i++] << 1;
2244     + }
2245     +}
2246     +/* }}} */
2247     +#endif
2248     +
2249     +
2250     +/* Notes:
2251     + * - This function may alter the block_sizes values to match platform alignment
2252     + * - This function does *not* perform sanity checks on the arguments
2253     + */
2254     +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)
2255     +{
2256     + zend_mm_storage *storage;
2257     + zend_mm_heap_canary *heap;
2258     + zend_mm_free_block_canary *tmp;
2259     +
2260     +#if 0
2261     + int i;
2262     +
2263     + printf("ZEND_MM_ALIGNMENT=%d\n", ZEND_MM_ALIGNMENT);
2264     + printf("ZEND_MM_ALIGNMENT_LOG2=%d\n", ZEND_MM_ALIGNMENT_LOG2);
2265     + printf("ZEND_MM_MIN_SIZE=%d\n", ZEND_MM_MIN_SIZE);
2266     + printf("ZEND_MM_MAX_SMALL_SIZE=%d\n", ZEND_MM_MAX_SMALL_SIZE);
2267     + printf("ZEND_MM_ALIGNED_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_HEADER_SIZE);
2268     + printf("ZEND_MM_ALIGNED_FREE_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_FREE_HEADER_SIZE);
2269     + printf("ZEND_MM_MIN_ALLOC_BLOCK_SIZE=%d\n", ZEND_MM_MIN_ALLOC_BLOCK_SIZE);
2270     + printf("ZEND_MM_ALIGNED_MIN_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_MIN_HEADER_SIZE);
2271     + printf("ZEND_MM_ALIGNED_SEGMENT_SIZE=%d\n", ZEND_MM_ALIGNED_SEGMENT_SIZE);
2272     + for (i = 0; i < ZEND_MM_MAX_SMALL_SIZE; i++) {
2273     + printf("%3d%c: %3ld %d %2ld\n", i, (i == ZEND_MM_MIN_SIZE?'*':' '), (long)ZEND_MM_TRUE_SIZE(i), ZEND_MM_SMALL_SIZE(ZEND_MM_TRUE_SIZE(i)), (long)ZEND_MM_BUCKET_INDEX(ZEND_MM_TRUE_SIZE(i)));
2274     + }
2275     + exit(0);
2276     +#endif
2277     +
2278     +#if ZEND_MM_HEAP_PROTECTION
2279     + if (_mem_block_start_magic == 0) {
2280     + zend_mm_random((unsigned char*)&_mem_block_start_magic, sizeof(_mem_block_start_magic));
2281     + }
2282     + if (_mem_block_end_magic == 0) {
2283     + zend_mm_random((unsigned char*)&_mem_block_end_magic, sizeof(_mem_block_end_magic));
2284     + }
2285     +#endif
2286     +#if ZEND_MM_COOKIES
2287     + if (_zend_mm_cookie == 0) {
2288     + zend_mm_random((unsigned char*)&_zend_mm_cookie, sizeof(_zend_mm_cookie));
2289     + }
2290     +#endif
2291     +
2292     + /* get the pointer guardian and ensure low 3 bits are 1 */
2293     + if (SUHOSIN_POINTER_GUARD == 0) {
2294     + zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
2295     + SUHOSIN_POINTER_GUARD |= 7;
2296     + }
2297     +
2298     + if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
2299     + fprintf(stderr, "'block_size' must be a power of two\n");
2300     +/* See http://support.microsoft.com/kb/190351 */
2301     +#ifdef PHP_WIN32
2302     + fflush(stderr);
2303     +#endif
2304     + exit(255);
2305     + }
2306     + storage = handlers->init(params);
2307     + if (!storage) {
2308     + fprintf(stderr, "Cannot initialize zend_mm storage [%s]\n", handlers->name);
2309     +/* See http://support.microsoft.com/kb/190351 */
2310     +#ifdef PHP_WIN32
2311     + fflush(stderr);
2312     +#endif
2313     + exit(255);
2314     + }
2315     + storage->handlers = handlers;
2316     +
2317     + heap = malloc(sizeof(struct _zend_mm_heap_canary));
2318     + if (heap == NULL) {
2319     + fprintf(stderr, "Cannot allocate heap for zend_mm storage [%s]\n", handlers->name);
2320     +#ifdef PHP_WIN32
2321     + fflush(stderr);
2322     +#endif
2323     + exit(255);
2324     + }
2325     +
2326     + heap->storage = storage;
2327     + heap->block_size = block_size;
2328     + heap->compact_size = 0;
2329     + heap->segments_list = NULL;
2330     + zend_mm_init(heap);
2331     +# if ZEND_MM_CACHE_STAT
2332     + memset(heap->cache_stat, 0, sizeof(heap->cache_stat));
2333     +# endif
2334     +
2335     + heap->use_zend_alloc = 1;
2336     + heap->real_size = 0;
2337     + heap->overflow = 0;
2338     + heap->real_peak = 0;
2339     + heap->limit = ZEND_MM_LONG_CONST(1)<<(ZEND_MM_NUM_BUCKETS-2);
2340     + heap->size = 0;
2341     + heap->peak = 0;
2342     + heap->internal = internal;
2343     + heap->reserve = NULL;
2344     + heap->reserve_size = reserve_size;
2345     + if (reserve_size > 0) {
2346     + heap->reserve = _zend_mm_alloc((zend_mm_heap *)heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2347     + }
2348     + if (internal) {
2349     + int i;
2350     + zend_mm_free_block_canary *p, *q, *orig;
2351     + zend_mm_heap_canary *mm_heap = _zend_mm_alloc((zend_mm_heap *)heap, sizeof(zend_mm_heap_canary) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2352     +
2353     + *mm_heap = *heap;
2354     +
2355     + p = ZEND_MM_SMALL_FREE_BUCKET(mm_heap, 0);
2356     + orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
2357     + for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
2358     + q = p;
2359     + while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) {
2360     + q = SUHOSIN_MANGLE_PTR(q->prev_free_block);
2361     + }
2362     + q->prev_free_block = SUHOSIN_MANGLE_PTR(p);
2363     + q = p;
2364     + while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) {
2365     + q = SUHOSIN_MANGLE_PTR(q->next_free_block);
2366     + }
2367     + q->next_free_block = SUHOSIN_MANGLE_PTR(p);
2368     + p = (zend_mm_free_block_canary*)((char*)p + sizeof(zend_mm_free_block_canary*) * 2);
2369     + orig = (zend_mm_free_block_canary*)((char*)orig + sizeof(zend_mm_free_block_canary*) * 2);
2370     + if (mm_heap->large_free_buckets[i]) {
2371     + mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
2372     + }
2373     + }
2374     + mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap));
2375     +
2376     + free(heap);
2377     + heap = mm_heap;
2378     + }
2379     + return heap;
2380     +}
2381     +
2382     +zend_mm_heap_canary *__zend_mm_startup_canary(void)
2383     +{
2384     + int i;
2385     + size_t seg_size;
2386     + char *mem_type = getenv("ZEND_MM_MEM_TYPE");
2387     + char *tmp;
2388     + const zend_mm_mem_handlers *handlers;
2389     + zend_mm_heap_canary *heap;
2390     +
2391     + if (mem_type == NULL) {
2392     + i = 0;
2393     + } else {
2394     + for (i = 0; mem_handlers[i].name; i++) {
2395     + if (strcmp(mem_handlers[i].name, mem_type) == 0) {
2396     + break;
2397     + }
2398     + }
2399     + if (!mem_handlers[i].name) {
2400     + fprintf(stderr, "Wrong or unsupported zend_mm storage type '%s'\n", mem_type);
2401     + fprintf(stderr, " supported types:\n");
2402     +/* See http://support.microsoft.com/kb/190351 */
2403     +#ifdef PHP_WIN32
2404     + fflush(stderr);
2405     +#endif
2406     + for (i = 0; mem_handlers[i].name; i++) {
2407     + fprintf(stderr, " '%s'\n", mem_handlers[i].name);
2408     + }
2409     +/* See http://support.microsoft.com/kb/190351 */
2410     +#ifdef PHP_WIN32
2411     + fflush(stderr);
2412     +#endif
2413     + exit(255);
2414     + }
2415     + }
2416     + handlers = &mem_handlers[i];
2417     +
2418     + tmp = getenv("ZEND_MM_SEG_SIZE");
2419     + if (tmp) {
2420     + seg_size = zend_atoi(tmp, 0);
2421     + if (zend_mm_low_bit(seg_size) != zend_mm_high_bit(seg_size)) {
2422     + fprintf(stderr, "ZEND_MM_SEG_SIZE must be a power of two\n");
2423     +/* See http://support.microsoft.com/kb/190351 */
2424     +#ifdef PHP_WIN32
2425     + fflush(stderr);
2426     +#endif
2427     + exit(255);
2428     + } else if (seg_size < ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE) {
2429     + fprintf(stderr, "ZEND_MM_SEG_SIZE is too small\n");
2430     +/* See http://support.microsoft.com/kb/190351 */
2431     +#ifdef PHP_WIN32
2432     + fflush(stderr);
2433     +#endif
2434     + exit(255);
2435     + }
2436     + } else {
2437     + seg_size = ZEND_MM_SEG_SIZE;
2438     + }
2439     +
2440     + heap = __zend_mm_startup_canary_ex(handlers, seg_size, ZEND_MM_RESERVE_SIZE, 0, NULL);
2441     + if (heap) {
2442     + tmp = getenv("ZEND_MM_COMPACT");
2443     + if (tmp) {
2444     + heap->compact_size = zend_atoi(tmp, 0);
2445     + } else {
2446     + heap->compact_size = 2 * 1024 * 1024;
2447     + }
2448     + }
2449     + return heap;
2450     +}
2451     +
2452     +#if ZEND_DEBUG
2453     +static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block_canary *b)
2454     +{
2455     + long leaks = 0;
2456     + zend_mm_block_canary *p, *q;
2457     +
2458     + p = ZEND_MM_NEXT_BLOCK(b);
2459     + while (1) {
2460     + if (ZEND_MM_IS_GUARD_BLOCK(p)) {
2461     + ZEND_MM_CHECK_MAGIC(p, MEM_BLOCK_GUARD);
2462     + segment = segment->next_segment;
2463     + if (!segment) {
2464     + break;
2465     + }
2466     + p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2467     + continue;
2468     + }
2469     + q = ZEND_MM_NEXT_BLOCK(p);
2470     + if (q <= p ||
2471     + (char*)q > (char*)segment + segment->size ||
2472     + p->info._size != q->info._prev) {
2473     + zend_mm_panic("zend_mm_heap corrupted");
2474     + }
2475     + if (!ZEND_MM_IS_FREE_BLOCK(p)) {
2476     + if (p->magic == MEM_BLOCK_VALID) {
2477     + if (p->debug.filename==b->debug.filename && p->debug.lineno==b->debug.lineno) {
2478     + ZEND_MM_SET_MAGIC(p, MEM_BLOCK_LEAK);
2479     + leaks++;
2480     + }
2481     +#if ZEND_MM_CACHE
2482     + } else if (p->magic == MEM_BLOCK_CACHED) {
2483     + /* skip it */
2484     +#endif
2485     + } else if (p->magic != MEM_BLOCK_LEAK) {
2486     + zend_mm_panic("zend_mm_heap corrupted");
2487     + }
2488     + }
2489     + p = q;
2490     + }
2491     + return leaks;
2492     +}
2493     +
2494     +static void zend_mm_check_leaks(zend_mm_heap_canary *heap TSRMLS_DC)
2495     +{
2496     + zend_mm_segment *segment = heap->segments_list;
2497     + zend_mm_block_canary *p, *q;
2498     + zend_uint total = 0;
2499     +
2500     + if (!segment) {
2501     + return;
2502     + }
2503     + p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2504     + while (1) {
2505     + q = ZEND_MM_NEXT_BLOCK(p);
2506     + if (q <= p ||
2507     + (char*)q > (char*)segment + segment->size ||
2508     + p->info._size != q->info._prev) {
2509     + zend_mm_panic("zend_mm_heap corrupted");
2510     + }
2511     + if (!ZEND_MM_IS_FREE_BLOCK(p)) {
2512     + if (p->magic == MEM_BLOCK_VALID) {
2513     + long repeated;
2514     + zend_leak_info leak;
2515     +
2516     + ZEND_MM_SET_MAGIC(p, MEM_BLOCK_LEAK);
2517     +
2518     + leak.addr = ZEND_MM_DATA_OF(p);
2519     + leak.size = p->debug.size;
2520     + leak.filename = p->debug.filename;
2521     + leak.lineno = p->debug.lineno;
2522     + leak.orig_filename = p->debug.orig_filename;
2523     + leak.orig_lineno = p->debug.orig_lineno;
2524     +
2525     + zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
2526     + zend_message_dispatcher(ZMSG_MEMORY_LEAK_DETECTED, &leak TSRMLS_CC);
2527     + repeated = zend_mm_find_leaks(segment, p);
2528     + total += 1 + repeated;
2529     + if (repeated) {
2530     + zend_message_dispatcher(ZMSG_MEMORY_LEAK_REPEATED, (void *)(zend_uintptr_t)repeated TSRMLS_CC);
2531     + }
2532     +#if ZEND_MM_CACHE
2533     + } else if (p->magic == MEM_BLOCK_CACHED) {
2534     + /* skip it */
2535     +#endif
2536     + } else if (p->magic != MEM_BLOCK_LEAK) {
2537     + zend_mm_panic("zend_mm_heap corrupted");
2538     + }
2539     + }
2540     + if (ZEND_MM_IS_GUARD_BLOCK(q)) {
2541     + segment = segment->next_segment;
2542     + if (!segment) {
2543     + break;
2544     + }
2545     + q = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2546     + }
2547     + p = q;
2548     + }
2549     + if (total) {
2550     + zend_message_dispatcher(ZMSG_MEMORY_LEAKS_GRAND_TOTAL, &total TSRMLS_CC);
2551     + }
2552     +}
2553     +
2554     +static int zend_mm_check_ptr(zend_mm_heap_canary *heap, void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2555     +{
2556     + zend_mm_block_canary *p;
2557     + int no_cache_notice = 0;
2558     + int had_problems = 0;
2559     + int valid_beginning = 1;
2560     +
2561     + if (silent==2) {
2562     + silent = 1;
2563     + no_cache_notice = 1;
2564     + } else if (silent==3) {
2565     + silent = 0;
2566     + no_cache_notice = 1;
2567     + }
2568     + if (!silent) {
2569     + TSRMLS_FETCH();
2570     +
2571     + zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
2572     + zend_debug_alloc_output("---------------------------------------\n");
2573     + zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr);
2574     + if (__zend_orig_filename) {
2575     + zend_debug_alloc_output("%s(%d) : Actual location (location was relayed)\n" ZEND_FILE_LINE_ORIG_RELAY_CC);
2576     + }
2577     + if (!ptr) {
2578     + zend_debug_alloc_output("NULL\n");
2579     + zend_debug_alloc_output("---------------------------------------\n");
2580     + return 0;
2581     + }
2582     + }
2583     +
2584     + if (!ptr) {
2585     + if (silent) {
2586     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2587     + }
2588     + }
2589     +
2590     + p = ZEND_MM_HEADER_OF(ptr);
2591     +
2592     +#ifdef ZTS
2593     + if (ZEND_MM_BAD_THREAD_ID(p)) {
2594     + if (!silent) {
2595     + zend_debug_alloc_output("Invalid pointer: ((thread_id=0x%0.8X) != (expected=0x%0.8X))\n", (long)p->thread_id, (long)tsrm_thread_id());
2596     + had_problems = 1;
2597     + } else {
2598     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2599     + }
2600     + }
2601     +#endif
2602     +
2603     + if (p->info._size != ZEND_MM_NEXT_BLOCK(p)->info._prev) {
2604     + if (!silent) {
2605     + zend_debug_alloc_output("Invalid pointer: ((size="PTR_FMT") != (next.prev="PTR_FMT"))\n", p->info._size, ZEND_MM_NEXT_BLOCK(p)->info._prev);
2606     + had_problems = 1;
2607     + } else {
2608     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2609     + }
2610     + }
2611     + if (p->info._prev != ZEND_MM_GUARD_BLOCK &&
2612     + ZEND_MM_PREV_BLOCK(p)->info._size != p->info._prev) {
2613     + if (!silent) {
2614     + zend_debug_alloc_output("Invalid pointer: ((prev="PTR_FMT") != (prev.size="PTR_FMT"))\n", p->info._prev, ZEND_MM_PREV_BLOCK(p)->info._size);
2615     + had_problems = 1;
2616     + } else {
2617     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2618     + }
2619     + }
2620     +
2621     + if (had_problems) {
2622     + zend_debug_alloc_output("---------------------------------------\n");
2623     + return 0;
2624     + }
2625     +
2626     + if (!silent) {
2627     + zend_debug_alloc_output("%10s\t","Beginning: ");
2628     + }
2629     +
2630     + if (!ZEND_MM_IS_USED_BLOCK(p)) {
2631     + if (!silent) {
2632     + if (p->magic != MEM_BLOCK_FREED) {
2633     + zend_debug_alloc_output("Freed (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_FREED);
2634     + } else {
2635     + zend_debug_alloc_output("Freed\n");
2636     + }
2637     + had_problems = 1;
2638     + } else {
2639     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2640     + }
2641     + } else if (ZEND_MM_IS_GUARD_BLOCK(p)) {
2642     + if (!silent) {
2643     + if (p->magic != MEM_BLOCK_FREED) {
2644     + zend_debug_alloc_output("Guard (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_FREED);
2645     + } else {
2646     + zend_debug_alloc_output("Guard\n");
2647     + }
2648     + had_problems = 1;
2649     + } else {
2650     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2651     + }
2652     + } else {
2653     + switch (p->magic) {
2654     + case MEM_BLOCK_VALID:
2655     + case MEM_BLOCK_LEAK:
2656     + if (!silent) {
2657     + zend_debug_alloc_output("OK (allocated on %s:%d, %d bytes)\n", p->debug.filename, p->debug.lineno, (int)p->debug.size);
2658     + }
2659     + break; /* ok */
2660     + case MEM_BLOCK_CACHED:
2661     + if (!no_cache_notice) {
2662     + if (!silent) {
2663     + zend_debug_alloc_output("Cached\n");
2664     + had_problems = 1;
2665     + } else {
2666     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2667     + }
2668     + }
2669     + case MEM_BLOCK_FREED:
2670     + if (!silent) {
2671     + zend_debug_alloc_output("Freed (invalid)\n");
2672     + had_problems = 1;
2673     + } else {
2674     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2675     + }
2676     + break;
2677     + case MEM_BLOCK_GUARD:
2678     + if (!silent) {
2679     + zend_debug_alloc_output("Guard (invalid)\n");
2680     + had_problems = 1;
2681     + } else {
2682     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2683     + }
2684     + break;
2685     + default:
2686     + if (!silent) {
2687     + zend_debug_alloc_output("Unknown (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_VALID);
2688     + had_problems = 1;
2689     + valid_beginning = 0;
2690     + } else {
2691     + return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2692     + }
2693     + break;
2694     + }
2695     + }
2696     +
2697     +#if ZEND_MM_HEAP_PROTECTION
2698     + if (!valid_beginning) {
2699     + if (!silent) {
2700     + zend_debug_alloc_output("%10s\t", "Start:");
2701     + zend_debug_alloc_output("Unknown\n");
2702     + zend_debug_alloc_output("%10s\t", "End:");
2703     + zend_debug_alloc_output("Unknown\n");
2704     + }
2705     + } else {
2706     + char *end_magic = ZEND_MM_END_MAGIC_PTR(p);
2707     +
2708     + if (p->debug.start_magic == _mem_block_start_magic) {
2709     + if (!silent) {
2710     + zend_debug_alloc_output("%10s\t", "Start:");
2711     + zend_debug_alloc_output("OK\n");
2712     + }
2713     + } else {
2714     + char *overflow_ptr, *magic_ptr=(char *) &_mem_block_start_magic;
2715     + int overflows=0;
2716     + int i;
2717     +
2718     + if (silent) {
2719     + return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2720     + }
2721     + had_problems = 1;
2722     + overflow_ptr = (char *) &p->debug.start_magic;
2723     + i = END_MAGIC_SIZE;
2724     + while (--i >= 0) {
2725     + if (overflow_ptr[i]!=magic_ptr[i]) {
2726     + overflows++;
2727     + }
2728     + }
2729     + zend_debug_alloc_output("%10s\t", "Start:");
2730     + zend_debug_alloc_output("Overflown (magic=0x%0.8X instead of 0x%0.8X)\n", p->debug.start_magic, _mem_block_start_magic);
2731     + zend_debug_alloc_output("%10s\t","");
2732     + if (overflows >= END_MAGIC_SIZE) {
2733     + zend_debug_alloc_output("At least %d bytes overflown\n", END_MAGIC_SIZE);
2734     + } else {
2735     + zend_debug_alloc_output("%d byte(s) overflown\n", overflows);
2736     + }
2737     + }
2738     + if (memcmp(end_magic, &_mem_block_end_magic, END_MAGIC_SIZE)==0) {
2739     + if (!silent) {
2740     + zend_debug_alloc_output("%10s\t", "End:");
2741     + zend_debug_alloc_output("OK\n");
2742     + }
2743     + } else {
2744     + char *overflow_ptr, *magic_ptr=(char *) &_mem_block_end_magic;
2745     + int overflows=0;
2746     + int i;
2747     +
2748     + if (silent) {
2749     + return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2750     + }
2751     + had_problems = 1;
2752     + overflow_ptr = (char *) end_magic;
2753     +
2754     + for (i=0; i < END_MAGIC_SIZE; i++) {
2755     + if (overflow_ptr[i]!=magic_ptr[i]) {
2756     + overflows++;
2757     + }
2758     + }
2759     +
2760     + zend_debug_alloc_output("%10s\t", "End:");
2761     + zend_debug_alloc_output("Overflown (magic=0x%0.8X instead of 0x%0.8X)\n", *end_magic, _mem_block_end_magic);
2762     + zend_debug_alloc_output("%10s\t","");
2763     + if (overflows >= END_MAGIC_SIZE) {
2764     + zend_debug_alloc_output("At least %d bytes overflown\n", END_MAGIC_SIZE);
2765     + } else {
2766     + zend_debug_alloc_output("%d byte(s) overflown\n", overflows);
2767     + }
2768     + }
2769     + }
2770     +#endif
2771     +
2772     + if (!silent) {
2773     + zend_debug_alloc_output("---------------------------------------\n");
2774     + }
2775     + return ((!had_problems) ? 1 : 0);
2776     +}
2777     +
2778     +static int zend_mm_check_heap(zend_mm_heap_canary *heap, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2779     +{
2780     + zend_mm_segment *segment = heap->segments_list;
2781     + zend_mm_block_canary *p, *q;
2782     + int errors = 0;
2783     +
2784     + if (!segment) {
2785     + return 0;
2786     + }
2787     + p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2788     + while (1) {
2789     + q = ZEND_MM_NEXT_BLOCK(p);
2790     + if (q <= p ||
2791     + (char*)q > (char*)segment + segment->size ||
2792     + p->info._size != q->info._prev) {
2793     + zend_mm_panic("zend_mm_heap corrupted");
2794     + }
2795     + if (!ZEND_MM_IS_FREE_BLOCK(p)) {
2796     + if (p->magic == MEM_BLOCK_VALID || p->magic == MEM_BLOCK_LEAK) {
2797     + if (!zend_mm_check_ptr(heap, ZEND_MM_DATA_OF(p), (silent?2:3) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)) {
2798     + errors++;
2799     + }
2800     +#if ZEND_MM_CACHE
2801     + } else if (p->magic == MEM_BLOCK_CACHED) {
2802     + /* skip it */
2803     +#endif
2804     + } else if (p->magic != MEM_BLOCK_LEAK) {
2805     + zend_mm_panic("zend_mm_heap corrupted");
2806     + }
2807     + }
2808     + if (ZEND_MM_IS_GUARD_BLOCK(q)) {
2809     + segment = segment->next_segment;
2810     + if (!segment) {
2811     + return errors;
2812     + }
2813     + q = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2814     + }
2815     + p = q;
2816     + }
2817     +}
2818     +#endif
2819     +
2820     +void __zend_mm_shutdown_canary(zend_mm_heap_canary *heap, int full_shutdown, int silent TSRMLS_DC)
2821     +{
2822     + zend_mm_storage *storage;
2823     + zend_mm_segment *segment;
2824     + zend_mm_segment *prev;
2825     + int internal;
2826     +
2827     + if (heap->reserve) {
2828     +#if ZEND_DEBUG
2829     + if (!silent) {
2830     + _zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2831     + }
2832     +#endif
2833     + heap->reserve = NULL;
2834     + }
2835     +
2836     +#if ZEND_MM_CACHE_STAT
2837     + if (full_shutdown) {
2838     + FILE *f;
2839     +
2840     + f = fopen("zend_mm.log", "w");
2841     + if (f) {
2842     + int i,j;
2843     + size_t size, true_size, min_size, max_size;
2844     + int hit = 0, miss = 0;
2845     +
2846     + fprintf(f, "\nidx min_size max_size true_size max_len hits misses\n");
2847     + size = 0;
2848     + while (1) {
2849     + true_size = ZEND_MM_TRUE_SIZE(size);
2850     + if (ZEND_MM_SMALL_SIZE(true_size)) {
2851     + min_size = size;
2852     + i = ZEND_MM_BUCKET_INDEX(true_size);
2853     + size++;
2854     + while (1) {
2855     + true_size = ZEND_MM_TRUE_SIZE(size);
2856     + if (ZEND_MM_SMALL_SIZE(true_size)) {
2857     + j = ZEND_MM_BUCKET_INDEX(true_size);
2858     + if (j > i) {
2859     + max_size = size-1;
2860     + break;
2861     + }
2862     + } else {
2863     + max_size = size-1;
2864     + break;
2865     + }
2866     + size++;
2867     + }
2868     + hit += heap->cache_stat[i].hit;
2869     + miss += heap->cache_stat[i].miss;
2870     + fprintf(f, "%2d %8d %8d %9d %8d %8d %8d\n", i, (int)min_size, (int)max_size, ZEND_MM_TRUE_SIZE(max_size), heap->cache_stat[i].max_count, heap->cache_stat[i].hit, heap->cache_stat[i].miss);
2871     + } else {
2872     + break;
2873     + }
2874     + }
2875     + fprintf(f, " %8d %8d\n", hit, miss);
2876     + fprintf(f, " %8d %8d\n", heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit, heap->cache_stat[ZEND_MM_NUM_BUCKETS].miss);
2877     + fclose(f);
2878     + }
2879     + }
2880     +#endif
2881     +
2882     +#if ZEND_DEBUG
2883     + if (!silent) {
2884     + zend_mm_check_leaks(heap TSRMLS_CC);
2885     + }
2886     +#endif
2887     +
2888     + internal = heap->internal;
2889     + storage = heap->storage;
2890     + segment = heap->segments_list;
2891     + while (segment) {
2892     + prev = segment;
2893     + segment = segment->next_segment;
2894     + ZEND_MM_STORAGE_FREE(prev);
2895     + }
2896     + if (full_shutdown) {
2897     + storage->handlers->dtor(storage);
2898     + if (!internal) {
2899     + free(heap);
2900     + }
2901     + } else {
2902     + if (heap->compact_size &&
2903     + heap->real_peak > heap->compact_size) {
2904     + storage->handlers->compact(storage);
2905     + }
2906     + heap->segments_list = NULL;
2907     + zend_mm_init(heap);
2908     + heap->real_size = 0;
2909     + heap->real_peak = 0;
2910     + heap->size = 0;
2911     + heap->peak = 0;
2912     + if (heap->reserve_size) {
2913     + heap->reserve = _zend_mm_alloc((zend_mm_heap *)heap, heap->reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2914     + }
2915     + heap->overflow = 0;
2916     + }
2917     +}
2918     +
2919     +static void zend_mm_safe_error(zend_mm_heap_canary *heap,
2920     + const char *format,
2921     + size_t limit,
2922     +#if ZEND_DEBUG
2923     + const char *filename,
2924     + uint lineno,
2925     +#endif
2926     + size_t size)
2927     +{
2928     + if (heap->reserve) {
2929     + _zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2930     + heap->reserve = NULL;
2931     + }
2932     + if (heap->overflow == 0) {
2933     + char *error_filename;
2934     + uint error_lineno;
2935     + TSRMLS_FETCH();
2936     + if (zend_is_compiling(TSRMLS_C)) {
2937     + error_filename = zend_get_compiled_filename(TSRMLS_C);
2938     + error_lineno = zend_get_compiled_lineno(TSRMLS_C);
2939     + } else if (EG(in_execution)) {
2940     + error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
2941     + error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
2942     + } else {
2943     + error_filename = NULL;
2944     + error_lineno = 0;
2945     + }
2946     + if (!error_filename) {
2947     + error_filename = "Unknown";
2948     + }
2949     + heap->overflow = 1;
2950     + zend_try {
2951     + zend_error_noreturn(E_ERROR,
2952     + format,
2953     + limit,
2954     +#if ZEND_DEBUG
2955     + filename,
2956     + lineno,
2957     +#endif
2958     + size);
2959     + } zend_catch {
2960     + if (heap->overflow == 2) {
2961     + fprintf(stderr, "\nFatal error: ");
2962     + fprintf(stderr,
2963     + format,
2964     + limit,
2965     +#if ZEND_DEBUG
2966     + filename,
2967     + lineno,
2968     +#endif
2969     + size);
2970     + fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
2971     + }
2972     +/* See http://support.microsoft.com/kb/190351 */
2973     +#ifdef PHP_WIN32
2974     + fflush(stderr);
2975     +#endif
2976     + } zend_end_try();
2977     + } else {
2978     + heap->overflow = 2;
2979     + }
2980     + zend_bailout();
2981     +}
2982     +
2983     +static zend_mm_free_block_canary *zend_mm_search_large_block(zend_mm_heap_canary *heap, size_t true_size)
2984     +{
2985     + zend_mm_free_block_canary *best_fit;
2986     + size_t index = ZEND_MM_LARGE_BUCKET_INDEX(true_size);
2987     + size_t bitmap = heap->large_free_bitmap >> index;
2988     + zend_mm_free_block_canary *p;
2989     +
2990     + if (bitmap == 0) {
2991     + return NULL;
2992     + }
2993     +
2994     + if (UNEXPECTED((bitmap & 1) != 0)) {
2995     + /* Search for best "large" free block */
2996     + zend_mm_free_block_canary *rst = NULL;
2997     + size_t m;
2998     + size_t best_size = -1;
2999     +
3000     + best_fit = NULL;
3001     + p = heap->large_free_buckets[index];
3002     + for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
3003     + if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
3004     + return SUHOSIN_MANGLE_PTR(p->next_free_block);
3005     + } else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
3006     + ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
3007     + best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
3008     + best_fit = p;
3009     + }
3010     + if ((m & (ZEND_MM_LONG_CONST(1) << (ZEND_MM_NUM_BUCKETS-1))) == 0) {
3011     + if (p->child[1]) {
3012     + rst = p->child[1];
3013     + }
3014     + if (p->child[0]) {
3015     + p = p->child[0];
3016     + } else {
3017     + break;
3018     + }
3019     + } else if (p->child[1]) {
3020     + p = p->child[1];
3021     + } else {
3022     + break;
3023     + }
3024     + }
3025     +
3026     + for (p = rst; p; p = p->child[p->child[0] != NULL]) {
3027     + if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
3028     + return SUHOSIN_MANGLE_PTR(p->next_free_block);
3029     + } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
3030     + ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
3031     + best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
3032     + best_fit = p;
3033     + }
3034     + }
3035     +
3036     + if (best_fit) {
3037     + return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
3038     + }
3039     + bitmap = bitmap >> 1;
3040     + if (!bitmap) {
3041     + return NULL;
3042     + }
3043     + index++;
3044     + }
3045     +
3046     + /* Search for smallest "large" free block */
3047     + best_fit = p = heap->large_free_buckets[index + zend_mm_low_bit(bitmap)];
3048     + while ((p = p->child[p->child[0] != NULL])) {
3049     + if (ZEND_MM_FREE_BLOCK_SIZE(p) < ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {
3050     + best_fit = p;
3051     + }
3052     + }
3053     + return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
3054     +}
3055     +
3056     +void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
3057     +{
3058     + zend_mm_free_block_canary *best_fit;
3059     + size_t true_size = ZEND_MM_TRUE_SIZE(size);
3060     + size_t block_size;
3061     + size_t remaining_size;
3062     + size_t segment_size;
3063     + zend_mm_segment *segment;
3064     + int keep_rest = 0;
3065     +
3066     + if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
3067     + size_t index = ZEND_MM_BUCKET_INDEX(true_size);
3068     + size_t bitmap;
3069     +
3070     + if (UNEXPECTED(true_size < size)) {
3071     + goto out_of_memory;
3072     + }
3073     +#if ZEND_MM_CACHE
3074     + if (EXPECTED(heap->cache[index] != NULL)) {
3075     + /* Get block from cache */
3076     +#if ZEND_MM_CACHE_STAT
3077     + heap->cache_stat[index].count--;
3078     + heap->cache_stat[index].hit++;
3079     +#endif
3080     + best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
3081     + heap->cache[index] = best_fit->prev_free_block;
3082     + heap->cached -= true_size;
3083     +#if SUHOSIN_PATCH
3084     + SUHOSIN_MM_SET_CANARIES(best_fit);
3085     + ((zend_mm_block_canary*)best_fit)->info.size = size;
3086     + SUHOSIN_MM_SET_END_CANARY(best_fit);
3087     +#endif
3088     + ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
3089     + ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
3090     + return ZEND_MM_DATA_OF(best_fit);
3091     + }
3092     +#if ZEND_MM_CACHE_STAT
3093     + heap->cache_stat[index].miss++;
3094     +#endif
3095     +#endif
3096     +
3097     + bitmap = heap->free_bitmap >> index;
3098     + if (bitmap) {
3099     + /* Found some "small" free block that can be used */
3100     + index += zend_mm_low_bit(bitmap);
3101     + best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]);
3102     +#if ZEND_MM_CACHE_STAT
3103     + heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
3104     +#endif
3105     + goto zend_mm_finished_searching_for_block;
3106     + }
3107     + }
3108     +
3109     +#if ZEND_MM_CACHE_STAT
3110     + heap->cache_stat[ZEND_MM_NUM_BUCKETS].miss++;
3111     +#endif
3112     +
3113     + best_fit = zend_mm_search_large_block(heap, true_size);
3114     +
3115     + if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
3116     + zend_mm_free_block_canary *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
3117     + size_t best_size = -1;
3118     +
3119     + while (p != ZEND_MM_REST_BUCKET(heap)) {
3120     + if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
3121     + best_fit = p;
3122     + goto zend_mm_finished_searching_for_block;
3123     + } else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
3124     + ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
3125     + best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
3126     + best_fit = p;
3127     + }
3128     + p = SUHOSIN_MANGLE_PTR(p->prev_free_block);
3129     + }
3130     + }
3131     +
3132     + if (!best_fit) {
3133     + if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
3134     + /* Make sure we add a memory block which is big enough,
3135     + segment must have header "size" and trailer "guard" block */
3136     + segment_size = true_size + ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE;
3137     + segment_size = (segment_size + (heap->block_size-1)) & ~(heap->block_size-1);
3138     + keep_rest = 1;
3139     + } else {
3140     + segment_size = heap->block_size;
3141     + }
3142     +
3143     + HANDLE_BLOCK_INTERRUPTIONS();
3144     +
3145     + if (segment_size < true_size ||
3146     + heap->real_size + segment_size > heap->limit) {
3147     + /* Memory limit overflow */
3148     +#if ZEND_MM_CACHE
3149     + zend_mm_free_cache(heap);
3150     +#endif
3151     + HANDLE_UNBLOCK_INTERRUPTIONS();
3152     +#if ZEND_DEBUG
3153     + zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %lu bytes)", heap->limit, __zend_filename, __zend_lineno, size);
3154     +#else
3155     + zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", heap->limit, size);
3156     +#endif
3157     + }
3158     +
3159     + segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);
3160     +
3161     + if (!segment) {
3162     + /* Storage manager cannot allocate memory */
3163     +#if ZEND_MM_CACHE
3164     + zend_mm_free_cache(heap);
3165     +#endif
3166     + HANDLE_UNBLOCK_INTERRUPTIONS();
3167     +out_of_memory:
3168     +#if ZEND_DEBUG
3169     + 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);
3170     +#else
3171     + zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
3172     +#endif
3173     + return NULL;
3174     + }
3175     +
3176     + heap->real_size += segment_size;
3177     + if (heap->real_size > heap->real_peak) {
3178     + heap->real_peak = heap->real_size;
3179     + }
3180     +
3181     + segment->size = segment_size;
3182     + segment->next_segment = heap->segments_list;
3183     + heap->segments_list = segment;
3184     +
3185     + best_fit = (zend_mm_free_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
3186     + ZEND_MM_MARK_FIRST_BLOCK(best_fit);
3187     +
3188     + block_size = segment_size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE;
3189     +
3190     + ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(best_fit, block_size));
3191     +
3192     + } else {
3193     +zend_mm_finished_searching_for_block:
3194     + /* remove from free list */
3195     + HANDLE_BLOCK_INTERRUPTIONS();
3196     + ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED);
3197     + ZEND_MM_CHECK_COOKIE(best_fit);
3198     + ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit);
3199     + zend_mm_remove_from_free_list(heap, best_fit);
3200     +
3201     + block_size = ZEND_MM_FREE_BLOCK_SIZE(best_fit);
3202     + }
3203     +
3204     + remaining_size = block_size - true_size;
3205     +
3206     + if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
3207     + true_size = block_size;
3208     + ZEND_MM_BLOCK(best_fit, ZEND_MM_USED_BLOCK, true_size);
3209     + } else {
3210     + zend_mm_free_block_canary *new_free_block;
3211     +
3212     + /* prepare new free block */
3213     + ZEND_MM_BLOCK(best_fit, ZEND_MM_USED_BLOCK, true_size);
3214     + new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(best_fit, true_size);
3215     + ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
3216     +
3217     + /* add the new free block to the free list */
3218     + if (EXPECTED(!keep_rest)) {
3219     + zend_mm_add_to_free_list(heap, new_free_block);
3220     + } else {
3221     + zend_mm_add_to_rest_list(heap, new_free_block);
3222     + }
3223     + }
3224     +
3225     + ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
3226     +
3227     +#if SUHOSIN_PATCH
3228     + SUHOSIN_MM_SET_CANARIES(best_fit);
3229     + ((zend_mm_block_canary*)best_fit)->info.size = size;
3230     + SUHOSIN_MM_SET_END_CANARY(best_fit);
3231     +#endif
3232     +
3233     + heap->size += true_size;
3234     + if (heap->peak < heap->size) {
3235     + heap->peak = heap->size;
3236     + }
3237     +
3238     + HANDLE_UNBLOCK_INTERRUPTIONS();
3239     + return ZEND_MM_DATA_OF(best_fit);
3240     +}
3241     +
3242     +
3243     +void _zend_mm_free_canary_int(zend_mm_heap_canary *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
3244     +{
3245     + zend_mm_block_canary *mm_block;
3246     + zend_mm_block_canary *next_block;
3247     + size_t size;
3248     +
3249     + if (!ZEND_MM_VALID_PTR(p)) {
3250     + return;
3251     + }
3252     +
3253     + mm_block = ZEND_MM_HEADER_OF(p);
3254     + size = ZEND_MM_BLOCK_SIZE(mm_block);
3255     +#if SUHOSIN_PATCH
3256     + SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()");
3257     +#endif
3258     + ZEND_MM_CHECK_PROTECTION(mm_block);
3259     +
3260     +#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
3261     + memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
3262     +#endif
3263     +#if SUHOSIN_PATCH
3264     + if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) {
3265     + memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size);
3266     + }
3267     +#endif
3268     +#if ZEND_MM_CACHE
3269     + if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
3270     + size_t index = ZEND_MM_BUCKET_INDEX(size);
3271     + zend_mm_free_block_canary **cache = &heap->cache[index];
3272     +
3273     + ((zend_mm_free_block_canary*)mm_block)->prev_free_block = *cache;
3274     + *cache = (zend_mm_free_block_canary*)SUHOSIN_MANGLE_PTR(mm_block);
3275     + heap->cached += size;
3276     + ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
3277     +#if ZEND_MM_CACHE_STAT
3278     + if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
3279     + heap->cache_stat[index].max_count = heap->cache_stat[index].count;
3280     + }
3281     +#endif
3282     + return;
3283     + }
3284     +#endif
3285     +
3286     + HANDLE_BLOCK_INTERRUPTIONS();
3287     +
3288     + heap->size -= size;
3289     +
3290     + next_block = ZEND_MM_BLOCK_AT(mm_block, size);
3291     + if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
3292     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
3293     + size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
3294     + }
3295     + if (ZEND_MM_PREV_BLOCK_IS_FREE(mm_block)) {
3296     + mm_block = ZEND_MM_PREV_BLOCK(mm_block);
3297     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) mm_block);
3298     + size += ZEND_MM_FREE_BLOCK_SIZE(mm_block);
3299     + }
3300     + if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
3301     + ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(mm_block, size))) {
3302     + zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE));
3303     + } else {
3304     + ZEND_MM_BLOCK(mm_block, ZEND_MM_FREE_BLOCK, size);
3305     + zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) mm_block);
3306     + }
3307     + HANDLE_UNBLOCK_INTERRUPTIONS();
3308     +}
3309     +
3310     +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)
3311     +{
3312     + zend_mm_block_canary *mm_block = ZEND_MM_HEADER_OF(p);
3313     + zend_mm_block_canary *next_block;
3314     + size_t true_size;
3315     + size_t orig_size;
3316     + void *ptr;
3317     +
3318     + if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
3319     + return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
3320     + }
3321     + mm_block = ZEND_MM_HEADER_OF(p);
3322     + true_size = ZEND_MM_TRUE_SIZE(size);
3323     + orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
3324     +#if SUHOSIN_PATCH
3325     + SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()");
3326     +#endif
3327     + ZEND_MM_CHECK_PROTECTION(mm_block);
3328     +
3329     + if (UNEXPECTED(true_size < size)) {
3330     + goto out_of_memory;
3331     + }
3332     +
3333     + if (true_size <= orig_size) {
3334     + size_t remaining_size = orig_size - true_size;
3335     +
3336     + if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
3337     + zend_mm_free_block_canary *new_free_block;
3338     +
3339     + HANDLE_BLOCK_INTERRUPTIONS();
3340     + next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
3341     + if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
3342     + remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
3343     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
3344     + }
3345     +
3346     + /* prepare new free block */
3347     + ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
3348     + new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
3349     +
3350     + ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
3351     +
3352     + /* add the new free block to the free list */
3353     + zend_mm_add_to_free_list(heap, new_free_block);
3354     + heap->size += (true_size - orig_size);
3355     + HANDLE_UNBLOCK_INTERRUPTIONS();
3356     + }
3357     + ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
3358     +#if SUHOSIN_PATCH
3359     + SUHOSIN_MM_SET_CANARIES(mm_block);
3360     + ((zend_mm_block_canary*)mm_block)->info.size = size;
3361     + SUHOSIN_MM_SET_END_CANARY(mm_block);
3362     +#endif
3363     + return p;
3364     + }
3365     +
3366     +#if ZEND_MM_CACHE
3367     + if (ZEND_MM_SMALL_SIZE(true_size)) {
3368     + size_t index = ZEND_MM_BUCKET_INDEX(true_size);
3369     +
3370     + if (heap->cache[index] != NULL) {
3371     + zend_mm_free_block_canary *best_fit;
3372     + zend_mm_free_block_canary **cache;
3373     +
3374     +#if ZEND_MM_CACHE_STAT
3375     + heap->cache_stat[index].count--;
3376     + heap->cache_stat[index].hit++;
3377     +#endif
3378     + best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
3379     + heap->cache[index] = best_fit->prev_free_block;
3380     + ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
3381     + ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
3382     +#if SUHOSIN_PATCH
3383     + SUHOSIN_MM_SET_CANARIES(best_fit);
3384     + ((zend_mm_block_canary*)best_fit)->info.size = size;
3385     + SUHOSIN_MM_SET_END_CANARY(best_fit);
3386     +#endif
3387     +
3388     + ptr = ZEND_MM_DATA_OF(best_fit);
3389     +
3390     +#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
3391     + memcpy(ptr, p, mm_block->debug.size);
3392     +#else
3393     + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
3394     +#endif
3395     +
3396     + heap->cached -= true_size - orig_size;
3397     +
3398     + index = ZEND_MM_BUCKET_INDEX(orig_size);
3399     + cache = &heap->cache[index];
3400     +
3401     + ((zend_mm_free_block_canary*)mm_block)->prev_free_block = *cache;
3402     + *cache = (zend_mm_free_block_canary*)SUHOSIN_MANGLE_PTR(mm_block);
3403     + ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
3404     +#if ZEND_MM_CACHE_STAT
3405     + if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
3406     + heap->cache_stat[index].max_count = heap->cache_stat[index].count;
3407     + }
3408     +#endif
3409     + return ptr;
3410     + }
3411     + }
3412     +#endif
3413     +
3414     + next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
3415     +
3416     + if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
3417     + ZEND_MM_CHECK_COOKIE(next_block);
3418     + ZEND_MM_CHECK_BLOCK_LINKAGE(next_block);
3419     + if (orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block) >= true_size) {
3420     + size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block);
3421     + size_t remaining_size = block_size - true_size;
3422     +
3423     + HANDLE_BLOCK_INTERRUPTIONS();
3424     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
3425     +
3426     + if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
3427     + true_size = block_size;
3428     + ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
3429     + } else {
3430     + zend_mm_free_block_canary *new_free_block;
3431     +
3432     + /* prepare new free block */
3433     + ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
3434     + new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
3435     + ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
3436     +
3437     + /* add the new free block to the free list */
3438     + if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
3439     + ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(new_free_block, remaining_size))) {
3440     + zend_mm_add_to_rest_list(heap, new_free_block);
3441     + } else {
3442     + zend_mm_add_to_free_list(heap, new_free_block);
3443     + }
3444     + }
3445     + ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
3446     + heap->size = heap->size + true_size - orig_size;
3447     + if (heap->peak < heap->size) {
3448     + heap->peak = heap->size;
3449     + }
3450     + HANDLE_UNBLOCK_INTERRUPTIONS();
3451     +#if SUHOSIN_PATCH
3452     + SUHOSIN_MM_SET_CANARIES(mm_block);
3453     + ((zend_mm_block_canary*)mm_block)->info.size = size;
3454     + SUHOSIN_MM_SET_END_CANARY(mm_block);
3455     +#endif
3456     + return p;
3457     + } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
3458     + ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
3459     + HANDLE_BLOCK_INTERRUPTIONS();
3460     + zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
3461     + goto realloc_segment;
3462     + }
3463     + } else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) && ZEND_MM_IS_GUARD_BLOCK(next_block)) {
3464     + zend_mm_segment *segment;
3465     + zend_mm_segment *segment_copy;
3466     + size_t segment_size;
3467     + size_t block_size;
3468     + size_t remaining_size;
3469     +
3470     + HANDLE_BLOCK_INTERRUPTIONS();
3471     +realloc_segment:
3472     + /* segment size, size of block and size of guard block */
3473     + if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
3474     + segment_size = true_size+ZEND_MM_ALIGNED_SEGMENT_SIZE+ZEND_MM_ALIGNED_HEADER_SIZE;
3475     + segment_size = (segment_size + (heap->block_size-1)) & ~(heap->block_size-1);
3476     + } else {
3477     + segment_size = heap->block_size;
3478     + }
3479     +
3480     + segment_copy = (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE);
3481     + if (segment_size < true_size ||
3482     + heap->real_size + segment_size - segment_copy->size > heap->limit) {
3483     + if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
3484     + zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) next_block);
3485     + }
3486     +#if ZEND_MM_CACHE
3487     + zend_mm_free_cache(heap);
3488     +#endif
3489     + HANDLE_UNBLOCK_INTERRUPTIONS();
3490     +#if ZEND_DEBUG
3491     + zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted at %s:%d (tried to allocate %ld bytes)", heap->limit, __zend_filename, __zend_lineno, size);
3492     +#else
3493     + zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %ld bytes)", heap->limit, size);
3494     +#endif
3495     + return NULL;
3496     + }
3497     +
3498     + segment = ZEND_MM_STORAGE_REALLOC(segment_copy, segment_size);
3499     + if (!segment) {
3500     +#if ZEND_MM_CACHE
3501     + zend_mm_free_cache(heap);
3502     +#endif
3503     + HANDLE_UNBLOCK_INTERRUPTIONS();
3504     +out_of_memory:
3505     +#if ZEND_DEBUG
3506     + 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);
3507     +#else
3508     + zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %ld bytes)", heap->real_size, size);
3509     +#endif
3510     + return NULL;
3511     + }
3512     + heap->real_size += segment_size - segment->size;
3513     + if (heap->real_size > heap->real_peak) {
3514     + heap->real_peak = heap->real_size;
3515     + }
3516     +
3517     + segment->size = segment_size;
3518     +
3519     + if (segment != segment_copy) {
3520     + zend_mm_segment **seg = &heap->segments_list;
3521     + while (*seg != segment_copy) {
3522     + seg = &(*seg)->next_segment;
3523     + }
3524     + *seg = segment;
3525     + mm_block = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
3526     + ZEND_MM_MARK_FIRST_BLOCK(mm_block);
3527     + }
3528     +
3529     + block_size = segment_size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE;
3530     + remaining_size = block_size - true_size;
3531     +
3532     + /* setup guard block */
3533     + ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(mm_block, block_size));
3534     +
3535     + if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
3536     + true_size = block_size;
3537     + ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
3538     + } else {
3539     + zend_mm_free_block_canary *new_free_block;
3540     +
3541     + /* prepare new free block */
3542     + ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
3543     + new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
3544     + ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
3545     +
3546     + /* add the new free block to the free list */
3547     + zend_mm_add_to_rest_list(heap, new_free_block);
3548     + }
3549     +
3550     + ZEND_MM_SET_DEBUG_INFO(mm_block, size, 1, 1);
3551     +
3552     + heap->size = heap->size + true_size - orig_size;
3553     + if (heap->peak < heap->size) {
3554     + heap->peak = heap->size;
3555     + }
3556     +
3557     + HANDLE_UNBLOCK_INTERRUPTIONS();
3558     +#if SUHOSIN_PATCH
3559     + SUHOSIN_MM_SET_CANARIES(mm_block);
3560     + ((zend_mm_block_canary*)mm_block)->info.size = size;
3561     + SUHOSIN_MM_SET_END_CANARY(mm_block);
3562     +#endif
3563     + return ZEND_MM_DATA_OF(mm_block);
3564     + }
3565     +
3566     + ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
3567     +#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
3568     + memcpy(ptr, p, mm_block->debug.size);
3569     +#else
3570     + memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
3571     +#endif
3572     + _zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
3573     + return ptr;
3574     +}
3575     +
3576     +ZEND_API size_t _zend_mm_block_size_canary(zend_mm_heap_canary *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
3577     +{
3578     + zend_mm_block_canary *mm_block;
3579     +
3580     + if (!ZEND_MM_VALID_PTR(p)) {
3581     + return 0;
3582     + }
3583     + mm_block = ZEND_MM_HEADER_OF(p);
3584     + ZEND_MM_CHECK_PROTECTION(mm_block);
3585     +#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
3586     + return mm_block->debug.size;
3587     +#else
3588     + return ZEND_MM_BLOCK_SIZE(mm_block);
3589     +#endif
3590     +}
3591     +
3592     +#if defined(__GNUC__) && defined(i386)
3593     +
3594     +static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
3595     +{
3596     + size_t res = nmemb;
3597     + unsigned long overflow = 0;
3598     +
3599     + __asm__ ("mull %3\n\taddl %4,%0\n\tadcl %1,%1"
3600     + : "=&a"(res), "=&d" (overflow)
3601     + : "%0"(res),
3602     + "rm"(size),
3603     + "rm"(offset));
3604     +
3605     + if (UNEXPECTED(overflow)) {
3606     + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
3607     + return 0;
3608     + }
3609     + return res;
3610     +}
3611     +
3612     +#elif defined(__GNUC__) && defined(__x86_64__)
3613     +
3614     +static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
3615     +{
3616     + size_t res = nmemb;
3617     + unsigned long overflow = 0;
3618     +
3619     + __asm__ ("mulq %3\n\taddq %4,%0\n\tadcq %1,%1"
3620     + : "=&a"(res), "=&d" (overflow)
3621     + : "%0"(res),
3622     + "rm"(size),
3623     + "rm"(offset));
3624     +
3625     + if (UNEXPECTED(overflow)) {
3626     + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
3627     + return 0;
3628     + }
3629     + return res;
3630     +}
3631     +
3632     +#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
3633     +
3634     +static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
3635     +{
3636     + zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
3637     +
3638     + if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
3639     + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
3640     + return 0;
3641     + }
3642     + return (size_t) res;
3643     +}
3644     +
3645     +#else
3646     +
3647     +static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
3648     +{
3649     + size_t res = nmemb * size + offset;
3650     + double _d = (double)nmemb * (double)size + (double)offset;
3651     + double _delta = (double)res - _d;
3652     +
3653     + if (UNEXPECTED((_d + _delta ) != _d)) {
3654     + zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
3655     + return 0;
3656     + }
3657     + return res;
3658     +}
3659     +#endif
3660     +
3661     +/*
3662     + * Local variables:
3663     + * tab-width: 4
3664     + * c-basic-offset: 4
3665     + * indent-tabs-mode: t
3666     + * End:
3667     + */
3668     +
3669     diff -Nura php-5.3.9/Zend/zend_canary.c suhosin-patch-5.3.9-0.9.10/Zend/zend_canary.c
3670     --- php-5.3.9/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
3671     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_canary.c 2012-01-11 19:29:07.000000000 +0100
3672     @@ -0,0 +1,66 @@
3673     +/*
3674     + +----------------------------------------------------------------------+
3675     + | Suhosin-Patch for PHP |
3676     + +----------------------------------------------------------------------+
3677     + | Copyright (c) 2004-2009 Stefan Esser |
3678     + +----------------------------------------------------------------------+
3679     + | This source file is subject to version 2.02 of the PHP license, |
3680     + | that is bundled with this package in the file LICENSE, and is |
3681     + | available at through the world-wide-web at |
3682     + | http://www.php.net/license/2_02.txt. |
3683     + | If you did not receive a copy of the PHP license and are unable to |
3684     + | obtain it through the world-wide-web, please send a note to |
3685     + | license@php.net so we can mail you a copy immediately. |
3686     + +----------------------------------------------------------------------+
3687     + | Author: Stefan Esser <stefan.esser@sektioneins.de> |
3688     + +----------------------------------------------------------------------+
3689     + */
3690     +/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
3691     +
3692     +#include "zend.h"
3693     +
3694     +#include <stdio.h>
3695     +#include <stdlib.h>
3696     +
3697     +
3698     +#if SUHOSIN_PATCH
3699     +
3700     +static size_t last_canary = 0x73625123;
3701     +
3702     +/* will be replaced later with more compatible method */
3703     +ZEND_API void zend_canary(void *buf, int len)
3704     +{
3705     + time_t t;
3706     + size_t canary;
3707     + int fd;
3708     +
3709     +#ifndef PHP_WIN32
3710     + fd = open("/dev/urandom", 0);
3711     + if (fd != -1) {
3712     + int r = read(fd, buf, len);
3713     + close(fd);
3714     + if (r == len) {
3715     + return;
3716     + }
3717     + }
3718     +#endif
3719     + /* not good but we never want to do this */
3720     + time(&t);
3721     + canary = *(unsigned int *)&t + getpid() << 16 + last_canary;
3722     + last_canary ^= (canary << 5) | (canary >> (32-5));
3723     + /* When we ensure full win32 compatibility in next version
3724     + we will replace this with the random number code from zend_alloc.c */
3725     + memcpy(buf, &canary, len);
3726     +}
3727     +
3728     +#endif
3729     +
3730     +
3731     +/*
3732     + * Local variables:
3733     + * tab-width: 4
3734     + * c-basic-offset: 4
3735     + * End:
3736     + * vim600: sw=4 ts=4 fdm=marker
3737     + * vim<600: sw=4 ts=4
3738     + */
3739     diff -Nura php-5.3.9/Zend/zend_compile.c suhosin-patch-5.3.9-0.9.10/Zend/zend_compile.c
3740     --- php-5.3.9/Zend/zend_compile.c 2012-01-01 14:15:04.000000000 +0100
3741     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_compile.c 2012-01-11 19:29:07.000000000 +0100
3742     @@ -73,6 +73,11 @@
3743     }
3744     /* }}} */
3745    
3746     +#if SUHOSIN_PATCH
3747     +void *suhosin_zend_destroy_property_info_internal = zend_destroy_property_info_internal;
3748     +void *suhosin_zend_destroy_property_info = zend_destroy_property_info;
3749     +#endif
3750     +
3751     static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */
3752     {
3753     char char_pos_buf[32];
3754     diff -Nura php-5.3.9/Zend/zend_compile.h suhosin-patch-5.3.9-0.9.10/Zend/zend_compile.h
3755     --- php-5.3.9/Zend/zend_compile.h 2012-01-01 14:15:04.000000000 +0100
3756     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_compile.h 2012-01-11 19:29:07.000000000 +0100
3757     @@ -607,6 +607,11 @@
3758     ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC);
3759     ZEND_API size_t zend_dirname(char *path, size_t len);
3760    
3761     +#if SUHOSIN_PATCH
3762     +extern void *suhosin_zend_destroy_property_info_internal;
3763     +extern void *suhosin_zend_destroy_property_info;
3764     +#endif
3765     +
3766     int zendlex(znode *zendlval TSRMLS_DC);
3767    
3768     /* BEGIN: OPCODES */
3769     diff -Nura php-5.3.9/Zend/zend_constants.c suhosin-patch-5.3.9-0.9.10/Zend/zend_constants.c
3770     --- php-5.3.9/Zend/zend_constants.c 2012-01-01 14:15:04.000000000 +0100
3771     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_constants.c 2012-01-11 19:29:07.000000000 +0100
3772     @@ -113,6 +113,76 @@
3773    
3774     REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
3775    
3776     +#if SUHOSIN_PATCH
3777     + REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
3778     + REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
3779     + REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
3780     + REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
3781     + REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
3782     + REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
3783     + REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
3784     + REGISTER_MAIN_LONG_CONSTANT("S_SESSION", S_SESSION, CONST_PERSISTENT | CONST_CS);
3785     + REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
3786     + REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
3787     + REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
3788     +
3789     + /* error levels */
3790     + REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
3791     + REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
3792     + REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
3793     + REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
3794     + REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
3795     + REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
3796     + REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
3797     + REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
3798     + /* facility: type of program logging the message */
3799     + REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
3800     + REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
3801     + REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
3802     + REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
3803     + REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
3804     + REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
3805     + REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
3806     +#ifdef LOG_NEWS
3807     + /* No LOG_NEWS on HP-UX */
3808     + REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
3809     +#endif
3810     +#ifdef LOG_UUCP
3811     + /* No LOG_UUCP on HP-UX */
3812     + REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
3813     +#endif
3814     +#ifdef LOG_CRON
3815     + /* apparently some systems don't have this one */
3816     + REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
3817     +#endif
3818     +#ifdef LOG_AUTHPRIV
3819     + /* AIX doesn't have LOG_AUTHPRIV */
3820     + REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
3821     +#endif
3822     +#ifndef PHP_WIN32
3823     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
3824     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
3825     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
3826     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
3827     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
3828     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
3829     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
3830     + REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
3831     +#endif
3832     + /* options */
3833     + REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
3834     + REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
3835     + REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
3836     + REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
3837     +#ifdef LOG_NOWAIT
3838     + REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
3839     +#endif
3840     +#ifdef LOG_PERROR
3841     + /* AIX doesn't have LOG_PERROR */
3842     + REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
3843     +#endif
3844     +#endif
3845     +
3846     REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
3847     REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
3848     /* true/false constants */
3849     diff -Nura php-5.3.9/Zend/zend_errors.h suhosin-patch-5.3.9-0.9.10/Zend/zend_errors.h
3850     --- php-5.3.9/Zend/zend_errors.h 2012-01-01 14:15:04.000000000 +0100
3851     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_errors.h 2012-01-11 19:29:07.000000000 +0100
3852     @@ -41,6 +41,20 @@
3853     #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED)
3854     #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
3855    
3856     +#if SUHOSIN_PATCH
3857     +#define S_MEMORY (1<<0L)
3858     +#define S_MISC (1<<1L)
3859     +#define S_VARS (1<<2L)
3860     +#define S_FILES (1<<3L)
3861     +#define S_INCLUDE (1<<4L)
3862     +#define S_SQL (1<<5L)
3863     +#define S_EXECUTOR (1<<6L)
3864     +#define S_MAIL (1<<7L)
3865     +#define S_SESSION (1<<8L)
3866     +#define S_INTERNAL (1<<29L)
3867     +#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_SESSION | S_MISC | S_SQL | S_EXECUTOR)
3868     +#endif
3869     +
3870     #endif /* ZEND_ERRORS_H */
3871    
3872     /*
3873     diff -Nura php-5.3.9/Zend/zend_hash.c suhosin-patch-5.3.9-0.9.10/Zend/zend_hash.c
3874     --- php-5.3.9/Zend/zend_hash.c 2012-01-01 14:15:04.000000000 +0100
3875     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_hash.c 2012-01-11 19:29:07.000000000 +0100
3876     @@ -20,6 +20,7 @@
3877     /* $Id: zend_hash.c 321634 2012-01-01 13:15:04Z felipe $ */
3878    
3879     #include "zend.h"
3880     +#include "zend_compile.h"
3881    
3882     #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
3883     (element)->pNext = (list_head); \
3884     @@ -136,6 +137,199 @@
3885     }
3886    
3887    
3888     +#if SUHOSIN_PATCH
3889     +#ifdef ZTS
3890     +static MUTEX_T zend_hash_dprot_mx_reader;
3891     +static MUTEX_T zend_hash_dprot_mx_writer;
3892     +static unsigned int zend_hash_dprot_reader;
3893     +#endif
3894     +static unsigned int zend_hash_dprot_counter;
3895     +static unsigned int zend_hash_dprot_curmax;
3896     +static dtor_func_t *zend_hash_dprot_table = NULL;
3897     +
3898     +static void zend_hash_dprot_begin_read()
3899     +{
3900     +#ifdef ZTS
3901     + tsrm_mutex_lock(zend_hash_dprot_mx_reader);
3902     + if ((++(zend_hash_dprot_reader)) == 1) {
3903     + tsrm_mutex_lock(zend_hash_dprot_mx_writer);
3904     + }
3905     + tsrm_mutex_unlock(zend_hash_dprot_mx_reader);
3906     +#endif
3907     +}
3908     +
3909     +static void zend_hash_dprot_end_read()
3910     +{
3911     +#ifdef ZTS
3912     + tsrm_mutex_lock(zend_hash_dprot_mx_reader);
3913     + if ((--(zend_hash_dprot_reader)) == 0) {
3914     + tsrm_mutex_unlock(zend_hash_dprot_mx_writer);
3915     + }
3916     + tsrm_mutex_unlock(zend_hash_dprot_mx_reader);
3917     +#endif
3918     +}
3919     +
3920     +static void zend_hash_dprot_begin_write()
3921     +{
3922     +#ifdef ZTS
3923     + tsrm_mutex_lock(zend_hash_dprot_mx_writer);
3924     +#endif
3925     +}
3926     +
3927     +static void zend_hash_dprot_end_write()
3928     +{
3929     +#ifdef ZTS
3930     + tsrm_mutex_unlock(zend_hash_dprot_mx_writer);
3931     +#endif
3932     +}
3933     +
3934     +/*ZEND_API void zend_hash_dprot_dtor()
3935     +{
3936     +#ifdef ZTS
3937     + tsrm_mutex_free(zend_hash_dprot_mx_reader);
3938     + tsrm_mutex_free(zend_hash_dprot_mx_writer);
3939     +#endif
3940     + free(zend_hash_dprot_table);
3941     +}*/
3942     +
3943     +static void zend_hash_add_destructor(dtor_func_t pDestructor)
3944     +{
3945     + int left, right, mid;
3946     + zend_bool found = 0;
3947     + unsigned long value;
3948     +
3949     + if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR || pDestructor == ZVAL_INTERNAL_PTR_DTOR
3950     + || pDestructor == ZEND_FUNCTION_DTOR || pDestructor == ZEND_CLASS_DTOR) {
3951     + return;
3952     + }
3953     +
3954     + if (zend_hash_dprot_table == NULL) {
3955     +#ifdef ZTS
3956     + zend_hash_dprot_mx_reader = tsrm_mutex_alloc();
3957     + zend_hash_dprot_mx_writer = tsrm_mutex_alloc();
3958     + zend_hash_dprot_reader = 0;
3959     +#endif
3960     + zend_hash_dprot_counter = 0;
3961     + zend_hash_dprot_curmax = 256;
3962     + zend_hash_dprot_table = (dtor_func_t *) malloc(256 * sizeof(dtor_func_t));
3963     + }
3964     +
3965     + zend_hash_dprot_begin_write();
3966     +
3967     + if (zend_hash_dprot_counter == 0) {
3968     + zend_hash_dprot_counter++;
3969     + zend_hash_dprot_table[0] = pDestructor;
3970     + } else {
3971     + value = (unsigned long) pDestructor;
3972     + left = 0;
3973     + right = zend_hash_dprot_counter-1;
3974     + mid = 0;
3975     +
3976     + while (left < right) {
3977     + mid = (right - left) >> 1;
3978     + mid += left;
3979     + if ((unsigned long)zend_hash_dprot_table[mid] == value) {
3980     + found = 1;
3981     + break;
3982     + }
3983     + if (value < (unsigned long)zend_hash_dprot_table[mid]) {
3984     + right = mid-1;
3985     + } else {
3986     + left = mid+1;
3987     + }
3988     + }
3989     + if ((unsigned long)zend_hash_dprot_table[left] == value) {
3990     + found = 1;
3991     + }
3992     +
3993     + if (!found) {
3994     +
3995     + if (zend_hash_dprot_counter >= zend_hash_dprot_curmax) {
3996     + zend_hash_dprot_curmax += 256;
3997     + zend_hash_dprot_table = (dtor_func_t *) realloc(zend_hash_dprot_table, zend_hash_dprot_curmax * sizeof(dtor_func_t));
3998     + }
3999     +
4000     + if ((unsigned long)zend_hash_dprot_table[left] < value) {
4001     + memmove(zend_hash_dprot_table+left+2, zend_hash_dprot_table+left+1, (zend_hash_dprot_counter-left-1)*sizeof(dtor_func_t));
4002     + zend_hash_dprot_table[left+1] = pDestructor;
4003     + } else {
4004     + memmove(zend_hash_dprot_table+left+1, zend_hash_dprot_table+left, (zend_hash_dprot_counter-left)*sizeof(dtor_func_t));
4005     + zend_hash_dprot_table[left] = pDestructor;
4006     + }
4007     +
4008     + zend_hash_dprot_counter++;
4009     + }
4010     + }
4011     +
4012     + zend_hash_dprot_end_write();
4013     +}
4014     +
4015     +static void zend_hash_check_destructor(dtor_func_t pDestructor)
4016     +{
4017     + unsigned long value;
4018     +
4019     + if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR || pDestructor == ZVAL_INTERNAL_PTR_DTOR
4020     +#ifdef ZEND_ENGINE_2
4021     + || pDestructor == suhosin_zend_destroy_property_info_internal || pDestructor == suhosin_zend_destroy_property_info
4022     +#endif
4023     + || pDestructor == ZEND_FUNCTION_DTOR || pDestructor == ZEND_CLASS_DTOR) {
4024     + return;
4025     + }
4026     +
4027     + zend_hash_dprot_begin_read();
4028     +
4029     + if (zend_hash_dprot_counter > 0) {
4030     + int left, right, mid;
4031     + zend_bool found = 0;
4032     +
4033     + value = (unsigned long) pDestructor;
4034     + left = 0;
4035     + right = zend_hash_dprot_counter-1;
4036     +
4037     + while (left < right) {
4038     + mid = (right - left) >> 1;
4039     + mid += left;
4040     + if ((unsigned long)zend_hash_dprot_table[mid] == value) {
4041     + found = 1;
4042     + break;
4043     + }
4044     + if (value < (unsigned long)zend_hash_dprot_table[mid]) {
4045     + right = mid-1;
4046     + } else {
4047     + left = mid+1;
4048     + }
4049     + }
4050     + if ((unsigned long)zend_hash_dprot_table[left] == value) {
4051     + found = 1;
4052     + }
4053     +
4054     + if (!found) {
4055     + zend_hash_dprot_end_read();
4056     +
4057     + zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown Hashtable destructor");
4058     + if (SUHOSIN_CONFIG(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR) == 0) {
4059     + _exit(1);
4060     + }
4061     + return;
4062     + }
4063     +
4064     + } else {
4065     + zend_hash_dprot_end_read();
4066     +
4067     + zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown Hashtable destructor");
4068     + if (SUHOSIN_CONFIG(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR) == 0) {
4069     + _exit(1);
4070     + }
4071     + return;
4072     + }
4073     +
4074     + zend_hash_dprot_end_read();
4075     +}
4076     +
4077     +#else
4078     +#define zend_hash_add_destructor(pDestructor) do {} while(0)
4079     +#define zend_hash_check_destructor(pDestructor) do {} while(0)
4080     +#endif
4081    
4082     ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
4083     {
4084     @@ -156,6 +350,7 @@
4085    
4086     ht->nTableMask = ht->nTableSize - 1;
4087     ht->pDestructor = pDestructor;
4088     + zend_hash_add_destructor(pDestructor);
4089     ht->arBuckets = NULL;
4090     ht->pListHead = NULL;
4091     ht->pListTail = NULL;
4092     @@ -233,6 +428,7 @@
4093     return FAILURE;
4094     }
4095     #endif
4096     + zend_hash_check_destructor(ht->pDestructor);
4097     if (ht->pDestructor) {
4098     ht->pDestructor(p->pData);
4099     }
4100     @@ -298,6 +494,7 @@
4101     return FAILURE;
4102     }
4103     #endif
4104     + zend_hash_check_destructor(ht->pDestructor);
4105     if (ht->pDestructor) {
4106     ht->pDestructor(p->pData);
4107     }
4108     @@ -373,6 +570,7 @@
4109     return FAILURE;
4110     }
4111     #endif
4112     + zend_hash_check_destructor(ht->pDestructor);
4113     if (ht->pDestructor) {
4114     ht->pDestructor(p->pData);
4115     }
4116     @@ -496,6 +694,7 @@
4117     if (ht->pInternalPointer == p) {
4118     ht->pInternalPointer = p->pListNext;
4119     }
4120     + zend_hash_check_destructor(ht->pDestructor);
4121     if (ht->pDestructor) {
4122     ht->pDestructor(p->pData);
4123     }
4124     @@ -522,6 +721,7 @@
4125     SET_INCONSISTENT(HT_IS_DESTROYING);
4126    
4127     p = ht->pListHead;
4128     + zend_hash_check_destructor(ht->pDestructor);
4129     while (p != NULL) {
4130     q = p;
4131     p = p->pListNext;
4132     @@ -554,6 +754,7 @@
4133     ht->nNextFreeElement = 0;
4134     ht->pInternalPointer = NULL;
4135    
4136     + zend_hash_check_destructor(ht->pDestructor);
4137     while (p != NULL) {
4138     q = p;
4139     p = p->pListNext;
4140     @@ -608,6 +809,7 @@
4141     ht->nNumOfElements--;
4142     HANDLE_UNBLOCK_INTERRUPTIONS();
4143    
4144     + zend_hash_check_destructor(ht->pDestructor);
4145     if (ht->pDestructor) {
4146     ht->pDestructor(p->pData);
4147     }
4148     @@ -628,6 +830,7 @@
4149     IS_CONSISTENT(ht);
4150    
4151     p = ht->pListHead;
4152     + zend_hash_check_destructor(ht->pDestructor);
4153     while (p != NULL) {
4154     p = zend_hash_apply_deleter(ht, p);
4155     }
4156     @@ -1180,6 +1383,7 @@
4157    
4158     IS_CONSISTENT(ht);
4159    
4160     + zend_hash_check_destructor(ht->pDestructor);
4161     if (p) {
4162     if (key_type == HASH_KEY_IS_LONG) {
4163     str_length = 0;
4164     diff -Nura php-5.3.9/Zend/zend_llist.c suhosin-patch-5.3.9-0.9.10/Zend/zend_llist.c
4165     --- php-5.3.9/Zend/zend_llist.c 2012-01-01 14:15:04.000000000 +0100
4166     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_llist.c 2012-01-11 19:29:07.000000000 +0100
4167     @@ -23,6 +23,194 @@
4168     #include "zend_llist.h"
4169     #include "zend_qsort.h"
4170    
4171     +#if SUHOSIN_PATCH
4172     +#ifdef ZTS
4173     +static MUTEX_T zend_llist_dprot_mx_reader;
4174     +static MUTEX_T zend_llist_dprot_mx_writer;
4175     +static unsigned int zend_llist_dprot_reader;
4176     +#endif
4177     +static unsigned int zend_llist_dprot_counter;
4178     +static unsigned int zend_llist_dprot_curmax;
4179     +static llist_dtor_func_t *zend_llist_dprot_table = NULL;
4180     +
4181     +static void zend_llist_dprot_begin_read()
4182     +{
4183     +#ifdef ZTS
4184     + tsrm_mutex_lock(zend_llist_dprot_mx_reader);
4185     + if ((++(zend_llist_dprot_reader)) == 1) {
4186     + tsrm_mutex_lock(zend_llist_dprot_mx_writer);
4187     + }
4188     + tsrm_mutex_unlock(zend_llist_dprot_mx_reader);
4189     +#endif
4190     +}
4191     +
4192     +static void zend_llist_dprot_end_read()
4193     +{
4194     +#ifdef ZTS
4195     + tsrm_mutex_lock(zend_llist_dprot_mx_reader);
4196     + if ((--(zend_llist_dprot_reader)) == 0) {
4197     + tsrm_mutex_unlock(zend_llist_dprot_mx_writer);
4198     + }
4199     + tsrm_mutex_unlock(zend_llist_dprot_mx_reader);
4200     +#endif
4201     +}
4202     +
4203     +static void zend_llist_dprot_begin_write()
4204     +{
4205     +#ifdef ZTS
4206     + tsrm_mutex_lock(zend_llist_dprot_mx_writer);
4207     +#endif
4208     +}
4209     +
4210     +static void zend_llist_dprot_end_write()
4211     +{
4212     +#ifdef ZTS
4213     + tsrm_mutex_unlock(zend_llist_dprot_mx_writer);
4214     +#endif
4215     +}
4216     +
4217     +/*ZEND_API void zend_llist_dprot_dtor()
4218     +{
4219     +#ifdef ZTS
4220     + tsrm_mutex_free(zend_llist_dprot_mx_reader);
4221     + tsrm_mutex_free(zend_llist_dprot_mx_writer);
4222     +#endif
4223     + free(zend_llist_dprot_table);
4224     +}*/
4225     +
4226     +static void zend_llist_add_destructor(llist_dtor_func_t pDestructor)
4227     +{
4228     + int left, right, mid;
4229     + zend_bool found = 0;
4230     + unsigned long value;
4231     +
4232     + if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR) {
4233     + return;
4234     + }
4235     +
4236     + if (zend_llist_dprot_table == NULL) {
4237     +#ifdef ZTS
4238     + zend_llist_dprot_mx_reader = tsrm_mutex_alloc();
4239     + zend_llist_dprot_mx_writer = tsrm_mutex_alloc();
4240     + zend_llist_dprot_reader = 0;
4241     +#endif
4242     + zend_llist_dprot_counter = 0;
4243     + zend_llist_dprot_curmax = 256;
4244     + zend_llist_dprot_table = (llist_dtor_func_t *) malloc(256 * sizeof(llist_dtor_func_t));
4245     + }
4246     +
4247     + zend_llist_dprot_begin_write();
4248     +
4249     + if (zend_llist_dprot_counter == 0) {
4250     + zend_llist_dprot_counter++;
4251     + zend_llist_dprot_table[0] = pDestructor;
4252     + } else {
4253     + value = (unsigned long) pDestructor;
4254     + left = 0;
4255     + right = zend_llist_dprot_counter-1;
4256     + mid = 0;
4257     +
4258     + while (left < right) {
4259     + mid = (right - left) >> 1;
4260     + mid += left;
4261     + if ((unsigned long)zend_llist_dprot_table[mid] == value) {
4262     + found = 1;
4263     + break;
4264     + }
4265     + if (value < (unsigned long)zend_llist_dprot_table[mid]) {
4266     + right = mid-1;
4267     + } else {
4268     + left = mid+1;
4269     + }
4270     + }
4271     + if ((unsigned long)zend_llist_dprot_table[left] == value) {
4272     + found = 1;
4273     + }
4274     +
4275     + if (!found) {
4276     +
4277     + if (zend_llist_dprot_counter >= zend_llist_dprot_curmax) {
4278     + zend_llist_dprot_curmax += 256;
4279     + zend_llist_dprot_table = (llist_dtor_func_t *) realloc(zend_llist_dprot_table, zend_llist_dprot_curmax * sizeof(llist_dtor_func_t));
4280     + }
4281     +
4282     + if ((unsigned long)zend_llist_dprot_table[left] < value) {
4283     + memmove(zend_llist_dprot_table+left+2, zend_llist_dprot_table+left+1, (zend_llist_dprot_counter-left-1)*sizeof(llist_dtor_func_t));
4284     + zend_llist_dprot_table[left+1] = pDestructor;
4285     + } else {
4286     + memmove(zend_llist_dprot_table+left+1, zend_llist_dprot_table+left, (zend_llist_dprot_counter-left)*sizeof(llist_dtor_func_t));
4287     + zend_llist_dprot_table[left] = pDestructor;
4288     + }
4289     +
4290     + zend_llist_dprot_counter++;
4291     + }
4292     + }
4293     +
4294     + zend_llist_dprot_end_write();
4295     +}
4296     +
4297     +static void zend_llist_check_destructor(llist_dtor_func_t pDestructor)
4298     +{
4299     + unsigned long value;
4300     +
4301     + if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR) {
4302     + return;
4303     + }
4304     +
4305     + zend_llist_dprot_begin_read();
4306     +
4307     + if (zend_llist_dprot_counter > 0) {
4308     + int left, right, mid;
4309     + zend_bool found = 0;
4310     +
4311     + value = (unsigned long) pDestructor;
4312     + left = 0;
4313     + right = zend_llist_dprot_counter-1;
4314     +
4315     + while (left < right) {
4316     + mid = (right - left) >> 1;
4317     + mid += left;
4318     + if ((unsigned long)zend_llist_dprot_table[mid] == value) {
4319     + found = 1;
4320     + break;
4321     + }
4322     + if (value < (unsigned long)zend_llist_dprot_table[mid]) {
4323     + right = mid-1;
4324     + } else {
4325     + left = mid+1;
4326     + }
4327     + }
4328     + if ((unsigned long)zend_llist_dprot_table[left] == value) {
4329     + found = 1;
4330     + }
4331     +
4332     + if (!found) {
4333     + zend_llist_dprot_end_read();
4334     +
4335     + zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown llist destructor");
4336     + if (SUHOSIN_CONFIG(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR) == 0) {
4337     + _exit(1);
4338     + }
4339     + return;
4340     + }
4341     +
4342     + } else {
4343     + zend_llist_dprot_end_read();
4344     +
4345     + zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown llist destructor");
4346     + if (SUHOSIN_CONFIG(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR) == 0) {
4347     + _exit(1);
4348     + }
4349     + return;
4350     + }
4351     +
4352     + zend_llist_dprot_end_read();
4353     +}
4354     +#else
4355     +#define zend_llist_add_destructor(pDestructor) do {} while(0)
4356     +#define zend_llist_check_destructor(pDestructor) do {} while(0)
4357     +#endif
4358     +
4359     ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
4360     {
4361     l->head = NULL;
4362     @@ -30,6 +218,7 @@
4363     l->count = 0;
4364     l->size = size;
4365     l->dtor = dtor;
4366     + zend_llist_add_destructor(dtor);
4367     l->persistent = persistent;
4368     }
4369    
4370     @@ -81,6 +270,7 @@
4371     } else {\
4372     (l)->tail = (current)->prev;\
4373     }\
4374     + zend_llist_check_destructor((l)->dtor); \
4375     if ((l)->dtor) {\
4376     (l)->dtor((current)->data);\
4377     }\
4378     @@ -108,6 +298,7 @@
4379     {
4380     zend_llist_element *current=l->head, *next;
4381    
4382     + zend_llist_check_destructor(l->dtor);
4383     while (current) {
4384     next = current->next;
4385     if (l->dtor) {
4386     @@ -133,6 +324,7 @@
4387     zend_llist_element *old_tail;
4388     void *data;
4389    
4390     + zend_llist_check_destructor((l)->dtor);
4391     if ((old_tail = l->tail)) {
4392     if (old_tail->prev) {
4393     old_tail->prev->next = NULL;
4394     diff -Nura php-5.3.9/Zend/zend_operators.c suhosin-patch-5.3.9-0.9.10/Zend/zend_operators.c
4395     --- php-5.3.9/Zend/zend_operators.c 2012-01-01 14:15:04.000000000 +0100
4396     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_operators.c 2012-01-11 19:29:07.000000000 +0100
4397     @@ -153,9 +153,14 @@
4398     case IS_STRING:
4399     {
4400     char *strval;
4401     + int strl;
4402    
4403     strval = Z_STRVAL_P(op);
4404     - if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
4405     + strl = Z_STRLEN_P(op);
4406     +#if SUHOSIN_PATCH
4407     + Z_STRLEN_P(op) = 0;
4408     +#endif
4409     + if ((Z_TYPE_P(op)=is_numeric_string(strval, strl, &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
4410     ZVAL_LONG(op, 0);
4411     }
4412     STR_FREE(strval);
4413     @@ -187,7 +192,8 @@
4414     } else { \
4415     switch (Z_TYPE_P(op)) { \
4416     case IS_STRING: \
4417     - { \
4418     + { \
4419     + Z_STRLEN(holder) = 0; \
4420     if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) { \
4421     ZVAL_LONG(&(holder), 0); \
4422     } \
4423     @@ -229,6 +235,7 @@
4424     Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op)); \
4425     break; \
4426     case IS_STRING: \
4427     + Z_STRLEN(holder) = 0; \
4428     Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10); \
4429     break; \
4430     case IS_ARRAY: \
4431     @@ -271,6 +278,7 @@
4432     Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0); \
4433     break; \
4434     case IS_STRING: \
4435     + Z_STRLEN(holder) = 0; \
4436     if (Z_STRLEN_P(op) == 0 \
4437     || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { \
4438     Z_LVAL(holder) = 0; \
4439     @@ -356,6 +364,9 @@
4440     {
4441     char *strval = Z_STRVAL_P(op);
4442    
4443     +#if SUHOSIN_PATCH
4444     + Z_STRLEN_P(op) = 0;
4445     +#endif
4446     Z_LVAL_P(op) = strtol(strval, NULL, base);
4447     STR_FREE(strval);
4448     }
4449     @@ -416,6 +427,9 @@
4450     {
4451     char *strval = Z_STRVAL_P(op);
4452    
4453     +#if SUHOSIN_PATCH
4454     + Z_STRLEN_P(op) = 0;
4455     +#endif
4456     Z_DVAL_P(op) = zend_strtod(strval, NULL);
4457     STR_FREE(strval);
4458     }
4459     @@ -502,8 +516,14 @@
4460    
4461     if (Z_STRLEN_P(op) == 0
4462     || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
4463     +#if SUHOSIN_PATCH
4464     + Z_STRLEN_P(op) = 0;
4465     +#endif
4466     Z_LVAL_P(op) = 0;
4467     } else {
4468     +#if SUHOSIN_PATCH
4469     + Z_STRLEN_P(op) = 0;
4470     +#endif
4471     Z_LVAL_P(op) = 1;
4472     }
4473     STR_FREE(strval);
4474     @@ -617,6 +637,9 @@
4475     *entry = *op;
4476     INIT_PZVAL(entry);
4477    
4478     +#if SUHOSIN_PATCH
4479     + Z_STRLEN_P(op) = 0;
4480     +#endif
4481     switch (type) {
4482     case IS_ARRAY:
4483     ALLOC_HASHTABLE(Z_ARRVAL_P(op));
4484     diff -Nura php-5.3.9/Zend/zend_variables.c suhosin-patch-5.3.9-0.9.10/Zend/zend_variables.c
4485     --- php-5.3.9/Zend/zend_variables.c 2012-01-01 14:15:04.000000000 +0100
4486     +++ suhosin-patch-5.3.9-0.9.10/Zend/zend_variables.c 2012-01-11 19:29:07.000000000 +0100
4487     @@ -34,6 +34,9 @@
4488     case IS_CONSTANT:
4489     CHECK_ZVAL_STRING_REL(zvalue);
4490     STR_FREE_REL(zvalue->value.str.val);
4491     +#if SUHOSIN_PATCH
4492     + zvalue->value.str.len = 0;
4493     +#endif
4494     break;
4495     case IS_ARRAY:
4496     case IS_CONSTANT_ARRAY: {
4497     @@ -78,6 +81,9 @@
4498     case IS_CONSTANT:
4499     CHECK_ZVAL_STRING_REL(zvalue);
4500     free(zvalue->value.str.val);
4501     +#if SUHOSIN_PATCH
4502     + zvalue->value.str.len = 0;
4503     +#endif
4504     break;
4505     case IS_ARRAY:
4506     case IS_CONSTANT_ARRAY:
4507     diff -Nura php-5.3.9/configure suhosin-patch-5.3.9-0.9.10/configure
4508     --- php-5.3.9/configure 2012-01-10 14:37:04.000000000 +0100
4509     +++ suhosin-patch-5.3.9-0.9.10/configure 2012-01-11 19:29:07.000000000 +0100
4510     @@ -19371,6 +19371,9 @@
4511    
4512     fi
4513    
4514     +cat >> confdefs.h <<\EOF
4515     +#define SUHOSIN_PATCH 1
4516     +EOF
4517    
4518     echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
4519     echo "configure:19377: checking for declared timezone" >&5
4520     @@ -115830,7 +115833,7 @@
4521     php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
4522     strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
4523     network.c php_open_temporary_file.c php_logos.c \
4524     - output.c getopt.c; do
4525     + output.c getopt.c suhosin_patch.c ; do
4526    
4527     IFS=.
4528     set $ac_src
4529     @@ -116034,7 +116037,7 @@
4530     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
4531     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
4532     zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
4533     - zend_closures.c zend_float.c; do
4534     + zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c ; do
4535    
4536     IFS=.
4537     set $ac_src
4538     diff -Nura php-5.3.9/configure.in suhosin-patch-5.3.9-0.9.10/configure.in
4539     --- php-5.3.9/configure.in 2012-01-10 12:21:57.000000000 +0100
4540     +++ suhosin-patch-5.3.9-0.9.10/configure.in 2012-01-11 19:29:07.000000000 +0100
4541     @@ -289,6 +289,7 @@
4542     sinclude(TSRM/threads.m4)
4543     sinclude(TSRM/tsrm.m4)
4544    
4545     +sinclude(main/suhosin_patch.m4)
4546    
4547     divert(2)
4548    
4549     @@ -1406,7 +1407,7 @@
4550     php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
4551     strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
4552     network.c php_open_temporary_file.c php_logos.c \
4553     - output.c getopt.c)
4554     + output.c getopt.c suhosin_patch.c )
4555    
4556     PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
4557     plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c \
4558     @@ -1434,7 +1435,7 @@
4559     zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
4560     zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
4561     zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
4562     - zend_closures.c zend_float.c)
4563     + zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c )
4564    
4565     if test -r "$abs_srcdir/Zend/zend_objects.c"; then
4566     PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
4567     diff -Nura php-5.3.9/ext/standard/dl.c suhosin-patch-5.3.9-0.9.10/ext/standard/dl.c
4568     --- php-5.3.9/ext/standard/dl.c 2012-01-01 14:15:04.000000000 +0100
4569     +++ suhosin-patch-5.3.9-0.9.10/ext/standard/dl.c 2012-01-11 19:29:07.000000000 +0100
4570     @@ -254,6 +254,23 @@
4571     return FAILURE;
4572     }
4573     }
4574     +
4575     +#if SUHOSIN_PATCH
4576     + if (strncmp("suhosin", module_entry->name, sizeof("suhosin")-1) == 0) {
4577     + void *log_func;
4578     + /* sucessfully loaded suhosin extension, now check for logging function replacement */
4579     + log_func = (void *) DL_FETCH_SYMBOL(handle, "suhosin_log");
4580     + if (log_func == NULL) {
4581     + log_func = (void *) DL_FETCH_SYMBOL(handle, "_suhosin_log");
4582     + }
4583     + if (log_func != NULL) {
4584     + zend_suhosin_log = log_func;
4585     + } else {
4586     + zend_suhosin_log(S_MISC, "could not replace logging function");
4587     + }
4588     + }
4589     +#endif
4590     +
4591     return SUCCESS;
4592     }
4593     /* }}} */
4594     diff -Nura php-5.3.9/ext/standard/info.c suhosin-patch-5.3.9-0.9.10/ext/standard/info.c
4595     --- php-5.3.9/ext/standard/info.c 2012-01-01 14:15:04.000000000 +0100
4596     +++ suhosin-patch-5.3.9-0.9.10/ext/standard/info.c 2012-01-11 22:54:58.000000000 +0100
4597     @@ -878,6 +878,33 @@
4598    
4599     php_info_print_table_end();
4600    
4601     + /* Suhosin Patch */
4602     + php_info_print_box_start(0);
4603     + if (expose_php && !sapi_module.phpinfo_as_text) {
4604     + PUTS("<a href=\"http://www.suhosin.org\"><img border=\"0\" src=\"");
4605     + if (SG(request_info).request_uri) {
4606     + char *elem_esc = php_info_html_esc(SG(request_info).request_uri TSRMLS_CC);
4607     + PUTS(elem_esc);
4608     + efree(elem_esc);
4609     + }
4610     + PUTS("?="SUHOSIN_LOGO_GUID"\" alt=\"Suhosin logo\" /></a>\n");
4611     + }
4612     + PUTS("This server is protected with the Suhosin Patch ");
4613     + if (sapi_module.phpinfo_as_text) {
4614     + PUTS(SUHOSIN_PATCH_VERSION);
4615     + } else {
4616     + zend_html_puts(SUHOSIN_PATCH_VERSION, strlen(SUHOSIN_PATCH_VERSION) TSRMLS_CC);
4617     + }
4618     + PUTS(!sapi_module.phpinfo_as_text?"<br />":"\n");
4619     + if (sapi_module.phpinfo_as_text) {
4620     + PUTS("Copyright (c) 2006-2007 Hardened-PHP Project\n");
4621     + PUTS("Copyright (c) 2007-2012 SektionEins GmbH\n");
4622     + } else {
4623     + PUTS("Copyright (c) 2006-2007 <a href=\"http://www.hardened-php.net/\">Hardened-PHP Project</a>\n");
4624     + PUTS("Copyright (c) 2007-2012 <a href=\"http://www.sektioneins.de/\">SektionEins GmbH</a>\n");
4625     + }
4626     + php_info_print_box_end();
4627     +
4628     /* Zend Engine */
4629     php_info_print_box_start(0);
4630     if (expose_php && !sapi_module.phpinfo_as_text) {
4631     diff -Nura php-5.3.9/ext/standard/syslog.c suhosin-patch-5.3.9-0.9.10/ext/standard/syslog.c
4632     --- php-5.3.9/ext/standard/syslog.c 2012-01-01 14:15:04.000000000 +0100
4633     +++ suhosin-patch-5.3.9-0.9.10/ext/standard/syslog.c 2012-01-11 19:29:07.000000000 +0100
4634     @@ -42,6 +42,7 @@
4635     */
4636     PHP_MINIT_FUNCTION(syslog)
4637     {
4638     +#if !SUHOSIN_PATCH
4639     /* error levels */
4640     REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
4641     REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
4642     @@ -97,6 +98,7 @@
4643     /* AIX doesn't have LOG_PERROR */
4644     REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
4645     #endif
4646     +#endif
4647     BG(syslog_device)=NULL;
4648    
4649     return SUCCESS;
4650     diff -Nura php-5.3.9/main/fopen_wrappers.c suhosin-patch-5.3.9-0.9.10/main/fopen_wrappers.c
4651     --- php-5.3.9/main/fopen_wrappers.c 2012-01-01 14:15:04.000000000 +0100
4652     +++ suhosin-patch-5.3.9-0.9.10/main/fopen_wrappers.c 2012-01-11 19:29:07.000000000 +0100
4653     @@ -85,13 +85,8 @@
4654     PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
4655     {
4656     char **p, *pathbuf, *ptr, *end;
4657     -#ifndef ZTS
4658     - char *base = (char *) mh_arg2;
4659     -#else
4660     - char *base = (char *) ts_resource(*((int *) mh_arg2));
4661     -#endif
4662    
4663     - p = (char **) (base + (size_t) mh_arg1);
4664     + p = &PG(open_basedir);
4665    
4666     if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {
4667     /* We're in a PHP_INI_SYSTEM context, no restrictions */
4668     diff -Nura php-5.3.9/main/main.c suhosin-patch-5.3.9-0.9.10/main/main.c
4669     --- php-5.3.9/main/main.c 2012-01-01 14:15:04.000000000 +0100
4670     +++ suhosin-patch-5.3.9-0.9.10/main/main.c 2012-01-11 19:29:07.000000000 +0100
4671     @@ -91,6 +91,9 @@
4672    
4673     #include "SAPI.h"
4674     #include "rfc1867.h"
4675     +#if SUHOSIN_PATCH
4676     +#include "suhosin_globals.h"
4677     +#endif
4678    
4679     #if HAVE_MMAP
4680     # if HAVE_UNISTD_H
4681     @@ -504,7 +507,7 @@
4682     STD_PHP_INI_ENTRY("extension_dir", PHP_EXTENSION_DIR, PHP_INI_SYSTEM, OnUpdateStringUnempty, extension_dir, php_core_globals, core_globals)
4683     STD_PHP_INI_ENTRY("include_path", PHP_INCLUDE_PATH, PHP_INI_ALL, OnUpdateStringUnempty, include_path, php_core_globals, core_globals)
4684     PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout)
4685     - STD_PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_ALL, OnUpdateBaseDir, open_basedir, php_core_globals, core_globals)
4686     + PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_ALL, OnUpdateBaseDir)
4687     STD_PHP_INI_ENTRY("safe_mode_exec_dir", PHP_SAFE_MODE_EXEC_DIR, PHP_INI_SYSTEM, OnUpdateString, safe_mode_exec_dir, php_core_globals, core_globals)
4688    
4689     STD_PHP_INI_BOOLEAN("file_uploads", "1", PHP_INI_SYSTEM, OnUpdateBool, file_uploads, php_core_globals, core_globals)
4690     @@ -1810,6 +1813,10 @@
4691     }
4692     #endif
4693    
4694     +#if SUHOSIN_PATCH
4695     +PHPAPI void suhosin_startup();
4696     +#endif
4697     +
4698     /* {{{ php_module_startup
4699     */
4700     int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules)
4701     @@ -1858,6 +1865,10 @@
4702     php_win32_init_rng_lock();
4703     #endif
4704    
4705     +#if SUHOSIN_PATCH
4706     + suhosin_startup();
4707     +#endif
4708     +
4709     module_shutdown = 0;
4710     module_startup = 1;
4711     sapi_initialize_empty_request(TSRMLS_C);
4712     @@ -1980,7 +1991,11 @@
4713     REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS);
4714     REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4715     REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4716     - REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
4717     +#if SUHOSIN_PATCH
4718     + REGISTER_MAIN_LONG_CONSTANT("SUHOSIN_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4719     + REGISTER_MAIN_STRINGL_CONSTANT("SUHOSIN_PATCH_VERSION", SUHOSIN_PATCH_VERSION, sizeof(SUHOSIN_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4720     +#endif
4721     + REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
4722     REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4723     REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4724     #ifdef ZEND_MULTIBYTE
4725     diff -Nura php-5.3.9/main/php.h suhosin-patch-5.3.9-0.9.10/main/php.h
4726     --- php-5.3.9/main/php.h 2012-01-01 14:15:04.000000000 +0100
4727     +++ suhosin-patch-5.3.9-0.9.10/main/php.h 2012-01-11 19:29:07.000000000 +0100
4728     @@ -454,6 +454,10 @@
4729     #endif
4730     #endif /* !XtOffsetOf */
4731    
4732     +#if SUHOSIN_PATCH
4733     +#include "suhosin_patch.h"
4734     +#endif
4735     +
4736     #endif
4737    
4738     /*
4739     diff -Nura php-5.3.9/main/php_config.h.in suhosin-patch-5.3.9-0.9.10/main/php_config.h.in
4740     --- php-5.3.9/main/php_config.h.in 2012-01-10 14:37:07.000000000 +0100
4741     +++ suhosin-patch-5.3.9-0.9.10/main/php_config.h.in 2012-01-11 19:29:07.000000000 +0100
4742     @@ -405,6 +405,9 @@
4743     /* Define to 1 if you have the `alphasort' function. */
4744     #undef HAVE_ALPHASORT
4745    
4746     +/* Suhosin-Patch for PHP */
4747     +#undef SUHOSIN_PATCH
4748     +
4749     /* Whether you have AOLserver */
4750     #undef HAVE_AOLSERVER
4751    
4752     diff -Nura php-5.3.9/main/php_logos.c suhosin-patch-5.3.9-0.9.10/main/php_logos.c
4753     --- php-5.3.9/main/php_logos.c 2012-01-01 14:15:04.000000000 +0100
4754     +++ suhosin-patch-5.3.9-0.9.10/main/php_logos.c 2012-01-11 19:29:07.000000000 +0100
4755     @@ -50,6 +50,10 @@
4756     return zend_hash_del(&phpinfo_logo_hash, logo_string, strlen(logo_string));
4757     }
4758    
4759     +#if SUHOSIN_PATCH
4760     +#include "suhosin_logo.h"
4761     +#endif
4762     +
4763     int php_init_info_logos(void)
4764     {
4765     if(zend_hash_init(&phpinfo_logo_hash, 0, NULL, NULL, 1)==FAILURE)
4766     @@ -58,7 +62,9 @@
4767     php_register_info_logo(PHP_LOGO_GUID , "image/gif", php_logo , sizeof(php_logo));
4768     php_register_info_logo(PHP_EGG_LOGO_GUID, "image/gif", php_egg_logo, sizeof(php_egg_logo));
4769     php_register_info_logo(ZEND_LOGO_GUID , "image/gif", zend_logo , sizeof(zend_logo));
4770     -
4771     +#if SUHOSIN_PATCH
4772     + php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo , sizeof(suhosin_logo));
4773     +#endif
4774     return SUCCESS;
4775     }
4776    
4777     diff -Nura php-5.3.9/main/snprintf.c suhosin-patch-5.3.9-0.9.10/main/snprintf.c
4778     --- php-5.3.9/main/snprintf.c 2012-01-01 14:15:04.000000000 +0100
4779     +++ suhosin-patch-5.3.9-0.9.10/main/snprintf.c 2012-01-11 19:29:07.000000000 +0100
4780     @@ -782,6 +782,10 @@
4781     */
4782     switch (*fmt) {
4783     case 'Z':
4784     +#if SUHOSIN_PATCH
4785     + zend_suhosin_log(S_MISC, "'Z' specifier within format string");
4786     + goto skip_output;
4787     +#else
4788     zvp = (zval*) va_arg(ap, zval*);
4789     zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
4790     if (free_zcopy) {
4791     @@ -792,6 +796,7 @@
4792     if (adjust_precision && precision < s_len) {
4793     s_len = precision;
4794     }
4795     +#endif
4796     break;
4797     case 'u':
4798     switch(modifier) {
4799     @@ -1093,7 +1098,11 @@
4800    
4801    
4802     case 'n':
4803     +#if SUHOSIN_PATCH
4804     + zend_suhosin_log(S_MISC, "'n' specifier within format string");
4805     +#else
4806     *(va_arg(ap, int *)) = cc;
4807     +#endif
4808     goto skip_output;
4809    
4810     /*
4811     diff -Nura php-5.3.9/main/spprintf.c suhosin-patch-5.3.9-0.9.10/main/spprintf.c
4812     --- php-5.3.9/main/spprintf.c 2012-01-01 14:15:04.000000000 +0100
4813     +++ suhosin-patch-5.3.9-0.9.10/main/spprintf.c 2012-01-11 19:29:08.000000000 +0100
4814     @@ -390,6 +390,10 @@
4815     */
4816     switch (*fmt) {
4817     case 'Z':
4818     +#if SUHOSIN_PATCH
4819     + zend_suhosin_log(S_MISC, "'Z' specifier within format string");
4820     + goto skip_output;
4821     +#else
4822     zvp = (zval*) va_arg(ap, zval*);
4823     zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
4824     if (free_zcopy) {
4825     @@ -400,6 +404,7 @@
4826     if (adjust_precision && precision < s_len) {
4827     s_len = precision;
4828     }
4829     +#endif
4830     break;
4831     case 'u':
4832     switch(modifier) {
4833     @@ -700,7 +705,11 @@
4834    
4835    
4836     case 'n':
4837     +#if SUHOSIN_PATCH
4838     + zend_suhosin_log(S_MISC, "'n' specifier within format string");
4839     +#else
4840     *(va_arg(ap, int *)) = xbuf->len;
4841     +#endif
4842     goto skip_output;
4843    
4844     /*
4845     diff -Nura php-5.3.9/main/suhosin_globals.h suhosin-patch-5.3.9-0.9.10/main/suhosin_globals.h
4846     --- php-5.3.9/main/suhosin_globals.h 1970-01-01 01:00:00.000000000 +0100
4847     +++ suhosin-patch-5.3.9-0.9.10/main/suhosin_globals.h 2012-01-11 19:29:08.000000000 +0100
4848     @@ -0,0 +1,61 @@
4849     +/*
4850     + +----------------------------------------------------------------------+
4851     + | Suhosin-Patch for PHP |
4852     + +----------------------------------------------------------------------+
4853     + | Copyright (c) 2004-2009 Stefan Esser |
4854     + +----------------------------------------------------------------------+
4855     + | This source file is subject to version 2.02 of the PHP license, |
4856     + | that is bundled with this package in the file LICENSE, and is |
4857     + | available at through the world-wide-web at |
4858     + | http://www.php.net/license/2_02.txt. |
4859     + | If you did not receive a copy of the PHP license and are unable to |
4860     + | obtain it through the world-wide-web, please send a note to |
4861     + | license@php.net so we can mail you a copy immediately. |
4862     + +----------------------------------------------------------------------+
4863     + | Author: Stefan Esser <stefan.esser@sektioneins.de> |
4864     + +----------------------------------------------------------------------+
4865     + */
4866     +
4867     +#ifndef SUHOSIN_GLOBALS_H
4868     +#define SUHOSIN_GLOBALS_H
4869     +
4870     +typedef struct _suhosin_patch_globals suhosin_patch_globals_struct;
4871     +
4872     +#ifdef ZTS
4873     +# define SPG(v) TSRMG(suhosin_patch_globals_id, suhosin_patch_globals_struct *, v)
4874     +extern int suhosin_patch_globals_id;
4875     +#else
4876     +# define SPG(v) (suhosin_patch_globals.v)
4877     +extern struct _suhosin_patch_globals suhosin_patch_globals;
4878     +#endif
4879     +
4880     +
4881     +struct _suhosin_patch_globals {
4882     + /* logging */
4883     + int log_syslog;
4884     + int log_syslog_facility;
4885     + int log_syslog_priority;
4886     + int log_sapi;
4887     + int log_script;
4888     + int log_phpscript;
4889     + char *log_scriptname;
4890     + char *log_phpscriptname;
4891     + zend_bool log_phpscript_is_safe;
4892     + zend_bool log_use_x_forwarded_for;
4893     +
4894     + /* memory manager canary protection */
4895     + unsigned int canary_1;
4896     + unsigned int canary_2;
4897     + unsigned int canary_3;
4898     + unsigned int dummy;
4899     +};
4900     +
4901     +
4902     +#endif /* SUHOSIN_GLOBALS_H */
4903     +
4904     +/*
4905     + * Local variables:
4906     + * tab-width: 4
4907     + * c-basic-offset: 4
4908     + * End:
4909     + */
4910     diff -Nura php-5.3.9/main/suhosin_logo.h suhosin-patch-5.3.9-0.9.10/main/suhosin_logo.h
4911     --- php-5.3.9/main/suhosin_logo.h 1970-01-01 01:00:00.000000000 +0100
4912     +++ suhosin-patch-5.3.9-0.9.10/main/suhosin_logo.h 2012-01-11 19:29:08.000000000 +0100
4913     @@ -0,0 +1,178 @@
4914     +static unsigned char suhosin_logo[] =
4915     + "\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48"
4916     + "\x00\x48\x00\x00\xff\xe1\x00\x16\x45\x78\x69\x66\x00\x00\x4d\x4d"
4917     + "\x00\x2a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\xff\xdb\x00\x43"
4918     + "\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
4919     + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
4920     + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
4921     + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
4922     + "\x01\xff\xc0\x00\x0b\x08\x00\x27\x00\x71\x01\x01\x22\x00\xff\xc4"
4923     + "\x00\x1e\x00\x00\x02\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00"
4924     + "\x00\x00\x00\x00\x09\x06\x08\x05\x07\x02\x03\x0a\x01\x04\xff\xc4"
4925     + "\x00\x32\x10\x00\x01\x04\x03\x00\x02\x00\x05\x01\x05\x09\x01\x00"
4926     + "\x00\x00\x00\x05\x02\x03\x04\x06\x01\x07\x08\x00\x09\x11\x12\x13"
4927     + "\x14\x21\x15\x0a\x16\x31\x56\x96\x17\x18\x19\x23\x32\x41\x58\x98"
4928     + "\xd4\xd6\xff\xda\x00\x08\x01\x01\x00\x00\x3f\x00\xf4\xc1\xe1\xe5"
4929     + "\x69\xe9\x3e\xb9\xd1\x7c\x8a\x2e\x9d\x66\xe8\x3b\x29\x4d\x7f\x46"
4930     + "\xba\x58\x55\x54\x8d\xb1\x5f\xaa\xd9\x8d\x51\x2b\xb6\x27\x5a\x69"
4931     + "\xd1\x43\xaf\x16\x1a\xf0\xb2\xb1\xe9\x6d\x9f\xc2\xa4\x36\x18\xb5"
4932     + "\x85\x10\x41\xbe\xfc\x09\xac\x49\x29\x11\xd4\x32\x97\xec\x08\x13"
4933     + "\xc1\x2d\x20\xc3\x59\xeb\x26\x05\xd8\x6b\x76\x31\x43\x8f\x57\xcf"
4934     + "\x84\x9f\x14\xa8\x53\x81\x0b\xc3\x64\x80\xa3\x02\x0a\x41\x75\xf8"
4935     + "\x44\x85\x93\x81\x22\x3c\xd8\x13\xe1\xbe\xf4\x59\x91\x1f\x6a\x44"
4936     + "\x77\x5c\x69\xc4\x2f\x39\x5f\x0f\x2a\x8d\xeb\xba\xf8\xc3\x56\x6c"
4937     + "\x3b\x36\xa7\xda\xbd\x4d\xa1\xb5\x4e\xc6\xa7\xa4\x3a\xec\x15\x2d"
4938     + "\xa5\xb3\xea\x5a\xdc\xac\x46\xac\x01\x60\xd8\x43\xc8\x8e\x8b\xb1"
4939     + "\x40\x4c\x95\x8b\x34\x41\x28\x52\x91\x28\x43\xd3\xa3\xb6\xa7\x55"
4940     + "\x15\xe7\x5a\x96\xcb\xf1\xda\xe5\x55\xee\xfe\x1e\xbd\xd9\x41\xd3"
4941     + "\x28\xfd\x97\xca\x57\x2b\x85\x9c\xa4\x30\x95\xaa\xa5\x57\xa2\x35"
4942     + "\x15\x86\xcb\x61\x34\x41\xe4\xc7\x80\x20\x18\x21\x17\x09\x85\x0b"
4943     + "\x14\x9d\x21\x68\x62\x1c\x08\x11\x64\x4b\x92\xf2\xd2\xd3\x2d\x2d"
4944     + "\x6a\xc2\x73\x6b\x3c\x3c\x8b\x9e\xbc\x52\xaa\xa4\xab\x81\x6c\xf6"
4945     + "\xfa\xbd\x70\xc5\xc6\x7b\xc2\xaa\x22\x4f\x58\x04\x87\x25\x6a\x27"
4946     + "\x1d\xa4\x3d\x20\x75\x72\x01\x09\x71\xe5\x1c\x9e\xc3\x2e\x36\xf3"
4947     + "\xd0\xc6\x35\x2a\x43\x4d\x2d\x0e\x2d\xb4\xa1\x49\xce\x65\x1e\x52"
4948     + "\x9e\xa1\xf6\x09\xcc\xdc\x63\x66\xa8\x01\xe9\x3b\x0d\xd7\x5a\x85"
4949     + "\xbb\xc5\x65\xc0\x7b\x2e\x46\xa9\xd9\x56\x1d\x4c\x92\x72\x26\x4e"
4950     + "\x86\xd5\x68\xae\xc4\xaa\x55\xce\xd7\x83\x59\xb3\x81\xee\xce\x74"
4951     + "\x39\x39\x31\x9f\x8a\x25\xe8\xa5\xa5\xe5\x81\xf2\x11\x23\xcb\xa1"
4952     + "\x1e\x43\x12\xe3\xb1\x2a\x2b\xcd\xc8\x8d\x25\x96\xa4\x47\x7d\x95"
4953     + "\xa5\xc6\x9f\x61\xe4\x25\xc6\x5e\x69\xc4\xe7\x29\x5b\x6e\xb6\xa4"
4954     + "\xad\x0b\x4e\x72\x95\x25\x58\x56\x33\x9c\x67\xce\xef\x0f\x17\xbf"
4955     + "\x4c\x7b\x2d\xe6\xfe\x76\x35\x27\x5a\x07\x97\x67\xe8\xae\x8d\x71"
4956     + "\x0f\xb2\x13\x99\xb9\xbc\x14\xad\xb3\xb7\xe6\x11\x6f\xe0\xda\x58"
4957     + "\xb1\x08\xac\xa6\x6c\x2d\x7f\x05\xb7\x56\xd2\xe6\xcf\xbb\x4d\x0c"
4958     + "\xe3\x50\xb2\xec\x91\xf0\x4a\xb8\xd6\x22\xb8\xa7\xf6\x67\xaf\xcf"
4959     + "\x63\x7e\xd7\xe7\x42\xd8\xbd\xc3\x71\xa1\xf2\x7e\x9b\xa8\x97\x83"
4960     + "\x6e\xd1\xdc\x4b\x06\x11\x2d\xae\x26\x61\x98\x72\x10\xf4\x42\x5d"
4961     + "\x20\x4a\xa3\x73\xd7\xf2\xcd\x3c\x48\x32\xe4\x03\x9f\x80\x37\x08"
4962     + "\x36\x11\xd0\xcb\x97\x6c\x08\xed\x6d\x33\x24\xa2\x1b\xb4\x77\xdf"
4963     + "\x61\x5d\x5f\xc1\x43\xc2\x82\xeb\x0f\x5d\x84\x08\x68\xaa\xa4\x01"
4964     + "\xe1\x19\xdf\xbc\x31\x65\xfe\xd1\xf5\x7d\x7a\xb2\x2a\x33\x50\x21"
4965     + "\x2a\x56\x9d\xb1\x81\xab\xdb\x35\x78\x30\x83\xd9\x89\x1d\x31\xac"
4966     + "\x96\x14\x07\x61\xbc\x20\x68\x42\x85\x33\x19\xac\xbe\xdb\x34\x56"
4967     + "\xf1\xd5\xfd\x29\xa9\x28\xdb\xcb\x4c\x5a\x23\xdc\xf5\x96\xc5\x10"
4968     + "\xa3\x35\x5b\x14\x68\xd3\x61\x62\x64\x76\x26\xcb\x17\x3e\x34\x98"
4969     + "\x04\xa3\xc4\x20\x38\x90\x92\xe3\xc8\x07\x2c\x36\x74\x66\x26\x0e"
4970     + "\x29\x02\x64\x29\x2d\x21\xe6\x16\x9c\x6b\xce\xa3\x89\xd9\x4f\xd3"
4971     + "\xc4\xbd\xc5\x87\x79\x9c\x65\xf6\x39\x45\x60\xe8\xce\x9e\xab\x6d"
4972     + "\x13\x15\x22\xe1\x5e\x4b\x38\x42\xc4\x1e\xd5\x76\xe0\xc5\xeb\x85"
4973     + "\x07\x2d\x0f\xb8\xb6\xa6\xd6\x6d\x71\x0d\xa2\x43\x4c\x25\xea\xfa"
4974     + "\xa1\xae\x4c\xe4\x7d\xbd\x76\xa9\xfb\x06\xc2\x83\x42\xeb\xad\xe7"
4975     + "\xe9\x5f\x68\x6f\xba\xfb\x2f\x07\xce\xb8\x13\xc1\x9b\xeb\xb0\x76"
4976     + "\x45\x57\x28\x7b\xea\xbe\x0f\xf4\x30\x7b\xa0\xed\xe4\x22\x93\x21"
4977     + "\xfc\xbc\xe0\xb9\x75\xc1\x4f\xfc\xef\xb6\xfa\xa1\xfc\x64\xa1\x4a"
4978     + "\x82\xc7\x33\xad\x75\xed\x82\xbd\x3d\xdb\xf7\xa8\xbe\x5e\xbb\x36"
4979     + "\x62\x04\x9a\x2e\xc5\xd9\x9e\x9c\x3a\x0b\x98\x0b\x57\xac\xf1\x24"
4980     + "\x62\x58\x83\x15\x5b\xa6\xf2\xda\x34\x70\x03\xce\x0f\x93\x1b\x12"
4981     + "\xc7\xce\x54\x87\x33\x15\xd6\x53\x25\x1f\x2a\x90\x87\x12\xe3\x78"
4982     + "\xef\x55\x77\x4d\x4a\xd8\x7e\xef\xd2\xfd\xd1\xaf\x3a\xaf\x55\xdb"
4983     + "\x6a\x2d\x3d\x42\xac\x51\x79\xee\x91\xab\xe1\x05\x2d\x3c\x80\xa2"
4984     + "\x43\xad\x22\x2e\xd5\x33\x13\xa4\x9e\x00\xe0\x04\x10\x84\xc8\xf2"
4985     + "\x19\x30\x92\x1f\xaa\xc3\x28\xc9\x76\x30\x3f\xe9\x10\x61\x5e\x79"
4986     + "\xd5\xf7\xdf\xd0\x54\xdb\xae\xb6\xae\xfa\xe8\xa3\x57\xe0\x6c\x2d"
4987     + "\xf7\xbd\x49\xd6\x6e\x76\x79\xcc\x54\x0c\x5f\xff\x00\xbb\x06\x98"
4988     + "\xa6\x9e\x89\x61\xb4\x6f\xc3\xe3\x6a\xc2\x4f\x59\x03\xc9\x80\x2c"
4989     + "\x59\x24\x44\x70\x38\xd5\x96\x6a\x9e\x8b\x81\x64\xe5\xbc\xa0\x3c"
4990     + "\x33\xaf\x17\x9d\xff\x00\x71\x1a\xd1\x3a\x80\x66\xb3\xd9\x31\x77"
4991     + "\x0d\x12\xbd\xae\x29\xb5\x6a\xd6\xcf\x8d\x68\x87\x75\xcd\xe8\x65"
4992     + "\x5a\xbe\x3c\x04\x7b\x34\xdb\x54\x19\xa4\x63\x9c\x2a\x5d\x23\xbe"
4993     + "\xf4\xb1\x1c\x4d\x90\xec\x92\x2f\x49\x71\xf7\x14\xf2\x97\x9f\x15"
4994     + "\x57\xed\x13\x21\x2a\xf5\x33\xd1\x2a\x52\x52\xac\xb7\x62\xd1\xcb"
4995     + "\x46\x73\x8c\x67\x28\x56\x77\x86\xbf\x6f\x2a\x4e\x73\xfe\x95\x65"
4996     + "\x0b\x5a\x3e\x38\xfc\xfc\xaa\x56\x3f\x86\x73\xe3\xb9\x4a\x52\x84"
4997     + "\xa5\x08\x4e\x12\x94\x27\x09\x4a\x53\x8c\x61\x29\x4a\x71\xf0\x4a"
4998     + "\x53\x8c\x7e\x31\x8c\x63\x18\xc6\x31\x8f\xc6\x31\xf8\xc7\x9f\x7c"
4999     + "\xd5\xbb\xae\x5e\xe2\x1f\xab\x6e\x24\x34\x00\x8a\x25\x83\x70\x40"
5000     + "\x1c\xcc\xda\x45\x7f\x66\x4e\x30\x2e\x94\x7e\x74\x49\xf0\xe4\x4e"
5001     + "\x06\x5c\xa8\x2f\x89\x21\x2e\x98\x0e\xd9\x21\xc2\x0b\x21\x0f\xc4"
5002     + "\x16\x6e\x48\xd9\xe4\xe3\x4a\x19\x1e\x64\x67\x54\xff\x00\x3a\x6d"
5003     + "\x4f\x62\xb5\x00\x4a\xaa\x51\xfd\x2d\xe8\x0e\x6c\xaf\xc6\x7d\x6d"
5004     + "\xc8\x88\xc7\x67\xea\x8a\x58\x02\x73\xe3\x65\x4d\xc9\x24\xc0\x3d"
5005     + "\x57\xa3\x2e\x53\x16\x99\x4f\xe5\xe7\x19\x97\x3e\x3b\xcf\xc9\x4b"
5006     + "\x99\x7f\x33\x25\xa5\xdf\xba\x77\x2b\xd3\x3e\xc2\x7b\x8b\x94\x07"
5007     + "\xe9\x52\x5b\x43\x87\x34\x14\x86\x37\xcf\x41\x6b\x8e\x6a\xa5\x22"
5008     + "\xab\xdb\x96\xa2\xcf\x46\xd8\x9b\x45\x93\xef\xd6\xdf\x3e\x99\x9c"
5009     + "\x7e\x29\x10\x6b\x6c\xa2\xb8\x43\x05\x09\x44\x70\x8c\xb8\xaa\x54"
5010     + "\x7c\x30\x36\x5e\x1c\x5e\x5b\x9f\x6c\x0d\x81\xee\xa0\x93\x8d\x67"
5011     + "\x55\xf3\x87\xaf\xaa\x6b\x58\xf9\xbe\xb2\x36\x07\x42\x6e\xbd\x96"
5012     + "\xe3\x9f\x1f\x8f\xc9\xf4\x9d\xae\x6a\x7d\x4c\x96\xbe\x5f\xc7\xcd"
5013     + "\xf3\xb2\xf7\xcd\xf0\xcf\xc3\xe4\xf8\xfe\x37\x4f\x1c\x4d\xf6\x40"
5014     + "\xf1\x6b\x7c\x4e\xe0\xa6\x71\xad\x56\xa7\x1c\x5c\x15\x6b\xfc\xf3"
5015     + "\x01\x5d\xac\xf1\x75\x9a\x72\x6b\xaa\x28\xc5\x88\x6d\xfb\x33\x85"
5016     + "\xe0\x4e\x61\xab\xeb\x31\x2c\x71\x08\x73\x11\x3b\xfc\xb5\xc0\x96"
5017     + "\xcc\x87\x24\x44\xb5\x9b\x9e\xb3\x71\xba\xe9\xed\xb1\x4e\xd7\x76"
5018     + "\x6c\xd2\xb6\x05\xb7\x5a\xde\xeb\x34\x5b\x96\x16\xfb\x59\xa9\x5c"
5019     + "\x4f\x55\xca\x8a\xac\x59\xb0\xe4\x54\x39\x25\xbc\x81\x37\x2a\x09"
5020     + "\x5f\x9e\x3b\x6b\x7d\x1f\x69\xf3\x34\x85\x39\x84\xa7\x28\x0b\xd3"
5021     + "\xfd\xfb\x4b\x7a\xea\xe7\xd2\x3c\xd3\xda\x15\x68\xbc\x73\xd3\x22"
5022     + "\x6f\xd7\x72\x5b\x2b\x66\xee\xa8\x0d\x54\xe8\x5b\xf9\x92\x96\x92"
5023     + "\x93\xea\x97\x4a\xc7\x43\x10\x46\x35\xc5\xc0\x60\x8a\xe4\xc1\xb5"
5024     + "\x36\xc6\xae\xed\xf7\x70\xa5\x86\x99\x3d\x91\xf8\xfd\x4e\x53\xeb"
5025     + "\xbb\xbd\x6d\xec\x8f\xd7\x89\x3d\x31\x7f\xd7\x78\xba\x50\xbb\x74"
5026     + "\x9d\xf6\xac\x4e\xb9\x03\x9c\x79\xd5\xe1\xbd\x17\x68\xd9\x13\x0b"
5027     + "\x45\x75\x88\x00\x1d\x1f\xae\x73\x6a\x1d\x5c\x6e\x44\x9f\xa6\xfa"
5028     + "\x4e\xd8\x25\x8b\xc0\xbc\xb2\x99\xe3\x17\x24\xb3\x23\xe2\x48\x8b"
5029     + "\xfa\x22\xe7\x7e\x8f\xe6\x3f\x5f\x55\x0d\x75\xd3\x51\x0b\xd7\xed"
5030     + "\xd3\x6f\x97\x3b\x85\x42\x80\x7e\x5f\xdc\x1b\xd6\xba\xee\xc4\x80"
5031     + "\xce\x06\xa9\x15\x8c\x97\x5f\x40\x69\xb2\x4d\xc5\xb2\x5c\x1e\x01"
5032     + "\x87\x7e\xe0\x36\x6d\x78\x80\x4e\x3c\x02\xec\x90\x1d\x11\x81\x74"
5033     + "\xa5\x8b\xa4\xa0\x56\x06\xd5\x79\x72\x85\x57\x3b\xb2\x2e\xae\x90"
5034     + "\x18\x8d\x91\xb2\x0e\x44\x19\xaa\xb4\xcc\x08\xed\x46\xfa\xd7\x2b"
5035     + "\x78\x58\x72\x5d\xbb\x5e\x49\xe7\xee\xf3\x8a\x9d\x22\xa4\x19\xc8"
5036     + "\xe7\x08\xc3\x90\x9b\x35\x9a\xa4\x25\x8c\x4b\x9b\xa7\xf8\xbf\x81"
5037     + "\xf5\xdf\x22\x66\xf1\x7e\x9f\x66\x3d\xbb\xfa\x73\x73\x4d\xfd\x67"
5038     + "\x7b\xf4\xce\xc3\x62\x2e\x6f\xbb\x0c\xa2\xdc\x69\xfc\x8a\x17\x0e"
5039     + "\x3a\x9e\x83\x46\xd7\xe3\x5e\x65\x86\xc0\x51\x00\xbb\x91\xe3\xe1"
5040     + "\xc1\x16\xc4\xe9\x65\x5c\x14\x3e\x44\x6a\x6b\xd1\x1e\xb0\x36\xdd"
5041     + "\x0b\x7d\x8a\xeb\xaf\x58\x5b\x64\x3f\x38\xed\x52\x76\xe8\x46\xf7"
5042     + "\x86\x84\xb3\x93\xb1\x0b\xe5\xfd\xfd\x0d\xe9\x6d\xe4\xf1\x1b\x1d"
5043     + "\x56\xb4\x34\xe4\x6a\xf5\xa4\x9c\x2c\xc9\x64\x94\xc1\xf5\x79\x6d"
5044     + "\x12\x96\xf3\x47\xc5\x48\xa8\xdb\xd8\x95\x64\x29\xcf\xf6\x88\xf1"
5045     + "\x95\x7a\x98\xe8\xbc\x27\x19\xce\x73\x61\xd1\xb8\xc6\x31\x8c\xe7"
5046     + "\x39\xce\x77\x9e\xbc\xc6\x31\x8c\x63\xf3\x9c\xe7\x39\xc6\x31\x8f"
5047     + "\xf7\xce\x7e\x1e\x3b\x7f\x0f\x0f\x0f\x13\x57\xb9\x0a\xe1\x0b\x64"
5048     + "\x5f\x58\x40\xc6\xc7\x7a\x4b\xf2\x3d\xbc\x71\xf4\xa7\xd2\xca\x14"
5049     + "\xe2\x98\x1a\x30\x1e\xe0\x26\x5a\x6a\xf0\x9c\x67\x38\x66\x00\xb8"
5050     + "\x72\xe6\xbe\xac\xfe\x12\xd3\x0b\x56\x73\x8c\x63\xc7\x2b\xe1\xe2"
5051     + "\xe8\xdd\x7b\xff\x00\xd8\xe5\x23\x6c\xce\xa8\x69\xcf\x5e\x3a\xef"
5052     + "\x77\xea\xe5\xab\x0e\x82\xdb\xd9\xed\x7a\x9e\xb8\x6d\x51\x32\xdb"
5053     + "\x79\xc3\x36\x9a\x2d\xa3\x50\x39\x65\x0a\x63\x0e\xe5\xd4\x39\x12"
5054     + "\xbf\x8b\x98\xa4\xa1\x2d\xad\xb3\xcf\x65\x6a\x43\x78\xb3\x3b\x07"
5055     + "\xd8\xd5\xea\xae\x76\xad\x6f\xf5\xff\x00\xca\x93\xab\x96\xb0\x64"
5056     + "\xeb\xd6\x4a\xd5\x87\xba\xec\x24\x60\x97\x06\x76\x03\xe3\x4c\x07"
5057     + "\x29\x11\x8e\x34\x25\x02\x64\x29\xf0\x25\x48\x85\x3a\x33\x8b\x7a"
5058     + "\x3c\x86\x1e\x75\xa5\x61\xc6\x97\x9f\x8d\x25\xf5\xc9\xcd\xde\xc9"
5059     + "\x7d\x77\xf2\xc8\x7e\x70\xaf\x73\x5f\x2d\xec\xa2\x51\x2d\x96\xfb"
5060     + "\x89\xad\x80\x57\xb2\x36\x1d\x7d\x83\x45\xac\xf3\xdb\xcc\x6c\x31"
5061     + "\x4f\xcf\x30\x58\xd0\x12\x28\x90\x50\x42\x86\xfb\x48\x16\x3c\xc5"
5062     + "\x9c\xf8\xe7\xcc\x29\x88\xb3\x4a\x4b\x4e\x6c\xbc\xdb\xc7\xbb\xe9"
5063     + "\xb6\xa0\x8b\x11\xa1\x7d\x73\xd7\xe9\xbf\x7e\xc2\x6c\x10\x8d\xee"
5064     + "\x9d\xef\x63\x3a\xe0\xf5\xbe\x8c\x3e\xa1\xc7\xc5\xd1\x00\x44\x1e"
5065     + "\xf3\x51\xf2\xe2\xb0\xe3\xb5\x13\x7f\x32\xf1\x8c\xa6\x22\xfe\x1f"
5066     + "\x49\x4d\xbb\xcf\x3a\x5d\xed\x4c\xd2\xfc\x85\xed\x23\xd6\xc7\x50"
5067     + "\xb6\x5b\x3a\x16\x83\xb8\x6f\xfd\x32\x3f\xaa\x36\x34\xbb\xf5\x96"
5068     + "\xa9\xab\xcf\x9f\x8f\xac\xc3\xca\xd5\x8b\xd8\x48\x9e\x79\xaa\x30"
5069     + "\x87\xca\x58\x4d\x59\x96\xb9\x4f\xc5\x1b\x1c\xd2\xda\x5b\xe6\x57"
5070     + "\x29\xa1\x28\x7a\x2b\x5b\xff\x00\x12\x2f\x5e\x3f\xf3\xbb\x8e\x7f"
5071     + "\xec\xc6\x98\xff\x00\xed\x3c\xa6\xdd\xa9\xdc\x7e\xa0\xf7\xd6\x99"
5072     + "\x31\xa2\xf7\xaf\x6b\xe9\x82\x74\x4b\x3d\x8f\x5e\x58\x0b\x33\xab"
5073     + "\xef\xc3\xaf\x84\x64\xb9\xae\xb6\x25\x5f\x62\x8f\x1c\xe3\xf4\x51"
5074     + "\xb7\x96\xe3\x0e\x30\x42\xa9\x18\x39\xbf\x9e\x2a\x1f\x74\x19\x02"
5075     + "\x2d\x43\x93\x06\x63\xb1\xa7\x47\x6a\xfa\x9b\x6c\xeb\xbd\xe9\xae"
5076     + "\x6a\x7b\x6f\x53\x5a\x60\x5d\xb5\xcd\xe8\x67\xeb\x35\x3b\x48\xc6"
5077     + "\xa6\xb3\x04\xc8\xdf\xb8\x7e\x26\x64\xb0\xc9\x18\xb0\xa7\x33\xf2"
5078     + "\x4a\x8b\x22\x3b\x8d\x4b\x89\x1d\xf6\x9d\x65\xc4\x38\xd2\x54\x9c"
5079     + "\xe3\xcd\x89\xe1\xe1\xe6\x3e\x70\x81\x45\x1d\x18\xf9\x31\x83\xc8"
5080     + "\xbe\x14\x82\x4b\x87\x7a\x74\x28\xd2\xdd\x12\x55\x30\xe6\x0e\x49"
5081     + "\x31\x8e\x48\x69\xc5\xc0\x20\x91\xe4\x48\x41\x4c\xd8\xb9\x6a\x4e"
5082     + "\x21\xce\x99\x1b\x0e\xfd\x09\x4f\xa1\x79\x0f\x0f\x0f\x0f\x0f\x0f"
5083     + "\x0f\x3f\x3c\xb8\x71\x27\xc7\x72\x24\xe8\xb1\xa6\xc5\x7b\x18\xc3"
5084     + "\xb1\xa5\xb0\xd4\x98\xee\xe3\x19\xc6\x71\x87\x19\x79\x2b\x6d\x78"
5085     + "\xc6\x71\x8c\xe3\x0a\x4e\x71\x8c\xe3\x19\xfe\x38\xf2\x3b\xfb\x8b"
5086     + "\x48\xfe\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe1\xfb\x8b\x48\xfe"
5087     + "\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe4\x95\x86\x18\x8a\xcb\x31"
5088     + "\xa3\x32\xd4\x78\xf1\xdb\x43\x2c\x47\x61\xb4\x32\xcb\x2c\xb4\x9c"
5089     + "\x21\xb6\x99\x69\xbc\x25\xb6\xdb\x6d\x18\xc2\x10\xda\x12\x94\xa1"
5090     + "\x38\xc2\x53\x8c\x63\x18\xc7\x9d\xbe\x7f\xff\xd9"
5091     + ;
5092     diff -Nura php-5.3.9/main/suhosin_patch.c suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.c
5093     --- php-5.3.9/main/suhosin_patch.c 1970-01-01 01:00:00.000000000 +0100
5094     +++ suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.c 2012-01-11 19:29:08.000000000 +0100
5095     @@ -0,0 +1,470 @@
5096     +/*
5097     + +----------------------------------------------------------------------+
5098     + | Suhosin Patch for PHP |
5099     + +----------------------------------------------------------------------+
5100     + | Copyright (c) 2004-2010 Stefan Esser |
5101     + +----------------------------------------------------------------------+
5102     + | This source file is subject to version 2.02 of the PHP license, |
5103     + | that is bundled with this package in the file LICENSE, and is |
5104     + | available at through the world-wide-web at |
5105     + | http://www.php.net/license/2_02.txt. |
5106     + | If you did not receive a copy of the PHP license and are unable to |
5107     + | obtain it through the world-wide-web, please send a note to |
5108     + | license@php.net so we can mail you a copy immediately. |
5109     + +----------------------------------------------------------------------+
5110     + | Author: Stefan Esser <sesser@hardened-php.net> |
5111     + +----------------------------------------------------------------------+
5112     + */
5113     +/* $Id: suhosin_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
5114     +
5115     +#include "php.h"
5116     +
5117     +#include <stdio.h>
5118     +#include <stdlib.h>
5119     +#include <sys/mman.h>
5120     +
5121     +#if HAVE_UNISTD_H
5122     +#include <unistd.h>
5123     +#endif
5124     +#include "SAPI.h"
5125     +#include "php_globals.h"
5126     +
5127     +#if SUHOSIN_PATCH
5128     +
5129     +#ifdef HAVE_SYS_SOCKET_H
5130     +#include <sys/socket.h>
5131     +#endif
5132     +
5133     +#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
5134     +#undef AF_UNIX
5135     +#endif
5136     +
5137     +#if defined(AF_UNIX)
5138     +#include <sys/un.h>
5139     +#endif
5140     +
5141     +#define SYSLOG_PATH "/dev/log"
5142     +
5143     +#ifdef PHP_WIN32
5144     +static HANDLE log_source = 0;
5145     +#endif
5146     +
5147     +#include "snprintf.h"
5148     +
5149     +#include "suhosin_patch.h"
5150     +
5151     +#ifdef ZTS
5152     +#include "suhosin_globals.h"
5153     +int suhosin_patch_globals_id;
5154     +#else
5155     +struct _suhosin_patch_globals suhosin_patch_globals;
5156     +#endif
5157     +
5158     +static char *suhosin_config = NULL;
5159     +
5160     +static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
5161     +
5162     +static void php_security_log(int loglevel, char *fmt, ...);
5163     +
5164     +static void suhosin_patch_globals_ctor(suhosin_patch_globals_struct *suhosin_patch_globals TSRMLS_DC)
5165     +{
5166     + memset(suhosin_patch_globals, 0, sizeof(*suhosin_patch_globals));
5167     +}
5168     +
5169     +ZEND_API char suhosin_get_config(int element)
5170     +{
5171     + return ((char *)SUHOSIN_MANGLE_PTR(suhosin_config))[element];
5172     +}
5173     +
5174     +static void suhosin_set_config(int element, char value)
5175     +{
5176     + ((char *)SUHOSIN_MANGLE_PTR(suhosin_config))[element] = value;
5177     +}
5178     +
5179     +static void suhosin_read_configuration_from_environment()
5180     +{
5181     + char *tmp;
5182     +
5183     + /* check if canary protection should be activated or not */
5184     + tmp = getenv("SUHOSIN_MM_USE_CANARY_PROTECTION");
5185     + /* default to activated */
5186     + suhosin_set_config(SUHOSIN_MM_USE_CANARY_PROTECTION, 1);
5187     + if (tmp) {
5188     + int flag = zend_atoi(tmp, 0);
5189     + suhosin_set_config(SUHOSIN_MM_USE_CANARY_PROTECTION, flag);
5190     + }
5191     +
5192     + /* check if free memory should be overwritten with 0xFF or not */
5193     + tmp = getenv("SUHOSIN_MM_DESTROY_FREE_MEMORY");
5194     + /* default to deactivated */
5195     + suhosin_set_config(SUHOSIN_MM_DESTROY_FREE_MEMORY, 0);
5196     + if (tmp) {
5197     + int flag = zend_atoi(tmp, 0);
5198     + suhosin_set_config(SUHOSIN_MM_DESTROY_FREE_MEMORY, flag);
5199     + }
5200     +
5201     + /* check if canary violations should be ignored */
5202     + tmp = getenv("SUHOSIN_MM_IGNORE_CANARY_VIOLATION");
5203     + /* default to NOT ignore */
5204     + suhosin_set_config(SUHOSIN_MM_IGNORE_CANARY_VIOLATION, 0);
5205     + if (tmp) {
5206     + int flag = zend_atoi(tmp, 0);
5207     + suhosin_set_config(SUHOSIN_MM_IGNORE_CANARY_VIOLATION, flag);
5208     + }
5209     +
5210     + /* check if invalid hashtable destructors should be ignored */
5211     + tmp = getenv("SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR");
5212     + /* default to NOT ignore */
5213     + suhosin_set_config(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR, 0);
5214     + if (tmp) {
5215     + int flag = zend_atoi(tmp, 0);
5216     + suhosin_set_config(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR, flag);
5217     + }
5218     +
5219     + /* check if invalid linkedlist destructors should be ignored */
5220     + tmp = getenv("SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR");
5221     + /* default to NOT ignore */
5222     + suhosin_set_config(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR, 0);
5223     + if (tmp) {
5224     + int flag = zend_atoi(tmp, 0);
5225     + suhosin_set_config(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR, flag);
5226     + }
5227     +
5228     + suhosin_set_config(SUHOSIN_CONFIG_SET, 1);
5229     +}
5230     +
5231     +static void suhosin_write_protect_configuration()
5232     +{
5233     + /* check return value of mprotect() to ensure memory is read only now */
5234     + if (mprotect(SUHOSIN_MANGLE_PTR(suhosin_config), sysconf(_SC_PAGESIZE), PROT_READ) != 0) {
5235     + perror("suhosin");
5236     + _exit(1);
5237     + }
5238     +}
5239     +
5240     +PHPAPI void suhosin_startup()
5241     +{
5242     +#ifdef ZTS
5243     + ts_allocate_id(&suhosin_patch_globals_id, sizeof(suhosin_patch_globals_struct), (ts_allocate_ctor) suhosin_patch_globals_ctor, NULL);
5244     +#else
5245     + suhosin_patch_globals_ctor(&suhosin_patch_globals TSRMLS_CC);
5246     +#endif
5247     + zend_suhosin_log = php_security_log;
5248     +
5249     + /* get the pointer guardian and ensure low 3 bits are 1 */
5250     + if (SUHOSIN_POINTER_GUARD == 0) {
5251     + zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
5252     + SUHOSIN_POINTER_GUARD |= 7;
5253     + }
5254     +
5255     + if (!suhosin_config) {
5256     +#ifndef MAP_ANONYMOUS
5257     +#define MAP_ANONYMOUS MAP_ANON
5258     +#endif
5259     + suhosin_config = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
5260     + if (suhosin_config == MAP_FAILED) {
5261     + perror("suhosin");
5262     + _exit(1);
5263     + }
5264     + suhosin_config = SUHOSIN_MANGLE_PTR(suhosin_config);
5265     + }
5266     + if (!SUHOSIN_CONFIG(SUHOSIN_CONFIG_SET)) {
5267     + suhosin_read_configuration_from_environment();
5268     + suhosin_write_protect_configuration();
5269     + }
5270     +}
5271     +
5272     +static char *loglevel2string(int loglevel)
5273     +{
5274     + switch (loglevel) {
5275     + case S_FILES:
5276     + return "FILES";
5277     + case S_INCLUDE:
5278     + return "INCLUDE";
5279     + case S_MEMORY:
5280     + return "MEMORY";
5281     + case S_MISC:
5282     + return "MISC";
5283     + case S_SESSION:
5284     + return "SESSION";
5285     + case S_SQL:
5286     + return "SQL";
5287     + case S_EXECUTOR:
5288     + return "EXECUTOR";
5289     + case S_VARS:
5290     + return "VARS";
5291     + default:
5292     + return "UNKNOWN";
5293     + }
5294     +}
5295     +
5296     +static void php_security_log(int loglevel, char *fmt, ...)
5297     +{
5298     + int s, r, i=0;
5299     +#if defined(AF_UNIX)
5300     + struct sockaddr_un saun;
5301     +#endif
5302     +#ifdef PHP_WIN32
5303     + LPTSTR strs[2];
5304     + unsigned short etype;
5305     + DWORD evid;
5306     +#endif
5307     + char buf[4096+64];
5308     + char error[4096+100];
5309     + char *ip_address;
5310     + char *fname;
5311     + char *alertstring;
5312     + int lineno;
5313     + va_list ap;
5314     + TSRMLS_FETCH();
5315     +
5316     + /*SDEBUG("(suhosin_log) loglevel: %d log_syslog: %u - log_sapi: %u - log_script: %u", loglevel, SPG(log_syslog), SPG(log_sapi), SPG(log_script));*/
5317     +
5318     + if (SPG(log_use_x_forwarded_for)) {
5319     + ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
5320     + if (ip_address == NULL) {
5321     + ip_address = "X-FORWARDED-FOR not set";
5322     + }
5323     + } else {
5324     + ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
5325     + if (ip_address == NULL) {
5326     + ip_address = "REMOTE_ADDR not set";
5327     + }
5328     + }
5329     +
5330     +
5331     + va_start(ap, fmt);
5332     + ap_php_vsnprintf(error, sizeof(error), fmt, ap);
5333     + va_end(ap);
5334     + while (error[i]) {
5335     + if (error[i] < 32) error[i] = '.';
5336     + i++;
5337     + }
5338     +
5339     +/* if (SPG(simulation)) {
5340     + alertstring = "ALERT-SIMULATION";
5341     + } else { */
5342     + alertstring = "ALERT";
5343     +/* }*/
5344     +
5345     + if (zend_is_executing(TSRMLS_C)) {
5346     + if (EG(current_execute_data)) {
5347     + lineno = EG(current_execute_data)->opline->lineno;
5348     + fname = EG(current_execute_data)->op_array->filename;
5349     + } else {
5350     + lineno = zend_get_executed_lineno(TSRMLS_C);
5351     + fname = zend_get_executed_filename(TSRMLS_C);
5352     + }
5353     + ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno);
5354     + } else {
5355     + fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
5356     + if (fname==NULL) {
5357     + fname = "unknown";
5358     + }
5359     + ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname);
5360     + }
5361     +
5362     + /* Syslog-Logging disabled? */
5363     + if (((SPG(log_syslog)|S_INTERNAL) & loglevel)==0) {
5364     + goto log_sapi;
5365     + }
5366     +
5367     +#if defined(AF_UNIX)
5368     + ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SPG(log_syslog_facility)|SPG(log_syslog_priority)),getpid(),buf);
5369     +
5370     + s = socket(AF_UNIX, SOCK_DGRAM, 0);
5371     + if (s == -1) {
5372     + goto log_sapi;
5373     + }
5374     +
5375     + memset(&saun, 0, sizeof(saun));
5376     + saun.sun_family = AF_UNIX;
5377     + strcpy(saun.sun_path, SYSLOG_PATH);
5378     + /*saun.sun_len = sizeof(saun);*/
5379     +
5380     + r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5381     + if (r) {
5382     + close(s);
5383     + s = socket(AF_UNIX, SOCK_STREAM, 0);
5384     + if (s == -1) {
5385     + goto log_sapi;
5386     + }
5387     +
5388     + memset(&saun, 0, sizeof(saun));
5389     + saun.sun_family = AF_UNIX;
5390     + strcpy(saun.sun_path, SYSLOG_PATH);
5391     + /*saun.sun_len = sizeof(saun);*/
5392     +
5393     + r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5394     + if (r) {
5395     + close(s);
5396     + goto log_sapi;
5397     + }
5398     + }
5399     + send(s, error, strlen(error), 0);
5400     +
5401     + close(s);
5402     +#endif
5403     +#ifdef PHP_WIN32
5404     + ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf);
5405     +
5406     + switch (SPG(log_syslog_priority)) { /* translate UNIX type into NT type */
5407     + case 1: /*LOG_ALERT:*/
5408     + etype = EVENTLOG_ERROR_TYPE;
5409     + break;
5410     + case 6: /*LOG_INFO:*/
5411     + etype = EVENTLOG_INFORMATION_TYPE;
5412     + break;
5413     + default:
5414     + etype = EVENTLOG_WARNING_TYPE;
5415     + }
5416     + evid = loglevel;
5417     + strs[0] = error;
5418     + /* report the event */
5419     + if (log_source == NULL) {
5420     + log_source = RegisterEventSource(NULL, "Suhosin-Patch-" SUHOSIN_PATCH_VERSION);
5421     + }
5422     + ReportEvent(log_source, etype, (unsigned short) SPG(log_syslog_priority), evid, NULL, 1, 0, strs, NULL);
5423     +
5424     +#endif
5425     +log_sapi:
5426     + /* SAPI Logging activated? */
5427     + /*SDEBUG("(suhosin_log) log_syslog: %u - log_sapi: %u - log_script: %u - log_phpscript: %u", SPG(log_syslog), SPG(log_sapi), SPG(log_script), SPG(log_phpscript));*/
5428     + if (((SPG(log_sapi)|S_INTERNAL) & loglevel)!=0) {
5429     + sapi_module.log_message(buf);
5430     + }
5431     +
5432     +/*log_script:*/
5433     + /* script logging activaed? */
5434     + if (((SPG(log_script) & loglevel)!=0) && SPG(log_scriptname)!=NULL) {
5435     + char cmd[8192], *cmdpos, *bufpos;
5436     + FILE *in;
5437     + int space;
5438     +
5439     + ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", SPG(log_scriptname), loglevel2string(loglevel));
5440     + space = sizeof(cmd) - strlen(cmd);
5441     + cmdpos = cmd + strlen(cmd);
5442     + bufpos = buf;
5443     + if (space <= 1) return;
5444     + while (space > 2 && *bufpos) {
5445     + if (*bufpos == '\'') {
5446     + if (space<=5) break;
5447     + *cmdpos++ = '\'';
5448     + *cmdpos++ = '\\';
5449     + *cmdpos++ = '\'';
5450     + *cmdpos++ = '\'';
5451     + bufpos++;
5452     + space-=4;
5453     + } else {
5454     + *cmdpos++ = *bufpos++;
5455     + space--;
5456     + }
5457     + }
5458     + *cmdpos++ = '\'';
5459     + *cmdpos = 0;
5460     +
5461     + if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
5462     + php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", SPG(log_scriptname));
5463     + return;
5464     + }
5465     + /* read and forget the result */
5466     + while (1) {
5467     + int readbytes = fread(cmd, 1, sizeof(cmd), in);
5468     + if (readbytes<=0) {
5469     + break;
5470     + }
5471     + }
5472     + pclose(in);
5473     + }
5474     +/*log_phpscript:*/
5475     + if ((SPG(log_phpscript) & loglevel)!=0 && EG(in_execution) && SPG(log_phpscriptname) && SPG(log_phpscriptname)[0]) {
5476     + zend_file_handle file_handle;
5477     + zend_op_array *new_op_array;
5478     + zval *result = NULL;
5479     +
5480     + /*long orig_execution_depth = SPG(execution_depth);*/
5481     + zend_bool orig_safe_mode = PG(safe_mode);
5482     + char *orig_basedir = PG(open_basedir);
5483     +
5484     + char *phpscript = SPG(log_phpscriptname);
5485     +/*SDEBUG("scriptname %s", SPG(log_phpscriptname));`*/
5486     +#ifdef ZEND_ENGINE_2
5487     + if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) {
5488     +#else
5489     + if (zend_open(phpscript, &file_handle) == SUCCESS && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
5490     + file_handle.filename = phpscript;
5491     + file_handle.free_filename = 0;
5492     +#endif
5493     + if (!file_handle.opened_path) {
5494     + file_handle.opened_path = estrndup(phpscript, strlen(phpscript));
5495     + }
5496     + new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
5497     + zend_destroy_file_handle(&file_handle TSRMLS_CC);
5498     + if (new_op_array) {
5499     + HashTable *active_symbol_table = EG(active_symbol_table);
5500     + zval *zerror, *zerror_class;
5501     +
5502     + if (active_symbol_table == NULL) {
5503     + active_symbol_table = &EG(symbol_table);
5504     + }
5505     + EG(return_value_ptr_ptr) = &result;
5506     + EG(active_op_array) = new_op_array;
5507     +
5508     + MAKE_STD_ZVAL(zerror);
5509     + MAKE_STD_ZVAL(zerror_class);
5510     + ZVAL_STRING(zerror, buf, 1);
5511     + ZVAL_LONG(zerror_class, loglevel);
5512     +
5513     + zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL);
5514     + zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL);
5515     +
5516     + /*SPG(execution_depth) = 0;*/
5517     + if (SPG(log_phpscript_is_safe)) {
5518     + PG(safe_mode) = 0;
5519     + PG(open_basedir) = NULL;
5520     + }
5521     +
5522     + zend_execute(new_op_array TSRMLS_CC);
5523     +
5524     + /*SPG(execution_depth) = orig_execution_depth;*/
5525     + PG(safe_mode) = orig_safe_mode;
5526     + PG(open_basedir) = orig_basedir;
5527     +
5528     +#ifdef ZEND_ENGINE_2
5529     + destroy_op_array(new_op_array TSRMLS_CC);
5530     +#else
5531     + destroy_op_array(new_op_array);
5532     +#endif
5533     + efree(new_op_array);
5534     +#ifdef ZEND_ENGINE_2
5535     + if (!EG(exception))
5536     +#endif
5537     + {
5538     + if (EG(return_value_ptr_ptr)) {
5539     + zval_ptr_dtor(EG(return_value_ptr_ptr));
5540     + EG(return_value_ptr_ptr) = NULL;
5541     + }
5542     + }
5543     + } else {
5544     + php_security_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SPG(log_phpscriptname));
5545     + return;
5546     + }
5547     + } else {
5548     + php_security_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SPG(log_phpscriptname));
5549     + return;
5550     + }
5551     + }
5552     +
5553     +}
5554     +
5555     +
5556     +#endif
5557     +
5558     +/*
5559     + * Local variables:
5560     + * tab-width: 4
5561     + * c-basic-offset: 4
5562     + * End:
5563     + * vim600: sw=4 ts=4 fdm=marker
5564     + * vim<600: sw=4 ts=4
5565     + */
5566     diff -Nura php-5.3.9/main/suhosin_patch.h suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.h
5567     --- php-5.3.9/main/suhosin_patch.h 1970-01-01 01:00:00.000000000 +0100
5568     +++ suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.h 2012-01-11 19:29:08.000000000 +0100
5569     @@ -0,0 +1,59 @@
5570     +/*
5571     + +----------------------------------------------------------------------+
5572     + | Suhosin Patch for PHP |
5573     + +----------------------------------------------------------------------+
5574     + | Copyright (c) 2004-2010 Stefan Esser |
5575     + +----------------------------------------------------------------------+
5576     + | This source file is subject to version 2.02 of the PHP license, |
5577     + | that is bundled with this package in the file LICENSE, and is |
5578     + | available at through the world-wide-web at |
5579     + | http://www.php.net/license/2_02.txt. |
5580     + | If you did not receive a copy of the PHP license and are unable to |
5581     + | obtain it through the world-wide-web, please send a note to |
5582     + | license@php.net so we can mail you a copy immediately. |
5583     + +----------------------------------------------------------------------+
5584     + | Author: Stefan Esser <stefan.esser@sektioneins.de> |
5585     + +----------------------------------------------------------------------+
5586     + */
5587     +
5588     +#ifndef SUHOSIN_PATCH_H
5589     +#define SUHOSIN_PATCH_H
5590     +
5591     +#if SUHOSIN_PATCH
5592     +
5593     +#include "zend.h"
5594     +
5595     +#define SUHOSIN_PATCH_VERSION "0.9.10"
5596     +
5597     +#define SUHOSIN_LOGO_GUID "SUHO8567F54-D428-14d2-A769-00DA302A5F18"
5598     +
5599     +#define SUHOSIN_CONFIG(idx) (suhosin_get_config(idx))
5600     +
5601     +#define SUHOSIN_MM_USE_CANARY_PROTECTION 0
5602     +#define SUHOSIN_MM_DESTROY_FREE_MEMORY 1
5603     +#define SUHOSIN_MM_IGNORE_CANARY_VIOLATION 2
5604     +#define SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR 3
5605     +#define SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR 4
5606     +
5607     +#define SUHOSIN_CONFIG_SET 100
5608     +
5609     +#include <sys/types.h>
5610     +#include <sys/stat.h>
5611     +#include <sys/mman.h>
5612     +
5613     +#if defined(DARWIN)
5614     +#include <mach/vm_param.h>
5615     +#endif
5616     +
5617     +#define SUHOSIN_MANGLE_PTR(ptr) (ptr==NULL?NULL:((void *)((zend_intptr_t)(ptr)^SUHOSIN_POINTER_GUARD)))
5618     +
5619     +#endif
5620     +
5621     +#endif /* SUHOSIN_PATCH_H */
5622     +
5623     +/*
5624     + * Local variables:
5625     + * tab-width: 4
5626     + * c-basic-offset: 4
5627     + * End:
5628     + */
5629     diff -Nura php-5.3.9/main/suhosin_patch.m4 suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.m4
5630     --- php-5.3.9/main/suhosin_patch.m4 1970-01-01 01:00:00.000000000 +0100
5631     +++ suhosin-patch-5.3.9-0.9.10/main/suhosin_patch.m4 2012-01-11 19:29:08.000000000 +0100
5632     @@ -0,0 +1,8 @@
5633     +dnl
5634     +dnl $Id: suhosin_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
5635     +dnl
5636     +dnl This file contains Suhosin Patch for PHP specific autoconf functions.
5637     +dnl
5638     +
5639     +AC_DEFINE(SUHOSIN_PATCH, 1, [Suhosin Patch])
5640     +
5641     diff -Nura php-5.3.9/sapi/apache/mod_php5.c suhosin-patch-5.3.9-0.9.10/sapi/apache/mod_php5.c
5642     --- php-5.3.9/sapi/apache/mod_php5.c 2012-01-01 14:15:04.000000000 +0100
5643     +++ suhosin-patch-5.3.9-0.9.10/sapi/apache/mod_php5.c 2012-01-11 19:29:08.000000000 +0100
5644     @@ -969,7 +969,11 @@
5645     {
5646     TSRMLS_FETCH();
5647     if (PG(expose_php)) {
5648     +#if SUHOSIN_PATCH
5649     + ap_add_version_component("PHP/" PHP_VERSION " with Suhosin-Patch");
5650     +#else
5651     ap_add_version_component("PHP/" PHP_VERSION);
5652     +#endif
5653     }
5654     }
5655     #endif
5656     diff -Nura php-5.3.9/sapi/apache2filter/sapi_apache2.c suhosin-patch-5.3.9-0.9.10/sapi/apache2filter/sapi_apache2.c
5657     --- php-5.3.9/sapi/apache2filter/sapi_apache2.c 2012-01-01 14:15:04.000000000 +0100
5658     +++ suhosin-patch-5.3.9-0.9.10/sapi/apache2filter/sapi_apache2.c 2012-01-11 19:29:08.000000000 +0100
5659     @@ -583,7 +583,11 @@
5660     {
5661     TSRMLS_FETCH();
5662     if (PG(expose_php)) {
5663     +#if SUHOSIN_PATCH
5664     + ap_add_version_component(p, "PHP/" PHP_VERSION " with Suhosin-Patch");
5665     +#else
5666     ap_add_version_component(p, "PHP/" PHP_VERSION);
5667     +#endif
5668     }
5669     }
5670    
5671     diff -Nura php-5.3.9/sapi/apache2handler/sapi_apache2.c suhosin-patch-5.3.9-0.9.10/sapi/apache2handler/sapi_apache2.c
5672     --- php-5.3.9/sapi/apache2handler/sapi_apache2.c 2012-01-01 14:15:04.000000000 +0100
5673     +++ suhosin-patch-5.3.9-0.9.10/sapi/apache2handler/sapi_apache2.c 2012-01-11 19:29:08.000000000 +0100
5674     @@ -407,7 +407,11 @@
5675     {
5676     TSRMLS_FETCH();
5677     if (PG(expose_php)) {
5678     +#if SUHOSIN_PATCH
5679     + ap_add_version_component(p, "PHP/" PHP_VERSION " with Suhosin-Patch");
5680     +#else
5681     ap_add_version_component(p, "PHP/" PHP_VERSION);
5682     +#endif
5683     }
5684     }
5685    
5686     diff -Nura php-5.3.9/sapi/apache_hooks/mod_php5.c suhosin-patch-5.3.9-0.9.10/sapi/apache_hooks/mod_php5.c
5687     --- php-5.3.9/sapi/apache_hooks/mod_php5.c 2012-01-01 14:15:04.000000000 +0100
5688     +++ suhosin-patch-5.3.9-0.9.10/sapi/apache_hooks/mod_php5.c 2012-01-11 19:29:08.000000000 +0100
5689     @@ -1256,7 +1256,11 @@
5690     {
5691     TSRMLS_FETCH();
5692     if (PG(expose_php)) {
5693     +#if SUHOSIN_PATCH
5694     + ap_add_version_component("PHP/" PHP_VERSION " with Suhosin-Patch");
5695     +#else
5696     ap_add_version_component("PHP/" PHP_VERSION);
5697     +#endif
5698     }
5699     }
5700     #endif
5701     diff -Nura php-5.3.9/sapi/cgi/cgi_main.c suhosin-patch-5.3.9-0.9.10/sapi/cgi/cgi_main.c
5702     --- php-5.3.9/sapi/cgi/cgi_main.c 2012-01-01 14:15:04.000000000 +0100
5703     +++ suhosin-patch-5.3.9-0.9.10/sapi/cgi/cgi_main.c 2012-01-11 19:36:52.000000000 +0100
5704     @@ -1932,11 +1932,19 @@
5705     SG(headers_sent) = 1;
5706     SG(request_info).no_headers = 1;
5707     }
5708     +#if SUHOSIN_PATCH
5709     +#if ZEND_DEBUG
5710     + php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5711     +#else
5712     + php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5713     +#endif
5714     +#else
5715     #if ZEND_DEBUG
5716     php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5717     #else
5718     php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5719     #endif
5720     +#endif
5721     php_request_shutdown((void *) 0);
5722     fcgi_shutdown();
5723     exit_status = 0;
5724     diff -Nura php-5.3.9/sapi/cli/php_cli.c suhosin-patch-5.3.9-0.9.10/sapi/cli/php_cli.c
5725     --- php-5.3.9/sapi/cli/php_cli.c 2012-01-01 14:15:04.000000000 +0100
5726     +++ suhosin-patch-5.3.9-0.9.10/sapi/cli/php_cli.c 2012-01-11 19:35:06.000000000 +0100
5727     @@ -826,7 +826,11 @@
5728     }
5729    
5730     request_started = 1;
5731     - php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2012 The PHP Group\n%s",
5732     + php_printf("PHP %s "
5733     +#if SUHOSIN_PATCH
5734     + "with Suhosin-Patch "
5735     +#endif
5736     + "(%s) (built: %s %s) %s\nCopyright (c) 1997-2012 The PHP Group\n%s",
5737     PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
5738     #if ZEND_DEBUG && defined(HAVE_GCOV)
5739     "(DEBUG GCOV)",
5740     diff -Nura php-5.3.9/sapi/litespeed/lsapi_main.c suhosin-patch-5.3.9-0.9.10/sapi/litespeed/lsapi_main.c
5741     --- php-5.3.9/sapi/litespeed/lsapi_main.c 2011-12-31 19:15:06.000000000 +0100
5742     +++ suhosin-patch-5.3.9-0.9.10/sapi/litespeed/lsapi_main.c 2012-01-11 19:29:08.000000000 +0100
5743     @@ -718,11 +718,19 @@
5744     break;
5745     case 'v':
5746     if (php_request_startup(TSRMLS_C) != FAILURE) {
5747     +#if SUHOSIN_PATCH
5748     + #if ZEND_DEBUG
5749     + php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5750     + #else
5751     + php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5752     + #endif
5753     +#else
5754     #if ZEND_DEBUG
5755     php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5756     #else
5757     php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5758     #endif
5759     +#endif
5760     #ifdef PHP_OUTPUT_NEWAPI
5761     php_output_end_all(TSRMLS_C);
5762     #else
5763     diff -Nura php-5.3.9/sapi/milter/php_milter.c suhosin-patch-5.3.9-0.9.10/sapi/milter/php_milter.c
5764     --- php-5.3.9/sapi/milter/php_milter.c 2012-01-01 14:15:04.000000000 +0100
5765     +++ suhosin-patch-5.3.9-0.9.10/sapi/milter/php_milter.c 2012-01-11 19:33:42.000000000 +0100
5766     @@ -1111,7 +1111,11 @@
5767     }
5768     SG(headers_sent) = 1;
5769     SG(request_info).no_headers = 1;
5770     +#if SUHOSIN_PATCH
5771     + php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5772     +#else
5773     php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5774     +#endif
5775     php_end_ob_buffers(1 TSRMLS_CC);
5776     exit(1);
5777     break;
5778     diff -Nura php-5.3.9/win32/build/config.w32 suhosin-patch-5.3.9-0.9.10/win32/build/config.w32
5779     --- php-5.3.9/win32/build/config.w32 2011-03-28 12:55:34.000000000 +0200
5780     +++ suhosin-patch-5.3.9-0.9.10/win32/build/config.w32 2012-01-11 19:29:08.000000000 +0100
5781     @@ -328,7 +328,7 @@
5782     zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
5783     zend_object_handlers.c zend_objects_API.c \
5784     zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
5785     - zend_float.c");
5786     + zend_float.c zend_canary.c zend_alloc_canary.c");
5787    
5788     if (VCVERS == 1200) {
5789     AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
5790     @@ -385,6 +385,7 @@
5791    
5792     AC_DEFINE('HAVE_USLEEP', 1);
5793     AC_DEFINE('HAVE_STRCOLL', 1);
5794     +AC_DEFINE('SUHOSIN_PATCH', 1);
5795    
5796     /* For snapshot builders, where can we find the additional
5797     * files that make up the snapshot template? */
5798     diff -Nura php-5.3.9/win32/build/config.w32.h.in suhosin-patch-5.3.9-0.9.10/win32/build/config.w32.h.in
5799     --- php-5.3.9/win32/build/config.w32.h.in 2010-11-26 19:25:13.000000000 +0100
5800     +++ suhosin-patch-5.3.9-0.9.10/win32/build/config.w32.h.in 2012-01-11 19:29:08.000000000 +0100
5801     @@ -152,6 +152,9 @@
5802     /* Win32 supports strcoll */
5803     #define HAVE_STRCOLL 1
5804    
5805     +/* Suhosin Patch support */
5806     +#define SUHOSIN_PATCH 1
5807     +
5808     /* Win32 supports socketpair by the emulation in win32/sockets.c */
5809     #define HAVE_SOCKETPAIR 1
5810     #define HAVE_SOCKLEN_T 1