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