]> git.pld-linux.org Git - packages/php.git/blame - suhosin.patch
- up to php-5.3.2RC3
[packages/php.git] / suhosin.patch
CommitLineData
65be62f2
ER
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@
65be62f2
ER
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
65be62f2
ER
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
65be62f2
ER
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)
65be62f2
ER
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 /*
65be62f2
ER
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
65be62f2
ER
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:
65be62f2
ER
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);
65be62f2
ER
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+
65be62f2
ER
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+ */
65be62f2
ER
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];
65be62f2
ER
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 */
65be62f2
ER
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;
65be62f2
ER
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 /*
65be62f2
ER
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 }
65be62f2
ER
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;
65be62f2
ER
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));
65be62f2
ER
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:
65be62f2
ER
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
65be62f2
ER
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)
65be62f2
ER
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 /* }}} */
65be62f2
ER
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) {
65be62f2
ER
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;
65be62f2
ER
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 */
65be62f2
ER
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
65be62f2
ER
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 /*
65be62f2
ER
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
65be62f2
ER
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)
552732b5 4393@@ -63,6 +63,9 @@
65be62f2
ER
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));
552732b5 4396 php_register_info_logo(PLD_LOGO_GUID , "image/png", pld_logo , sizeof(pld_logo));
65be62f2 4397+#if SUHOSIN_PATCH
552732b5 4398+ php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo , sizeof(suhosin_logo));
65be62f2 4399+#endif
552732b5 4400
65be62f2
ER
4401 return SUCCESS;
4402 }
65be62f2
ER
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 /*
65be62f2
ER
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 /*
65be62f2
ER
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+ */
65be62f2
ER
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+ ;
65be62f2
ER
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+ */
65be62f2
ER
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+ */
65be62f2
ER
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+
65be62f2
ER
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
65be62f2
ER
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
65be62f2
ER
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
65be62f2
ER
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
25e7e080
ER
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 @@
65be62f2
ER
5273 SG(headers_sent) = 1;
5274 SG(request_info).no_headers = 1;
5275 }
5276+#if SUHOSIN_PATCH
5277+#if ZEND_DEBUG
25e7e080 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());
65be62f2 5279+#else
25e7e080 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());
65be62f2
ER
5281+#endif
5282+#else
5283 #if ZEND_DEBUG
25e7e080 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());
65be62f2 5285 #else
25e7e080 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());
65be62f2
ER
5287 #endif
5288+#endif
5289 php_request_shutdown((void *) 0);
5290 exit_status = 0;
5291 goto out;
25e7e080
ER
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 @@
65be62f2
ER
5295 }
5296
5297 request_started = 1;
25e7e080 5298- php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2010 The PHP Group\n%s",
65be62f2
ER
5299+ php_printf("PHP %s "
5300+#if SUHOSIN_PATCH
5301+ "with Suhosin-Patch "
5302+#endif
25e7e080 5303+ "(%s) (built: %s %s) %s\nCopyright (c) 1997-2010 The PHP Group\n%s",
65be62f2
ER
5304 PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
5305 #if ZEND_DEBUG && defined(HAVE_GCOV)
5306 "(DEBUG GCOV)",
65be62f2
ER
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
25e7e080
ER
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
65be62f2
ER
5331@@ -1102,7 +1102,11 @@
5332 }
5333 SG(headers_sent) = 1;
5334 SG(request_info).no_headers = 1;
5335+#if SUHOSIN_PATCH
25e7e080 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());
65be62f2 5337+#else
25e7e080 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());
65be62f2
ER
5339+#endif
5340 php_end_ob_buffers(1 TSRMLS_CC);
5341 exit(1);
5342 break;
65be62f2
ER
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? */
65be62f2
ER
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 1.017071 seconds and 4 git commands to generate.