Magellan Linux

Annotation of /trunk/php5/patches/php5-5.3.0-suhosin-0.9.8.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 933 - (hide annotations) (download)
Tue Nov 17 11:39:50 2009 UTC (14 years, 6 months ago) by niro
File size: 181916 byte(s)
suhosin for 5.3.0

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