Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 411935
Collapse All | Expand All

(-)php-5.3.9/Zend/Makefile.am (-1 / +1 lines)
Lines 17-23 Link Here
17
	zend_objects_API.c zend_ts_hash.c zend_stream.c \
17
	zend_objects_API.c zend_ts_hash.c zend_stream.c \
18
	zend_default_classes.c \
18
	zend_default_classes.c \
19
	zend_iterators.c zend_interfaces.c zend_exceptions.c \
19
	zend_iterators.c zend_interfaces.c zend_exceptions.c \
20
	zend_strtod.c zend_closures.c zend_float.c
20
	zend_strtod.c zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c 
21
21
22
libZend_la_LDFLAGS =
22
libZend_la_LDFLAGS =
23
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
23
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
(-)php-5.3.9/Zend/Zend.dsp (+8 lines)
Lines 247-252 Link Here
247
# End Source File
247
# End Source File
248
# Begin Source File
248
# Begin Source File
249
249
250
SOURCE=.\zend_canary.c
251
# End Source File
252
# Begin Source File
253
254
SOURCE=.\zend_alloc_canary.c
255
# End Source File
256
# Begin Source File
257
250
SOURCE=.\zend_ts_hash.c
258
SOURCE=.\zend_ts_hash.c
251
# End Source File
259
# End Source File
252
# Begin Source File
260
# Begin Source File
(-)php-5.3.9/Zend/ZendTS.dsp (+8 lines)
Lines 277-282 Link Here
277
# End Source File
277
# End Source File
278
# Begin Source File
278
# Begin Source File
279
279
280
SOURCE=.\zend_canary.c
281
# End Source File
282
# Begin Source File
283
284
SOURCE=.\zend_alloc_canary.c
285
# End Source File
286
# Begin Source File
287
280
SOURCE=.\zend_ts_hash.c
288
SOURCE=.\zend_ts_hash.c
281
# End Source File
289
# End Source File
282
# Begin Source File
290
# Begin Source File
(-)php-5.3.9/Zend/zend.c (+72 lines)
Lines 60-65 Link Here
60
ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
60
ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
61
ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
61
ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
62
62
63
#if SUHOSIN_PATCH
64
ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
65
#endif
66
63
void (*zend_on_timeout)(int seconds TSRMLS_DC);
67
void (*zend_on_timeout)(int seconds TSRMLS_DC);
64
68
65
static void (*zend_message_dispatcher_p)(long message, void *data TSRMLS_DC);
69
static void (*zend_message_dispatcher_p)(long message, void *data TSRMLS_DC);
Lines 88-93 Link Here
88
}
92
}
89
/* }}} */
93
/* }}} */
90
94
95
#if SUHOSIN_PATCH
96
static ZEND_INI_MH(OnUpdateSuhosin_log_syslog)
97
{
98
	if (!new_value) {
99
		SPG(log_syslog) = S_ALL & ~S_SQL | S_MEMORY;
100
	} else {
101
		SPG(log_syslog) = atoi(new_value) | S_MEMORY;
102
	}
103
	return SUCCESS;
104
}
105
static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_facility)
106
{
107
	if (!new_value) {
108
		SPG(log_syslog_facility) = LOG_USER;
109
	} else {
110
		SPG(log_syslog_facility) = atoi(new_value);
111
	}
112
	return SUCCESS;
113
}
114
static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_priority)
115
{
116
	if (!new_value) {
117
		SPG(log_syslog_priority) = LOG_ALERT;
118
	} else {
119
		SPG(log_syslog_priority) = atoi(new_value);
120
	}
121
	return SUCCESS;
122
}
123
static ZEND_INI_MH(OnUpdateSuhosin_log_sapi)
124
{
125
	if (!new_value) {
126
		SPG(log_sapi) = S_ALL & ~S_SQL;
127
	} else {
128
		SPG(log_sapi) = atoi(new_value);
129
	}
130
	return SUCCESS;
131
}
132
static ZEND_INI_MH(OnUpdateSuhosin_log_script)
133
{
134
	if (!new_value) {
135
		SPG(log_script) = S_ALL & ~S_MEMORY;
136
	} else {
137
		SPG(log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
138
	}
139
	return SUCCESS;
140
}
141
static ZEND_INI_MH(OnUpdateSuhosin_log_scriptname)
142
{
143
	if (SPG(log_scriptname)) {
144
		pefree(SPG(log_scriptname),1);
145
	}
146
        SPG(log_scriptname) = NULL;
147
	if (new_value) {
148
		SPG(log_scriptname) = pestrdup(new_value,1);
149
	}
150
	return SUCCESS;
151
}
152
static ZEND_INI_MH(OnUpdateSuhosin_log_phpscript)
153
{
154
	if (!new_value) {
155
		SPG(log_phpscript) = S_ALL & ~S_MEMORY;
156
	} else {
157
		SPG(log_phpscript) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
158
	}
159
	return SUCCESS;
160
}
161
#endif
162
91
ZEND_INI_BEGIN()
163
ZEND_INI_BEGIN()
92
	ZEND_INI_ENTRY("error_reporting",				NULL,		ZEND_INI_ALL,		OnUpdateErrorReporting)
164
	ZEND_INI_ENTRY("error_reporting",				NULL,		ZEND_INI_ALL,		OnUpdateErrorReporting)
93
	STD_ZEND_INI_BOOLEAN("zend.enable_gc",				"1",	ZEND_INI_ALL,		OnUpdateGCEnabled,      gc_enabled,     zend_gc_globals,        gc_globals)
165
	STD_ZEND_INI_BOOLEAN("zend.enable_gc",				"1",	ZEND_INI_ALL,		OnUpdateGCEnabled,      gc_enabled,     zend_gc_globals,        gc_globals)
(-)php-5.3.9/Zend/zend.h (+13 lines)
Lines 627-632 Link Here
627
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
627
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
628
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
628
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
629
extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
629
extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
630
#if SUHOSIN_PATCH
631
extern ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
632
#endif
630
633
631
ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
634
ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
632
635
Lines 774-779 Link Here
774
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
777
#define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0)
775
#define DEBUG_BACKTRACE_IGNORE_ARGS    (1<<1)
778
#define DEBUG_BACKTRACE_IGNORE_ARGS    (1<<1)
776
779
780
#if SUHOSIN_PATCH
781
#include "suhosin_globals.h"
782
#include "suhosin_patch.h"
783
#include "php_syslog.h"
784
785
ZEND_API void zend_canary(void *buf, int len);
786
ZEND_API char suhosin_get_config(int element);
787
788
#endif
789
777
#endif /* ZEND_H */
790
#endif /* ZEND_H */
778
791
779
/*
792
/*
(-)php-5.3.9/Zend/zend_alloc.c (-75 / +358 lines)
Lines 32-37 Link Here
32
# include <unistd.h>
32
# include <unistd.h>
33
#endif
33
#endif
34
34
35
#if SUHOSIN_PATCH
36
#include "suhosin_patch.h"
37
#endif
38
35
#ifdef ZEND_WIN32
39
#ifdef ZEND_WIN32
36
# include <wincrypt.h>
40
# include <wincrypt.h>
37
# include <process.h>
41
# include <process.h>
Lines 59-64 Link Here
59
# define PTR_FMT "0x%0.8lx"
63
# define PTR_FMT "0x%0.8lx"
60
#endif
64
#endif
61
65
66
#ifndef SUHOSIN_MM_CLONE_FILE
62
#if ZEND_DEBUG
67
#if ZEND_DEBUG
63
void zend_debug_alloc_output(char *format, ...)
68
void zend_debug_alloc_output(char *format, ...)
64
{
69
{
Lines 76-81 Link Here
76
#endif
81
#endif
77
}
82
}
78
#endif
83
#endif
84
#endif
79
85
80
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
86
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
81
static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
87
static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
Lines 134-139 Link Here
134
# endif
140
# endif
135
#endif
141
#endif
136
142
143
static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
144
137
static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
145
static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
138
{
146
{
139
	return malloc(sizeof(zend_mm_storage));
147
	return malloc(sizeof(zend_mm_storage));
Lines 332-344 Link Here
332
#define	MEM_BLOCK_GUARD  0x2A8FCC84
340
#define	MEM_BLOCK_GUARD  0x2A8FCC84
333
#define	MEM_BLOCK_LEAK   0x6C5E8F2D
341
#define	MEM_BLOCK_LEAK   0x6C5E8F2D
334
342
343
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
344
# define CANARY_SIZE sizeof(size_t)
345
#else
346
# define CANARY_SIZE 0
347
#endif
348
335
/* mm block type */
349
/* mm block type */
336
typedef struct _zend_mm_block_info {
350
typedef struct _zend_mm_block_info {
337
#if ZEND_MM_COOKIES
351
#if ZEND_MM_COOKIES
338
	size_t _cookie;
352
	size_t _cookie;
339
#endif
353
#endif
340
	size_t _size;
354
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
341
	size_t _prev;
355
	size_t canary_1;
356
#endif
357
  	size_t _size;
358
  	size_t _prev;
359
#if SUHOSIN_PATCH
360
	size_t size;
361
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
362
	size_t canary_2;
363
#endif
364
#endif
342
} zend_mm_block_info;
365
} zend_mm_block_info;
343
366
344
#if ZEND_DEBUG
367
#if ZEND_DEBUG
Lines 412-418 Link Here
412
# define ZEND_MM_CACHE_STAT 0
435
# define ZEND_MM_CACHE_STAT 0
413
#endif
436
#endif
414
437
415
struct _zend_mm_heap {
438
typedef struct _zend_mm_heap {
416
	int                 use_zend_alloc;
439
	int                 use_zend_alloc;
417
	void               *(*_malloc)(size_t);
440
	void               *(*_malloc)(size_t);
418
	void                (*_free)(void*);
441
	void                (*_free)(void*);
Lines 447-452 Link Here
447
		int miss;
470
		int miss;
448
	} cache_stat[ZEND_MM_NUM_BUCKETS+1];
471
	} cache_stat[ZEND_MM_NUM_BUCKETS+1];
449
#endif
472
#endif
473
#if SUHOSIN_PATCH
474
 	size_t              canary_1,canary_2,canary_3;
475
#endif
450
};
476
};
451
477
452
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
478
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
Lines 520-537 Link Here
520
/* optimized access */
546
/* optimized access */
521
#define ZEND_MM_FREE_BLOCK_SIZE(b)		(b)->info._size
547
#define ZEND_MM_FREE_BLOCK_SIZE(b)		(b)->info._size
522
548
549
#ifndef ZEND_MM_ALIGNMENT
550
# define ZEND_MM_ALIGNMENT 8
551
# define ZEND_MM_ALIGNMENT_LOG2 3
552
#elif ZEND_MM_ALIGNMENT < 4
553
# undef ZEND_MM_ALIGNMENT
554
# undef ZEND_MM_ALIGNMENT_LOG2
555
# define ZEND_MM_ALIGNMENT 4
556
# define ZEND_MM_ALIGNMENT_LOG2 2
557
#endif
558
559
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
560
523
/* Aligned header size */
561
/* Aligned header size */
562
#define ZEND_MM_ALIGNED_SIZE(size)			((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
524
#define ZEND_MM_ALIGNED_HEADER_SIZE			ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
563
#define ZEND_MM_ALIGNED_HEADER_SIZE			ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
525
#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE	ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
564
#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE	ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
526
#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE		ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE)
565
#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE		ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)
527
#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)
566
#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)
528
#define ZEND_MM_ALIGNED_SEGMENT_SIZE		ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
567
#define ZEND_MM_ALIGNED_SEGMENT_SIZE		ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
529
568
530
#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)
569
#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)
531
570
532
#define ZEND_MM_MAX_SMALL_SIZE				((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
571
#define ZEND_MM_MAX_SMALL_SIZE				((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
533
572
534
#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)))
573
#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)))
535
574
536
#define ZEND_MM_BUCKET_INDEX(true_size)		((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
575
#define ZEND_MM_BUCKET_INDEX(true_size)		((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
537
576
Lines 593-598 Link Here
593
632
594
#endif
633
#endif
595
634
635
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
636
637
# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \
638
        char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \
639
	if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \
640
		canary_mismatch: \
641
		zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
642
                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; }\
643
	} \
644
        memcpy(&check, p, CANARY_SIZE); \
645
        if (check != heap->canary_3) { \
646
                zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
647
                if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \
648
        } \
649
	} while (0)
650
651
# define SUHOSIN_MM_SET_CANARIES(block) do { \
652
        (block)->info.canary_1 = heap->canary_1; \
653
        (block)->info.canary_2 = heap->canary_2; \
654
        } while (0)      
655
656
# define SUHOSIN_MM_END_CANARY_PTR(block) \
657
	(char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block*)(block))->info.size + END_MAGIC_SIZE)
658
659
# define SUHOSIN_MM_SET_END_CANARY(block) do { \
660
	char *p = SUHOSIN_MM_END_CANARY_PTR(block); \
661
	memcpy(p, &heap->canary_3, CANARY_SIZE); \
662
	} while (0)
663
664
#else
665
666
# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION)
667
# define SUHOSIN_MM_SET_CANARIES(block)
668
# define SUHOSIN_MM_END_CANARY_PTR(block)
669
# define SUHOSIN_MM_SET_END_CANARY(block)
670
671
#endif
672
596
673
597
#if ZEND_MM_HEAP_PROTECTION
674
#if ZEND_MM_HEAP_PROTECTION
598
675
Lines 715-721 Link Here
715
#endif
792
#endif
716
}
793
}
717
794
718
static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
795
static void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
719
{
796
{
720
	zend_mm_free_block *prev, *next;
797
	zend_mm_free_block *prev, *next;
721
798
Lines 725-738 Link Here
725
		mm_block->parent = NULL;
802
		mm_block->parent = NULL;
726
	}
803
	}
727
804
728
	prev = heap->rest_buckets[0];
805
	prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
729
	next = prev->next_free_block;
806
	next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
730
	mm_block->prev_free_block = prev;
807
	mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
731
	mm_block->next_free_block = next;
808
	mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
732
	prev->next_free_block = next->prev_free_block = mm_block;
809
	prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
733
}
810
}
734
811
735
static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
812
static void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
736
{
813
{
737
	size_t size;
814
	size_t size;
738
	size_t index;
815
	size_t index;
Lines 749-755 Link Here
749
		if (!*p) {
826
		if (!*p) {
750
			*p = mm_block;
827
			*p = mm_block;
751
			mm_block->parent = p;
828
			mm_block->parent = p;
752
			mm_block->prev_free_block = mm_block->next_free_block = mm_block;
829
			mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
753
			heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
830
			heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
754
		} else {
831
		} else {
755
			size_t m;
832
			size_t m;
Lines 762-776 Link Here
762
					if (!*p) {
839
					if (!*p) {
763
						*p = mm_block;
840
						*p = mm_block;
764
						mm_block->parent = p;
841
						mm_block->parent = p;
765
						mm_block->prev_free_block = mm_block->next_free_block = mm_block;
842
						mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
766
						break;
843
						break;
767
					}
844
					}
768
				} else {
845
				} else {
769
					zend_mm_free_block *next = prev->next_free_block;
846
					zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
770
847
771
					prev->next_free_block = next->prev_free_block = mm_block;
848
					prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
772
					mm_block->next_free_block = next;
849
					mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
773
					mm_block->prev_free_block = prev;
850
					mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
774
					mm_block->parent = NULL;
851
					mm_block->parent = NULL;
775
					break;
852
					break;
776
				}
853
				}
Lines 782-808 Link Here
782
		index = ZEND_MM_BUCKET_INDEX(size);
859
		index = ZEND_MM_BUCKET_INDEX(size);
783
860
784
		prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
861
		prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
785
		if (prev->prev_free_block == prev) {
862
		if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) {
786
			heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
863
			heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
787
		}
864
		}
788
		next = prev->next_free_block;
865
		next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
789
866
790
		mm_block->prev_free_block = prev;
867
		mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
791
		mm_block->next_free_block = next;
868
		mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
792
		prev->next_free_block = next->prev_free_block = mm_block;
869
		prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
793
	}
870
	}
794
}
871
}
795
872
796
static inline void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
873
static void zend_mm_remove_from_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
797
{
874
{
798
	zend_mm_free_block *prev = mm_block->prev_free_block;
875
	zend_mm_free_block *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
799
	zend_mm_free_block *next = mm_block->next_free_block;
876
	zend_mm_free_block *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block);
800
877
801
	ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
878
	ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
802
879
803
	if (EXPECTED(prev == mm_block)) {
880
	if (EXPECTED(prev == mm_block)) {
804
		zend_mm_free_block **rp, **cp;
881
		zend_mm_free_block **rp, **cp;
805
882
883
#if SUHOSIN_PATCH
884
                if (next != mm_block) {
885
                        zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block);
886
                        _exit(1);
887
                }
888
#endif
806
#if ZEND_MM_SAFE_UNLINKING
889
#if ZEND_MM_SAFE_UNLINKING
807
		if (UNEXPECTED(next != mm_block)) {
890
		if (UNEXPECTED(next != mm_block)) {
808
			zend_mm_panic("zend_mm_heap corrupted");
891
			zend_mm_panic("zend_mm_heap corrupted");
Lines 841-854 Link Here
841
		}
924
		}
842
	} else {
925
	} else {
843
926
927
#if SUHOSIN_PATCH
928
                if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) {
929
                        zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block);
930
		        _exit(1);
931
                }
932
#endif    
933
844
#if ZEND_MM_SAFE_UNLINKING
934
#if ZEND_MM_SAFE_UNLINKING
845
		if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block != mm_block)) {
935
		if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) {
846
			zend_mm_panic("zend_mm_heap corrupted");
936
			zend_mm_panic("zend_mm_heap corrupted");
847
		}
937
		}
848
#endif
938
#endif
849
939
850
		prev->next_free_block = next;
940
		prev->next_free_block = SUHOSIN_MANGLE_PTR(next);
851
		next->prev_free_block = prev;
941
		next->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
852
942
853
		if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
943
		if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
854
			if (EXPECTED(prev == next)) {
944
			if (EXPECTED(prev == next)) {
Lines 864-870 Link Here
864
	}
954
	}
865
}
955
}
866
956
867
static inline void zend_mm_init(zend_mm_heap *heap)
957
static void zend_mm_init(zend_mm_heap *heap)
868
{
958
{
869
	zend_mm_free_block* p;
959
	zend_mm_free_block* p;
870
	int i;
960
	int i;
Lines 882-893 Link Here
882
#endif
972
#endif
883
	p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
973
	p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
884
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
974
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
885
		p->next_free_block = p;
975
		p->next_free_block = SUHOSIN_MANGLE_PTR(p);
886
		p->prev_free_block = p;
976
		p->prev_free_block = SUHOSIN_MANGLE_PTR(p);
887
		p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
977
		p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
888
		heap->large_free_buckets[i] = NULL;
978
		heap->large_free_buckets[i] = NULL;
889
	}
979
	}
890
	heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
980
	heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap));
981
#if SUHOSIN_PATCH
982
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
983
	        zend_canary(&heap->canary_1, sizeof(heap->canary_1));
984
	        zend_canary(&heap->canary_2, sizeof(heap->canary_2));
985
	        zend_canary(&heap->canary_3, sizeof(heap->canary_3));
986
	}
987
#endif
891
}
988
}
892
989
893
static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
990
static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
Lines 908-919 Link Here
908
	int i;
1005
	int i;
909
1006
910
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
1007
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
1008
		/* NULL means NULL even MANGLED */
911
		if (heap->cache[i]) {
1009
		if (heap->cache[i]) {
912
			zend_mm_free_block *mm_block = heap->cache[i];
1010
			zend_mm_free_block *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]);
913
1011
914
			while (mm_block) {
1012
			while (mm_block) {
915
				size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
1013
				size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
916
				zend_mm_free_block *q = mm_block->prev_free_block;
1014
				zend_mm_free_block *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
917
				zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
1015
				zend_mm_block *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
918
1016
919
				heap->cached -= size;
1017
				heap->cached -= size;
Lines 1009-1022 Link Here
1009
/* }}} */
1107
/* }}} */
1010
#endif
1108
#endif
1011
1109
1110
1012
/* Notes:
1111
/* Notes:
1013
 * - This function may alter the block_sizes values to match platform alignment
1112
 * - This function may alter the block_sizes values to match platform alignment
1014
 * - This function does *not* perform sanity checks on the arguments
1113
 * - This function does *not* perform sanity checks on the arguments
1015
 */
1114
 */
1016
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)
1115
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1116
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)
1117
#else
1118
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)
1119
#endif
1017
{
1120
{
1018
	zend_mm_storage *storage;
1121
	zend_mm_storage *storage;
1019
	zend_mm_heap    *heap;
1122
	zend_mm_heap    *heap;
1123
        zend_mm_free_block *tmp;
1020
1124
1021
#if 0
1125
#if 0
1022
	int i;
1126
	int i;
Lines 1050-1055 Link Here
1050
	}
1154
	}
1051
#endif
1155
#endif
1052
1156
1157
        /* get the pointer guardian and ensure low 3 bits are 1 */
1158
        if (SUHOSIN_POINTER_GUARD == 0) {
1159
                zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
1160
                SUHOSIN_POINTER_GUARD |= 7;
1161
        }
1162
1053
	if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
1163
	if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
1054
		fprintf(stderr, "'block_size' must be a power of two\n");
1164
		fprintf(stderr, "'block_size' must be a power of two\n");
1055
/* See http://support.microsoft.com/kb/190351 */
1165
/* See http://support.microsoft.com/kb/190351 */
Lines 1077-1082 Link Here
1077
#endif
1187
#endif
1078
		exit(255);
1188
		exit(255);
1079
	}
1189
	}
1190
	
1080
	heap->storage = storage;
1191
	heap->storage = storage;
1081
	heap->block_size = block_size;
1192
	heap->block_size = block_size;
1082
	heap->compact_size = 0;
1193
	heap->compact_size = 0;
Lines 1097-1108 Link Here
1097
	heap->reserve = NULL;
1208
	heap->reserve = NULL;
1098
	heap->reserve_size = reserve_size;
1209
	heap->reserve_size = reserve_size;
1099
	if (reserve_size > 0) {
1210
	if (reserve_size > 0) {
1100
		heap->reserve = _zend_mm_alloc_int(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1211
		heap->reserve = _zend_mm_alloc(heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1101
	}
1212
	}
1102
	if (internal) {
1213
	if (internal) {
1103
		int i;
1214
		int i;
1104
		zend_mm_free_block *p, *q, *orig;
1215
		zend_mm_free_block *p, *q, *orig;
1105
		zend_mm_heap *mm_heap = _zend_mm_alloc_int(heap, sizeof(zend_mm_heap)  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1216
		zend_mm_heap *mm_heap = _zend_mm_alloc(heap, sizeof(zend_mm_heap)  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1106
1217
1107
		*mm_heap = *heap;
1218
		*mm_heap = *heap;
1108
1219
Lines 1110-1131 Link Here
1110
		orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
1221
		orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
1111
		for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
1222
		for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
1112
			q = p;
1223
			q = p;
1113
			while (q->prev_free_block != orig) {
1224
			while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) {
1114
				q = q->prev_free_block;
1225
				q = SUHOSIN_MANGLE_PTR(q->prev_free_block);
1115
			}
1226
			}
1116
			q->prev_free_block = p;
1227
			q->prev_free_block = SUHOSIN_MANGLE_PTR(p);
1117
			q = p;
1228
			q = p;
1118
			while (q->next_free_block != orig) {
1229
			while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) {
1119
				q = q->next_free_block;
1230
				q = SUHOSIN_MANGLE_PTR(q->next_free_block);
1120
			}
1231
			}
1121
			q->next_free_block = p;
1232
			q->next_free_block = SUHOSIN_MANGLE_PTR(p);
1122
			p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
1233
			p = (zend_mm_free_block*)((char*)p + sizeof(zend_mm_free_block*) * 2);
1123
			orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2);
1234
			orig = (zend_mm_free_block*)((char*)orig + sizeof(zend_mm_free_block*) * 2);
1124
			if (mm_heap->large_free_buckets[i]) {
1235
			if (mm_heap->large_free_buckets[i]) {
1125
				mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
1236
				mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
1126
			}
1237
			}
1127
		}
1238
		}
1128
		mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(mm_heap);
1239
		mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap));
1129
1240
1130
		free(heap);
1241
		free(heap);
1131
		heap = mm_heap;
1242
		heap = mm_heap;
Lines 1133-1139 Link Here
1133
	return heap;
1244
	return heap;
1134
}
1245
}
1135
1246
1136
ZEND_API zend_mm_heap *zend_mm_startup(void)
1247
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1248
zend_mm_heap *__zend_mm_startup_canary(void)
1249
#else
1250
static zend_mm_heap *__zend_mm_startup(void)
1251
#endif
1137
{
1252
{
1138
	int i;
1253
	int i;
1139
	size_t seg_size;
1254
	size_t seg_size;
Lines 1203-1208 Link Here
1203
	return heap;
1318
	return heap;
1204
}
1319
}
1205
1320
1321
#ifndef SUHOSIN_MM_CLONE_FILE
1322
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);
1323
zend_mm_heap_canary *__zend_mm_startup_canary(void);
1324
1325
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)
1326
{
1327
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
1328
                return (zend_mm_heap *)__zend_mm_startup_canary_ex(handlers, block_size, reserve_size, internal, params);
1329
        }
1330
        return __zend_mm_startup_ex(handlers, block_size, reserve_size, internal, params);
1331
}
1332
ZEND_API zend_mm_heap *zend_mm_startup(void)
1333
{
1334
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
1335
                return (zend_mm_heap *)__zend_mm_startup_canary();
1336
        }
1337
        return __zend_mm_startup();        
1338
}
1339
1340
#endif
1341
1206
#if ZEND_DEBUG
1342
#if ZEND_DEBUG
1207
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
1343
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block *b)
1208
{
1344
{
Lines 1571-1577 Link Here
1571
}
1707
}
1572
#endif
1708
#endif
1573
1709
1574
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
1710
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
1711
void __zend_mm_shutdown_canary(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
1712
#else
1713
static void __zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
1714
#endif
1575
{
1715
{
1576
	zend_mm_storage *storage;
1716
	zend_mm_storage *storage;
1577
	zend_mm_segment *segment;
1717
	zend_mm_segment *segment;
Lines 1581-1587 Link Here
1581
	if (heap->reserve) {
1721
	if (heap->reserve) {
1582
#if ZEND_DEBUG
1722
#if ZEND_DEBUG
1583
		if (!silent) {
1723
		if (!silent) {
1584
			_zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1724
			_zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1585
		}
1725
		}
1586
#endif
1726
#endif
1587
		heap->reserve = NULL;
1727
		heap->reserve = NULL;
Lines 1664-1675 Link Here
1664
		heap->size = 0;
1804
		heap->size = 0;
1665
		heap->peak = 0;
1805
		heap->peak = 0;
1666
		if (heap->reserve_size) {
1806
		if (heap->reserve_size) {
1667
			heap->reserve = _zend_mm_alloc_int(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1807
			heap->reserve = _zend_mm_alloc(heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1668
		}
1808
		}
1669
		heap->overflow = 0;
1809
		heap->overflow = 0;
1670
	}
1810
	}
1671
}
1811
}
1672
1812
1813
#ifndef SUHOSIN_MM_CLONE_FILE
1814
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC)
1815
{
1816
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
1817
                __zend_mm_shutdown_canary(heap, full_shutdown, silent TSRMLS_CC);
1818
                return;
1819
        }
1820
        __zend_mm_shutdown(heap, full_shutdown, silent TSRMLS_CC);
1821
}
1822
#endif
1823
1673
static void zend_mm_safe_error(zend_mm_heap *heap,
1824
static void zend_mm_safe_error(zend_mm_heap *heap,
1674
	const char *format,
1825
	const char *format,
1675
	size_t limit,
1826
	size_t limit,
Lines 1680-1686 Link Here
1680
	size_t size)
1831
	size_t size)
1681
{
1832
{
1682
	if (heap->reserve) {
1833
	if (heap->reserve) {
1834
#if SUHOSIN_MM_WITH_CANARY_PROTECTION	        
1835
		_zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1836
#else
1683
		_zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1837
		_zend_mm_free_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1838
#endif
1684
		heap->reserve = NULL;
1839
		heap->reserve = NULL;
1685
	}
1840
	}
1686
	if (heap->overflow == 0) {
1841
	if (heap->overflow == 0) {
Lines 1755-1761 Link Here
1755
		p = heap->large_free_buckets[index];
1910
		p = heap->large_free_buckets[index];
1756
		for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
1911
		for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
1757
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1912
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1758
				return p->next_free_block;
1913
				return SUHOSIN_MANGLE_PTR(p->next_free_block);
1759
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
1914
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
1760
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1915
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1761
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1916
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
Lines 1779-1785 Link Here
1779
1934
1780
		for (p = rst; p; p = p->child[p->child[0] != NULL]) {
1935
		for (p = rst; p; p = p->child[p->child[0] != NULL]) {
1781
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1936
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1782
				return p->next_free_block;
1937
				return SUHOSIN_MANGLE_PTR(p->next_free_block);
1783
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
1938
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
1784
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1939
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1785
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1940
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
Lines 1788-1794 Link Here
1788
		}
1943
		}
1789
1944
1790
		if (best_fit) {
1945
		if (best_fit) {
1791
			return best_fit->next_free_block;
1946
			return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
1792
		}
1947
		}
1793
		bitmap = bitmap >> 1;
1948
		bitmap = bitmap >> 1;
1794
		if (!bitmap) {
1949
		if (!bitmap) {
Lines 1804-1812 Link Here
1804
			best_fit = p;
1959
			best_fit = p;
1805
		}
1960
		}
1806
	}
1961
	}
1807
	return best_fit->next_free_block;
1962
	return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
1808
}
1963
}
1809
1964
1965
#if SUHOSIN_PATCH
1966
void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
1967
#endif
1810
static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1968
static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1811
{
1969
{
1812
	zend_mm_free_block *best_fit;
1970
	zend_mm_free_block *best_fit;
Lines 1816-1822 Link Here
1816
	size_t segment_size;
1974
	size_t segment_size;
1817
	zend_mm_segment *segment;
1975
	zend_mm_segment *segment;
1818
	int keep_rest = 0;
1976
	int keep_rest = 0;
1819
1977
	
1820
	if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
1978
	if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
1821
		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
1979
		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
1822
		size_t bitmap;
1980
		size_t bitmap;
Lines 1831-1839 Link Here
1831
			heap->cache_stat[index].count--;
1989
			heap->cache_stat[index].count--;
1832
			heap->cache_stat[index].hit++;
1990
			heap->cache_stat[index].hit++;
1833
#endif
1991
#endif
1834
			best_fit = heap->cache[index];
1992
			best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
1835
			heap->cache[index] = best_fit->prev_free_block;
1993
			heap->cache[index] = best_fit->prev_free_block;
1836
			heap->cached -= true_size;
1994
			heap->cached -= true_size;
1995
#if SUHOSIN_PATCH
1996
                        SUHOSIN_MM_SET_CANARIES(best_fit);
1997
                        ((zend_mm_block*)best_fit)->info.size = size;
1998
                        SUHOSIN_MM_SET_END_CANARY(best_fit);
1999
#endif			
1837
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
2000
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
1838
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
2001
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
1839
			return ZEND_MM_DATA_OF(best_fit);
2002
			return ZEND_MM_DATA_OF(best_fit);
Lines 1847-1853 Link Here
1847
		if (bitmap) {
2010
		if (bitmap) {
1848
			/* Found some "small" free block that can be used */
2011
			/* Found some "small" free block that can be used */
1849
			index += zend_mm_low_bit(bitmap);
2012
			index += zend_mm_low_bit(bitmap);
1850
			best_fit = heap->free_buckets[index*2];
2013
			best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]);
1851
#if ZEND_MM_CACHE_STAT
2014
#if ZEND_MM_CACHE_STAT
1852
			heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
2015
			heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
1853
#endif
2016
#endif
Lines 1862-1868 Link Here
1862
	best_fit = zend_mm_search_large_block(heap, true_size);
2025
	best_fit = zend_mm_search_large_block(heap, true_size);
1863
2026
1864
	if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
2027
	if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
1865
		zend_mm_free_block *p = heap->rest_buckets[0];
2028
		zend_mm_free_block *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
1866
		size_t best_size = -1;
2029
		size_t best_size = -1;
1867
2030
1868
		while (p != ZEND_MM_REST_BUCKET(heap)) {
2031
		while (p != ZEND_MM_REST_BUCKET(heap)) {
Lines 1874-1880 Link Here
1874
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
2037
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1875
				best_fit = p;
2038
				best_fit = p;
1876
			}
2039
			}
1877
			p = p->prev_free_block;
2040
			p = SUHOSIN_MANGLE_PTR(p->prev_free_block);
1878
		}
2041
		}
1879
	}
2042
	}
1880
2043
Lines 1973-1985 Link Here
1973
2136
1974
	ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
2137
	ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
1975
2138
2139
#if SUHOSIN_PATCH
2140
        SUHOSIN_MM_SET_CANARIES(best_fit);
2141
        ((zend_mm_block*)best_fit)->info.size = size;
2142
        SUHOSIN_MM_SET_END_CANARY(best_fit);
2143
#endif
2144
        
1976
	heap->size += true_size;
2145
	heap->size += true_size;
1977
	if (heap->peak < heap->size) {
2146
	if (heap->peak < heap->size) {
1978
		heap->peak = heap->size;
2147
		heap->peak = heap->size;
1979
	}
2148
	}
1980
2149
1981
	HANDLE_UNBLOCK_INTERRUPTIONS();
2150
	HANDLE_UNBLOCK_INTERRUPTIONS();
1982
2151
	
1983
	return ZEND_MM_DATA_OF(best_fit);
2152
	return ZEND_MM_DATA_OF(best_fit);
1984
}
2153
}
1985
2154
Lines 1996-2014 Link Here
1996
2165
1997
	mm_block = ZEND_MM_HEADER_OF(p);
2166
	mm_block = ZEND_MM_HEADER_OF(p);
1998
	size = ZEND_MM_BLOCK_SIZE(mm_block);
2167
	size = ZEND_MM_BLOCK_SIZE(mm_block);
2168
#if SUHOSIN_PATCH
2169
        SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()");
2170
#endif    
1999
	ZEND_MM_CHECK_PROTECTION(mm_block);
2171
	ZEND_MM_CHECK_PROTECTION(mm_block);
2000
2172
2001
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2173
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2002
	memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
2174
	memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
2003
#endif
2175
#endif
2004
2176
#if SUHOSIN_PATCH
2177
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) {
2178
                memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size);
2179
        }
2180
#endif
2005
#if ZEND_MM_CACHE
2181
#if ZEND_MM_CACHE
2006
	if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
2182
	if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
2007
		size_t index = ZEND_MM_BUCKET_INDEX(size);
2183
		size_t index = ZEND_MM_BUCKET_INDEX(size);
2008
		zend_mm_free_block **cache = &heap->cache[index];
2184
		zend_mm_free_block **cache = &heap->cache[index];
2009
2185
2010
		((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
2186
		((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
2011
		*cache = (zend_mm_free_block*)mm_block;
2187
		*cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);
2012
		heap->cached += size;
2188
		heap->cached += size;
2013
		ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2189
		ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2014
#if ZEND_MM_CACHE_STAT
2190
#if ZEND_MM_CACHE_STAT
Lines 2044-2049 Link Here
2044
	HANDLE_UNBLOCK_INTERRUPTIONS();
2220
	HANDLE_UNBLOCK_INTERRUPTIONS();
2045
}
2221
}
2046
2222
2223
#if SUHOSIN_PATCH
2224
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);
2225
#endif
2047
static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2226
static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2048
{
2227
{
2049
	zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);
2228
	zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);
Lines 2053-2063 Link Here
2053
	void *ptr;
2232
	void *ptr;
2054
2233
2055
	if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
2234
	if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
2235
#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
2236
		return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2237
#else
2056
		return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2238
		return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2239
#endif
2057
	}
2240
	}
2058
	mm_block = ZEND_MM_HEADER_OF(p);
2241
	mm_block = ZEND_MM_HEADER_OF(p);
2059
	true_size = ZEND_MM_TRUE_SIZE(size);
2242
	true_size = ZEND_MM_TRUE_SIZE(size);
2060
	orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
2243
	orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
2244
#if SUHOSIN_PATCH
2245
        SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()");
2246
#endif	
2061
	ZEND_MM_CHECK_PROTECTION(mm_block);
2247
	ZEND_MM_CHECK_PROTECTION(mm_block);
2062
2248
2063
	if (UNEXPECTED(true_size < size)) {
2249
	if (UNEXPECTED(true_size < size)) {
Lines 2089-2094 Link Here
2089
			HANDLE_UNBLOCK_INTERRUPTIONS();
2275
			HANDLE_UNBLOCK_INTERRUPTIONS();
2090
		}
2276
		}
2091
		ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
2277
		ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
2278
#if SUHOSIN_PATCH
2279
                SUHOSIN_MM_SET_CANARIES(mm_block);
2280
                ((zend_mm_block*)mm_block)->info.size = size;
2281
                SUHOSIN_MM_SET_END_CANARY(mm_block);
2282
#endif
2092
		return p;
2283
		return p;
2093
	}
2284
	}
2094
2285
Lines 2104-2120 Link Here
2104
			heap->cache_stat[index].count--;
2295
			heap->cache_stat[index].count--;
2105
			heap->cache_stat[index].hit++;
2296
			heap->cache_stat[index].hit++;
2106
#endif
2297
#endif
2107
			best_fit = heap->cache[index];
2298
			best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
2108
			heap->cache[index] = best_fit->prev_free_block;
2299
			heap->cache[index] = best_fit->prev_free_block;
2109
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
2300
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
2110
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
2301
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);                        	
2111
	
2302
#if SUHOSIN_PATCH
2303
                        SUHOSIN_MM_SET_CANARIES(best_fit);
2304
                        ((zend_mm_block*)best_fit)->info.size = size;
2305
                        SUHOSIN_MM_SET_END_CANARY(best_fit);
2306
#endif
2307
2112
			ptr = ZEND_MM_DATA_OF(best_fit);
2308
			ptr = ZEND_MM_DATA_OF(best_fit);
2113
2309
2114
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2310
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2115
			memcpy(ptr, p, mm_block->debug.size);
2311
			memcpy(ptr, p, mm_block->debug.size);
2116
#else
2312
#else
2117
			memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
2313
			memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
2118
#endif
2314
#endif
2119
2315
2120
			heap->cached -= true_size - orig_size;
2316
			heap->cached -= true_size - orig_size;
Lines 2123-2136 Link Here
2123
			cache = &heap->cache[index];
2319
			cache = &heap->cache[index];
2124
2320
2125
			((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
2321
			((zend_mm_free_block*)mm_block)->prev_free_block = *cache;
2126
			*cache = (zend_mm_free_block*)mm_block;
2322
			*cache = (zend_mm_free_block*)SUHOSIN_MANGLE_PTR(mm_block);
2127
			ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2323
			ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2128
#if ZEND_MM_CACHE_STAT
2324
#if ZEND_MM_CACHE_STAT
2129
			if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
2325
			if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
2130
				heap->cache_stat[index].max_count = heap->cache_stat[index].count;
2326
				heap->cache_stat[index].max_count = heap->cache_stat[index].count;
2131
			}
2327
			}
2132
#endif
2328
#endif
2133
2134
			return ptr;
2329
			return ptr;
2135
		}
2330
		}
2136
	}
2331
	}
Lines 2173-2178 Link Here
2173
				heap->peak = heap->size;
2368
				heap->peak = heap->size;
2174
			}
2369
			}
2175
			HANDLE_UNBLOCK_INTERRUPTIONS();
2370
			HANDLE_UNBLOCK_INTERRUPTIONS();
2371
#if SUHOSIN_PATCH
2372
                        SUHOSIN_MM_SET_CANARIES(mm_block);
2373
                        ((zend_mm_block*)mm_block)->info.size = size;
2374
                        SUHOSIN_MM_SET_END_CANARY(mm_block);
2375
#endif
2176
			return p;
2376
			return p;
2177
		} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2377
		} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2178
				   ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
2378
				   ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
Lines 2275-2312 Link Here
2275
		}
2475
		}
2276
2476
2277
		HANDLE_UNBLOCK_INTERRUPTIONS();
2477
		HANDLE_UNBLOCK_INTERRUPTIONS();
2478
#if SUHOSIN_PATCH
2479
                SUHOSIN_MM_SET_CANARIES(mm_block);
2480
                ((zend_mm_block*)mm_block)->info.size = size;
2481
                SUHOSIN_MM_SET_END_CANARY(mm_block);
2482
#endif
2278
		return ZEND_MM_DATA_OF(mm_block);
2483
		return ZEND_MM_DATA_OF(mm_block);
2279
	}
2484
	}
2280
2485
2486
#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
2487
	ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2488
#else
2281
	ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2489
	ptr = _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2490
#endif
2282
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2491
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2283
	memcpy(ptr, p, mm_block->debug.size);
2492
	memcpy(ptr, p, mm_block->debug.size);
2284
#else
2493
#else
2285
	memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE);
2494
	memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
2286
#endif
2495
#endif
2496
#ifdef SUHOSIN_MM_WITH_CANARY_PROTECTION
2497
	_zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2498
#else
2287
	_zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2499
	_zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2500
#endif
2288
	return ptr;
2501
	return ptr;
2289
}
2502
}
2290
2503
2504
#ifndef SUHOSIN_MM_CLONE_FILE
2291
ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2505
ZEND_API void *_zend_mm_alloc(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2292
{
2506
{
2293
	return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2507
#if SUHOSIN_PATCH	
2508
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2509
#endif
2510
	        return _zend_mm_alloc_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2511
#if SUHOSIN_PATCH
2512
        return _zend_mm_alloc_canary_int((zend_mm_heap_canary *)heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2513
#endif
2294
}
2514
}
2295
2515
2296
ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2516
ZEND_API void _zend_mm_free(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2297
{
2517
{
2298
	_zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2518
#if SUHOSIN_PATCH	
2519
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2520
#endif
2521
                { _zend_mm_free_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; }
2522
#if SUHOSIN_PATCH
2523
        _zend_mm_free_canary_int((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2524
#endif
2299
}
2525
}
2300
2526
2301
ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2527
ZEND_API void *_zend_mm_realloc(zend_mm_heap *heap, void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2302
{
2528
{
2303
	return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2529
#if SUHOSIN_PATCH	
2530
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2531
#endif
2532
        	return _zend_mm_realloc_int(heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2533
#if SUHOSIN_PATCH	
2534
	return _zend_mm_realloc_canary_int((zend_mm_heap_canary *)heap, ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2535
#endif
2304
}
2536
}
2305
2537
2306
ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2538
ZEND_API size_t _zend_mm_block_size(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2307
{
2539
{
2308
	zend_mm_block *mm_block;
2540
	zend_mm_block *mm_block;
2309
2541
2542
	if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) != 0) {
2543
                return _zend_mm_block_size_canary((zend_mm_heap_canary *)heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2544
	}
2545
2310
	if (!ZEND_MM_VALID_PTR(p)) {
2546
	if (!ZEND_MM_VALID_PTR(p)) {
2311
		return 0;
2547
		return 0;
2312
	}
2548
	}
Lines 2318-2323 Link Here
2318
	return ZEND_MM_BLOCK_SIZE(mm_block);
2554
	return ZEND_MM_BLOCK_SIZE(mm_block);
2319
#endif
2555
#endif
2320
}
2556
}
2557
#else
2558
ZEND_API size_t _zend_mm_block_size_canary(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2559
{
2560
	zend_mm_block *mm_block;
2561
2562
	if (!ZEND_MM_VALID_PTR(p)) {
2563
		return 0;
2564
	}
2565
	mm_block = ZEND_MM_HEADER_OF(p);
2566
	ZEND_MM_CHECK_PROTECTION(mm_block);
2567
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2568
	return mm_block->debug.size;
2569
#else
2570
	return ZEND_MM_BLOCK_SIZE(mm_block);
2571
#endif
2572
}
2573
2574
#endif
2321
2575
2322
/**********************/
2576
/**********************/
2323
/* Allocation Manager */
2577
/* Allocation Manager */
Lines 2335-2340 Link Here
2335
static zend_alloc_globals alloc_globals;
2589
static zend_alloc_globals alloc_globals;
2336
#endif
2590
#endif
2337
2591
2592
#ifndef SUHOSIN_MM_CLONE_FILE
2338
ZEND_API int is_zend_mm(TSRMLS_D)
2593
ZEND_API int is_zend_mm(TSRMLS_D)
2339
{
2594
{
2340
	return AG(mm_heap)->use_zend_alloc;
2595
	return AG(mm_heap)->use_zend_alloc;
Lines 2347-2353 Link Here
2347
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2602
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2348
		return AG(mm_heap)->_malloc(size);
2603
		return AG(mm_heap)->_malloc(size);
2349
	}
2604
	}
2605
#if SUHOSIN_PATCH	
2606
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2607
#endif
2350
	return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2608
	return _zend_mm_alloc_int(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2609
#if SUHOSIN_PATCH	
2610
        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);
2611
#endif
2351
}
2612
}
2352
2613
2353
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2614
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Lines 2358-2364 Link Here
2358
		AG(mm_heap)->_free(ptr);
2619
		AG(mm_heap)->_free(ptr);
2359
		return;
2620
		return;
2360
	}
2621
	}
2361
	_zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2622
#if SUHOSIN_PATCH	
2623
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2624
#endif
2625
                { _zend_mm_free_int(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); return; }
2626
#if SUHOSIN_PATCH	
2627
        _zend_mm_free_canary_int((zend_mm_heap_canary *)AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2628
#endif
2362
}
2629
}
2363
2630
2364
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2631
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Lines 2368-2374 Link Here
2368
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2635
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2369
		return AG(mm_heap)->_realloc(ptr, size);
2636
		return AG(mm_heap)->_realloc(ptr, size);
2370
	}
2637
	}
2638
#if SUHOSIN_PATCH	
2639
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2640
#endif
2371
	return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2641
	return _zend_mm_realloc_int(AG(mm_heap), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2642
#if SUHOSIN_PATCH	
2643
        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);
2644
#endif
2372
}
2645
}
2373
2646
2374
ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2647
ZEND_API size_t _zend_mem_block_size(void *ptr TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
Lines 2376-2383 Link Here
2376
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2649
	if (UNEXPECTED(!AG(mm_heap)->use_zend_alloc)) {
2377
		return 0;
2650
		return 0;
2378
	}
2651
	}
2379
	return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2652
#if SUHOSIN_PATCH	
2653
	if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION) == 0))
2654
#endif
2655
        	return _zend_mm_block_size(AG(mm_heap), ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2656
#if SUHOSIN_PATCH	
2657
	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);
2658
#endif
2380
}
2659
}
2660
#endif
2381
2661
2382
#if defined(__GNUC__) && defined(i386)
2662
#if defined(__GNUC__) && defined(i386)
2383
2663
Lines 2448-2454 Link Here
2448
}
2728
}
2449
#endif
2729
#endif
2450
2730
2451
2731
#ifndef SUHOSIN_MM_CLONE_FILE
2452
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2732
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2453
{
2733
{
2454
	return emalloc_rel(safe_address(nmemb, size, offset));
2734
	return emalloc_rel(safe_address(nmemb, size, offset));
Lines 2561-2566 Link Here
2561
{
2841
{
2562
	zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC);
2842
	zend_mm_shutdown(AG(mm_heap), full_shutdown, silent TSRMLS_CC);
2563
}
2843
}
2844
#endif
2564
2845
2565
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC)
2846
static void alloc_globals_ctor(zend_alloc_globals *alloc_globals TSRMLS_DC)
2566
{
2847
{
Lines 2585-2590 Link Here
2585
}
2866
}
2586
#endif
2867
#endif
2587
2868
2869
#ifndef SUHOSIN_MM_CLONE_FILE
2588
ZEND_API void start_memory_manager(TSRMLS_D)
2870
ZEND_API void start_memory_manager(TSRMLS_D)
2589
{
2871
{
2590
#ifdef ZTS
2872
#ifdef ZTS
Lines 2649-2654 Link Here
2649
	zend_debug_alloc_output("------------------------------------------------\n");
2931
	zend_debug_alloc_output("------------------------------------------------\n");
2650
}
2932
}
2651
#endif
2933
#endif
2934
#endif
2652
2935
2653
/*
2936
/*
2654
 * Local variables:
2937
 * Local variables:
(-)php-5.3.9/Zend/zend_alloc.h (+2 lines)
Lines 203-208 Link Here
203
203
204
/* Heap functions */
204
/* Heap functions */
205
typedef struct _zend_mm_heap zend_mm_heap;
205
typedef struct _zend_mm_heap zend_mm_heap;
206
typedef struct _zend_mm_heap_canary zend_mm_heap_canary;
207
206
208
207
ZEND_API zend_mm_heap *zend_mm_startup(void);
209
ZEND_API zend_mm_heap *zend_mm_startup(void);
208
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC);
210
ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent TSRMLS_DC);
(-)php-5.3.9/Zend/zend_alloc_canary.c (+2509 lines)
Line 0 Link Here
1
/*
2
   +----------------------------------------------------------------------+
3
   | Suhosin-Patch for PHP                                                |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 2004-2011 Stefan Esser                                 |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.02 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available at through the world-wide-web at                           |
10
   | http://www.php.net/license/2_02.txt.                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Stefan Esser <stefan.esser@sektioneins.de>                   |
16
   +----------------------------------------------------------------------+
17
 */
18
/* $Id: zend_alloc_canary.c, $ */
19
20
#include "zend.h"
21
#include "zend_alloc.h"
22
#include "zend_globals.h"
23
#include "zend_operators.h"
24
25
#ifdef HAVE_SIGNAL_H
26
# include <signal.h>
27
#endif
28
#ifdef HAVE_UNISTD_H
29
# include <unistd.h>
30
#endif
31
32
#if SUHOSIN_PATCH
33
#include "suhosin_patch.h"
34
#endif
35
36
#ifdef ZEND_WIN32
37
# include <wincrypt.h>
38
# include <process.h>
39
#endif
40
41
#ifndef ZEND_MM_HEAP_PROTECTION
42
# define ZEND_MM_HEAP_PROTECTION ZEND_DEBUG
43
#endif
44
45
#ifndef ZEND_MM_SAFE_UNLINKING
46
# define ZEND_MM_SAFE_UNLINKING 1
47
#endif
48
49
#ifndef ZEND_MM_COOKIES
50
# define ZEND_MM_COOKIES ZEND_DEBUG
51
#endif
52
53
#ifdef _WIN64
54
# define PTR_FMT "0x%0.16I64x"
55
/*
56
#elif sizeof(long) == 8
57
# define PTR_FMT "0x%0.16lx"
58
*/
59
#else
60
# define PTR_FMT "0x%0.8lx"
61
#endif
62
63
#define SUHOSIN_MM_WITH_CANARY_PROTECTION 1
64
65
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
66
static void zend_mm_panic(const char *message) __attribute__ ((noreturn));
67
#endif
68
69
static void zend_mm_panic(const char *message)
70
{
71
	fprintf(stderr, "%s\n", message);
72
/* See http://support.microsoft.com/kb/190351 */
73
#ifdef PHP_WIN32
74
	fflush(stderr);
75
#endif
76
#if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID)
77
	kill(getpid(), SIGSEGV);
78
#endif
79
	exit(1);
80
}
81
82
/*******************/
83
/* Storage Manager */
84
/*******************/
85
86
#ifdef ZEND_WIN32
87
#  define HAVE_MEM_WIN32    /* use VirtualAlloc() to allocate memory     */
88
#endif
89
#define HAVE_MEM_MALLOC     /* use malloc() to allocate segments         */
90
91
#include <sys/types.h>
92
#include <sys/stat.h>
93
#if HAVE_LIMITS_H
94
#include <limits.h>
95
#endif
96
#include <fcntl.h>
97
#include <errno.h>
98
99
#if defined(HAVE_MEM_MMAP_ANON) || defined(HAVE_MEM_MMAP_ZERO)
100
# ifdef HAVE_MREMAP
101
#  ifndef _GNU_SOURCE
102
#   define _GNU_SOURCE
103
#  endif
104
#  ifndef __USE_GNU
105
#   define __USE_GNU
106
#  endif
107
# endif
108
# include <sys/mman.h>
109
# ifndef MAP_ANON
110
#  ifdef MAP_ANONYMOUS
111
#   define MAP_ANON MAP_ANONYMOUS
112
#  endif
113
# endif
114
# ifndef MREMAP_MAYMOVE
115
#  define MREMAP_MAYMOVE 0
116
# endif
117
# ifndef MAP_FAILED
118
#  define MAP_FAILED ((void*)-1)
119
# endif
120
#endif
121
122
static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
123
124
static zend_mm_storage* zend_mm_mem_dummy_init(void *params)
125
{
126
	return malloc(sizeof(zend_mm_storage));
127
}
128
129
static void zend_mm_mem_dummy_dtor(zend_mm_storage *storage)
130
{
131
	free(storage);
132
}
133
134
static void zend_mm_mem_dummy_compact(zend_mm_storage *storage)
135
{
136
}
137
138
#if defined(HAVE_MEM_MMAP_ANON) || defined(HAVE_MEM_MMAP_ZERO)
139
140
static zend_mm_segment* zend_mm_mem_mmap_realloc(zend_mm_storage *storage, zend_mm_segment* segment, size_t size)
141
{
142
	zend_mm_segment *ret;
143
#ifdef HAVE_MREMAP
144
#if defined(__NetBSD__)
145
	/* NetBSD 5 supports mremap but takes an extra newp argument */
146
	ret = (zend_mm_segment*)mremap(segment, segment->size, segment, size, MREMAP_MAYMOVE);
147
#else
148
	ret = (zend_mm_segment*)mremap(segment, segment->size, size, MREMAP_MAYMOVE);
149
#endif
150
	if (ret == MAP_FAILED) {
151
#endif
152
		ret = storage->handlers->_alloc(storage, size);
153
		if (ret) {
154
			memcpy(ret, segment, size > segment->size ? segment->size : size);
155
			storage->handlers->_free(storage, segment);
156
		}
157
#ifdef HAVE_MREMAP
158
	}
159
#endif
160
	return ret;
161
}
162
163
static void zend_mm_mem_mmap_free(zend_mm_storage *storage, zend_mm_segment* segment)
164
{
165
	munmap((void*)segment, segment->size);
166
}
167
168
#endif
169
170
#ifdef HAVE_MEM_MMAP_ANON
171
172
static zend_mm_segment* zend_mm_mem_mmap_anon_alloc(zend_mm_storage *storage, size_t size)
173
{
174
	zend_mm_segment *ret = (zend_mm_segment*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
175
	if (ret == MAP_FAILED) {
176
		ret = NULL;
177
	}
178
	return ret;
179
}
180
181
# 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}
182
183
#endif
184
185
#ifdef HAVE_MEM_MMAP_ZERO
186
187
static int zend_mm_dev_zero_fd = -1;
188
189
static zend_mm_storage* zend_mm_mem_mmap_zero_init(void *params)
190
{
191
	if (zend_mm_dev_zero_fd != -1) {
192
		zend_mm_dev_zero_fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
193
	}
194
	if (zend_mm_dev_zero_fd >= 0) {
195
		return malloc(sizeof(zend_mm_storage));
196
	} else {
197
		return NULL;
198
	}
199
}
200
201
static void zend_mm_mem_mmap_zero_dtor(zend_mm_storage *storage)
202
{
203
	close(zend_mm_dev_zero_fd);
204
	free(storage);
205
}
206
207
static zend_mm_segment* zend_mm_mem_mmap_zero_alloc(zend_mm_storage *storage, size_t size)
208
{
209
	zend_mm_segment *ret = (zend_mm_segment*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zend_mm_dev_zero_fd, 0);
210
	if (ret == MAP_FAILED) {
211
		ret = NULL;
212
	}
213
	return ret;
214
}
215
216
# 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}
217
218
#endif
219
220
#ifdef HAVE_MEM_WIN32
221
222
static zend_mm_storage* zend_mm_mem_win32_init(void *params)
223
{
224
	HANDLE heap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
225
	zend_mm_storage* storage;
226
227
	if (heap == NULL) {
228
		return NULL;
229
	}
230
	storage = (zend_mm_storage*)malloc(sizeof(zend_mm_storage));
231
	if (storage == NULL) {
232
		HeapDestroy(heap);
233
		return NULL;
234
	}
235
	storage->data = (void*) heap;
236
	return storage;
237
}
238
239
static void zend_mm_mem_win32_dtor(zend_mm_storage *storage)
240
{
241
	HeapDestroy((HANDLE)storage->data);
242
	free(storage);
243
}
244
245
static void zend_mm_mem_win32_compact(zend_mm_storage *storage)
246
{
247
    HeapDestroy((HANDLE)storage->data);
248
    storage->data = (void*)HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
249
}
250
251
static zend_mm_segment* zend_mm_mem_win32_alloc(zend_mm_storage *storage, size_t size)
252
{
253
	return (zend_mm_segment*) HeapAlloc((HANDLE)storage->data, HEAP_NO_SERIALIZE, size);
254
}
255
256
static void zend_mm_mem_win32_free(zend_mm_storage *storage, zend_mm_segment* segment)
257
{
258
	HeapFree((HANDLE)storage->data, HEAP_NO_SERIALIZE, segment);
259
}
260
261
static zend_mm_segment* zend_mm_mem_win32_realloc(zend_mm_storage *storage, zend_mm_segment* segment, size_t size)
262
{
263
	return (zend_mm_segment*) HeapReAlloc((HANDLE)storage->data, HEAP_NO_SERIALIZE, segment, size);
264
}
265
266
# 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}
267
268
#endif
269
270
#ifdef HAVE_MEM_MALLOC
271
272
static zend_mm_segment* zend_mm_mem_malloc_alloc(zend_mm_storage *storage, size_t size)
273
{
274
	return (zend_mm_segment*)malloc(size);
275
}
276
277
static zend_mm_segment* zend_mm_mem_malloc_realloc(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size)
278
{
279
	return (zend_mm_segment*)realloc(ptr, size);
280
}
281
282
static void zend_mm_mem_malloc_free(zend_mm_storage *storage, zend_mm_segment *ptr)
283
{
284
	free(ptr);
285
}
286
287
# 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}
288
289
#endif
290
291
static const zend_mm_mem_handlers mem_handlers[] = {
292
#ifdef HAVE_MEM_WIN32
293
	ZEND_MM_MEM_WIN32_DSC,
294
#endif
295
#ifdef HAVE_MEM_MALLOC
296
	ZEND_MM_MEM_MALLOC_DSC,
297
#endif
298
#ifdef HAVE_MEM_MMAP_ANON
299
	ZEND_MM_MEM_MMAP_ANON_DSC,
300
#endif
301
#ifdef HAVE_MEM_MMAP_ZERO
302
	ZEND_MM_MEM_MMAP_ZERO_DSC,
303
#endif
304
	{NULL, NULL, NULL, NULL, NULL, NULL}
305
};
306
307
# define ZEND_MM_STORAGE_DTOR()						heap->storage->handlers->dtor(heap->storage)
308
# define ZEND_MM_STORAGE_ALLOC(size)				heap->storage->handlers->_alloc(heap->storage, size)
309
# define ZEND_MM_STORAGE_REALLOC(ptr, size)			heap->storage->handlers->_realloc(heap->storage, ptr, size)
310
# define ZEND_MM_STORAGE_FREE(ptr)					heap->storage->handlers->_free(heap->storage, ptr)
311
312
/****************/
313
/* Heap Manager */
314
/****************/
315
316
#define MEM_BLOCK_VALID  0x7312F8DC
317
#define	MEM_BLOCK_FREED  0x99954317
318
#define	MEM_BLOCK_CACHED 0xFB8277DC
319
#define	MEM_BLOCK_GUARD  0x2A8FCC84
320
#define	MEM_BLOCK_LEAK   0x6C5E8F2D
321
322
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
323
# define CANARY_SIZE sizeof(size_t)
324
#else
325
# define CANARY_SIZE 0
326
#endif
327
328
/* mm block type */
329
typedef struct _zend_mm_block_info_canary {
330
#if ZEND_MM_COOKIES
331
	size_t _cookie;
332
#endif
333
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
334
	size_t canary_1;
335
#endif
336
  	size_t _size;
337
  	size_t _prev;
338
#if SUHOSIN_PATCH
339
	size_t size;
340
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
341
	size_t canary_2;
342
#endif
343
#endif
344
} zend_mm_block_info_canary;
345
346
#if ZEND_DEBUG
347
348
typedef struct _zend_mm_debug_info_canary {
349
	char *filename;
350
	uint lineno;
351
	char *orig_filename;
352
	uint orig_lineno;
353
	size_t size;
354
#if ZEND_MM_HEAP_PROTECTION
355
	unsigned int start_magic;
356
#endif
357
} zend_mm_debug_info_canary;
358
359
#elif ZEND_MM_HEAP_PROTECTION
360
361
typedef struct _zend_mm_debug_info_canary {
362
	size_t size;
363
	unsigned int start_magic;
364
} zend_mm_debug_info_canary;
365
366
#endif
367
368
typedef struct _zend_mm_block_canary {
369
	zend_mm_block_info_canary info;
370
#if ZEND_DEBUG
371
	unsigned int magic;
372
# ifdef ZTS
373
	THREAD_T thread_id;
374
# endif
375
	zend_mm_debug_info_canary debug;
376
#elif ZEND_MM_HEAP_PROTECTION
377
	zend_mm_debug_info_canary debug;
378
#endif
379
} zend_mm_block_canary;
380
381
typedef struct _zend_mm_small_free_block_canary {
382
	zend_mm_block_info_canary info;
383
#if ZEND_DEBUG
384
	unsigned int magic;
385
# ifdef ZTS
386
	THREAD_T thread_id;
387
# endif
388
#endif
389
	struct _zend_mm_free_block_canary *prev_free_block;
390
	struct _zend_mm_free_block_canary *next_free_block;
391
} zend_mm_small_free_block_canary;
392
393
typedef struct _zend_mm_free_block_canary {
394
	zend_mm_block_info_canary info;
395
#if ZEND_DEBUG
396
	unsigned int magic;
397
# ifdef ZTS
398
	THREAD_T thread_id;
399
# endif
400
#endif
401
	struct _zend_mm_free_block_canary *prev_free_block;
402
	struct _zend_mm_free_block_canary *next_free_block;
403
404
	struct _zend_mm_free_block_canary **parent;
405
	struct _zend_mm_free_block_canary *child[2];
406
} zend_mm_free_block_canary;
407
408
#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)
409
410
#define ZEND_MM_CACHE 1
411
#define ZEND_MM_CACHE_SIZE (ZEND_MM_NUM_BUCKETS * 4 * 1024)
412
413
#ifndef ZEND_MM_CACHE_STAT
414
# define ZEND_MM_CACHE_STAT 0
415
#endif
416
417
typedef struct _zend_mm_heap_canary {
418
	int                 use_zend_alloc;
419
	void               *(*_malloc)(size_t);
420
	void                (*_free)(void*);
421
	void               *(*_realloc)(void*, size_t);
422
	size_t              free_bitmap;
423
	size_t              large_free_bitmap;
424
	size_t              block_size;
425
	size_t              compact_size;
426
	zend_mm_segment    *segments_list;
427
	zend_mm_storage    *storage;
428
	size_t              real_size;
429
	size_t              real_peak;
430
	size_t              limit;
431
	size_t              size;
432
	size_t              peak;
433
	size_t              reserve_size;
434
	void               *reserve;
435
	int                 overflow;
436
	int                 internal;
437
#if ZEND_MM_CACHE
438
	unsigned int        cached;
439
	zend_mm_free_block_canary *cache[ZEND_MM_NUM_BUCKETS];
440
#endif
441
	zend_mm_free_block_canary *free_buckets[ZEND_MM_NUM_BUCKETS*2];
442
	zend_mm_free_block_canary *large_free_buckets[ZEND_MM_NUM_BUCKETS];
443
	zend_mm_free_block_canary *rest_buckets[2];
444
#if ZEND_MM_CACHE_STAT
445
	struct {
446
		int count;
447
		int max_count;
448
		int hit;
449
		int miss;
450
	} cache_stat[ZEND_MM_NUM_BUCKETS+1];
451
#endif
452
#if SUHOSIN_PATCH
453
 	size_t              canary_1,canary_2,canary_3;
454
#endif
455
};
456
457
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
458
	(zend_mm_free_block_canary*) ((char*)&heap->free_buckets[index * 2] + \
459
		sizeof(zend_mm_free_block_canary*) * 2 - \
460
		sizeof(zend_mm_small_free_block_canary))
461
462
#define ZEND_MM_REST_BUCKET(heap) \
463
	(zend_mm_free_block_canary*)((char*)&heap->rest_buckets[0] + \
464
		sizeof(zend_mm_free_block_canary*) * 2 - \
465
		sizeof(zend_mm_small_free_block_canary))
466
467
#if ZEND_MM_COOKIES
468
469
static unsigned int _zend_mm_cookie = 0;
470
471
# define ZEND_MM_COOKIE(block) \
472
	(((size_t)(block)) ^ _zend_mm_cookie)
473
# define ZEND_MM_SET_COOKIE(block) \
474
	(block)->info._cookie = ZEND_MM_COOKIE(block)
475
# define ZEND_MM_CHECK_COOKIE(block) \
476
	if (UNEXPECTED((block)->info._cookie != ZEND_MM_COOKIE(block))) { \
477
		zend_mm_panic("zend_mm_heap corrupted"); \
478
	}
479
#else
480
# define ZEND_MM_SET_COOKIE(block)
481
# define ZEND_MM_CHECK_COOKIE(block)
482
#endif
483
484
/* Default memory segment size */
485
#define ZEND_MM_SEG_SIZE   (256 * 1024)
486
487
/* Reserved space for error reporting in case of memory overflow */
488
#define ZEND_MM_RESERVE_SIZE            (8*1024)
489
490
#ifdef _WIN64
491
# define ZEND_MM_LONG_CONST(x)	(x##i64)
492
#else
493
# define ZEND_MM_LONG_CONST(x)	(x##L)
494
#endif
495
496
#define ZEND_MM_TYPE_MASK		ZEND_MM_LONG_CONST(0x3)
497
498
#define ZEND_MM_FREE_BLOCK		ZEND_MM_LONG_CONST(0x0)
499
#define ZEND_MM_USED_BLOCK		ZEND_MM_LONG_CONST(0x1)
500
#define ZEND_MM_GUARD_BLOCK		ZEND_MM_LONG_CONST(0x3)
501
502
#define ZEND_MM_BLOCK(b, type, size)	do { \
503
											size_t _size = (size); \
504
											(b)->info._size = (type) | _size; \
505
											ZEND_MM_BLOCK_AT(b, _size)->info._prev = (type) | _size; \
506
											ZEND_MM_SET_COOKIE(b); \
507
										} while (0);
508
#define ZEND_MM_LAST_BLOCK(b)			do { \
509
		(b)->info._size = ZEND_MM_GUARD_BLOCK | ZEND_MM_ALIGNED_HEADER_SIZE; \
510
		ZEND_MM_SET_MAGIC(b, MEM_BLOCK_GUARD); \
511
 	} while (0);
512
#define ZEND_MM_BLOCK_SIZE(b)			((b)->info._size & ~ZEND_MM_TYPE_MASK)
513
#define ZEND_MM_IS_FREE_BLOCK(b)		(!((b)->info._size & ZEND_MM_USED_BLOCK))
514
#define ZEND_MM_IS_USED_BLOCK(b)		((b)->info._size & ZEND_MM_USED_BLOCK)
515
#define ZEND_MM_IS_GUARD_BLOCK(b)		(((b)->info._size & ZEND_MM_TYPE_MASK) == ZEND_MM_GUARD_BLOCK)
516
517
#define ZEND_MM_NEXT_BLOCK(b)			ZEND_MM_BLOCK_AT(b, ZEND_MM_BLOCK_SIZE(b))
518
#define ZEND_MM_PREV_BLOCK(b)			ZEND_MM_BLOCK_AT(b, -(ssize_t)((b)->info._prev & ~ZEND_MM_TYPE_MASK))
519
520
#define ZEND_MM_PREV_BLOCK_IS_FREE(b)	(!((b)->info._prev & ZEND_MM_USED_BLOCK))
521
522
#define ZEND_MM_MARK_FIRST_BLOCK(b)		((b)->info._prev = ZEND_MM_GUARD_BLOCK)
523
#define ZEND_MM_IS_FIRST_BLOCK(b)		((b)->info._prev == ZEND_MM_GUARD_BLOCK)
524
525
/* optimized access */
526
#define ZEND_MM_FREE_BLOCK_SIZE(b)		(b)->info._size
527
528
#ifndef ZEND_MM_ALIGNMENT
529
# define ZEND_MM_ALIGNMENT 8
530
# define ZEND_MM_ALIGNMENT_LOG2 3
531
#elif ZEND_MM_ALIGNMENT < 4
532
# undef ZEND_MM_ALIGNMENT
533
# undef ZEND_MM_ALIGNMENT_LOG2
534
# define ZEND_MM_ALIGNMENT 4
535
# define ZEND_MM_ALIGNMENT_LOG2 2
536
#endif
537
538
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
539
540
/* Aligned header size */
541
#define ZEND_MM_ALIGNED_SIZE(size)			((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
542
#define ZEND_MM_ALIGNED_HEADER_SIZE			ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block_canary))
543
#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE	ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block_canary))
544
#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE		ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)
545
#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)
546
#define ZEND_MM_ALIGNED_SEGMENT_SIZE		ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
547
548
#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)
549
550
#define ZEND_MM_MAX_SMALL_SIZE				((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
551
552
#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)))
553
554
#define ZEND_MM_BUCKET_INDEX(true_size)		((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
555
556
#define ZEND_MM_SMALL_SIZE(true_size)		(true_size < ZEND_MM_MAX_SMALL_SIZE)
557
558
/* Memory calculations */
559
#define ZEND_MM_BLOCK_AT(blk, offset)	((zend_mm_block_canary *) (((char *) (blk))+(offset)))
560
#define ZEND_MM_DATA_OF(p)				((void *) (((char *) (p))+ZEND_MM_ALIGNED_HEADER_SIZE))
561
#define ZEND_MM_HEADER_OF(blk)			ZEND_MM_BLOCK_AT(blk, -(int)ZEND_MM_ALIGNED_HEADER_SIZE)
562
563
/* Debug output */
564
#if ZEND_DEBUG
565
566
# ifdef ZTS
567
#  define ZEND_MM_SET_THREAD_ID(block) \
568
	((zend_mm_block_canary*)(block))->thread_id = tsrm_thread_id()
569
#  define ZEND_MM_BAD_THREAD_ID(block) ((block)->thread_id != tsrm_thread_id())
570
# else
571
#  define ZEND_MM_SET_THREAD_ID(block)
572
#  define ZEND_MM_BAD_THREAD_ID(block) 0
573
# endif
574
575
# define ZEND_MM_VALID_PTR(block) \
576
	zend_mm_check_ptr(heap, block, 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC)
577
578
# define ZEND_MM_SET_MAGIC(block, val) do { \
579
		(block)->magic = (val); \
580
	} while (0)
581
582
# define ZEND_MM_CHECK_MAGIC(block, val) do { \
583
		if ((block)->magic != (val)) { \
584
			zend_mm_panic("zend_mm_heap corrupted"); \
585
		} \
586
	} while (0)
587
588
# define ZEND_MM_SET_DEBUG_INFO(block, __size, set_valid, set_thread) do { \
589
		((zend_mm_block_canary*)(block))->debug.filename = __zend_filename; \
590
		((zend_mm_block_canary*)(block))->debug.lineno = __zend_lineno; \
591
		((zend_mm_block_canary*)(block))->debug.orig_filename = __zend_orig_filename; \
592
		((zend_mm_block_canary*)(block))->debug.orig_lineno = __zend_orig_lineno; \
593
		ZEND_MM_SET_BLOCK_SIZE(block, __size); \
594
		if (set_valid) { \
595
			ZEND_MM_SET_MAGIC(block, MEM_BLOCK_VALID); \
596
		} \
597
		if (set_thread) { \
598
			ZEND_MM_SET_THREAD_ID(block); \
599
		} \
600
	} while (0)
601
602
#else
603
604
# define ZEND_MM_VALID_PTR(ptr) EXPECTED(ptr != NULL)
605
606
# define ZEND_MM_SET_MAGIC(block, val)
607
608
# define ZEND_MM_CHECK_MAGIC(block, val)
609
610
# define ZEND_MM_SET_DEBUG_INFO(block, __size, set_valid, set_thread) ZEND_MM_SET_BLOCK_SIZE(block, __size)
611
612
#endif
613
614
#if SUHOSIN_MM_WITH_CANARY_PROTECTION
615
616
# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \
617
        char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \
618
	if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \
619
		canary_mismatch: \
620
		zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
621
                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; }\
622
	} \
623
        memcpy(&check, p, CANARY_SIZE); \
624
        if (check != heap->canary_3) { \
625
                zend_suhosin_log(S_MEMORY, "end canary mismatch on " MFUNCTION " - heap overflow detected at %p", (block)); \
626
                if (SUHOSIN_CONFIG(SUHOSIN_MM_IGNORE_CANARY_VIOLATION) == 0) { _exit(1); } else { memcpy(p, heap->canary_3, CANARY_SIZE); } \
627
        } \
628
	} while (0)
629
630
# define SUHOSIN_MM_SET_CANARIES(block) do { \
631
        (block)->info.canary_1 = heap->canary_1; \
632
        (block)->info.canary_2 = heap->canary_2; \
633
        } while (0)      
634
635
# define SUHOSIN_MM_END_CANARY_PTR(block) \
636
	(char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block_canary*)(block))->info.size + END_MAGIC_SIZE)
637
638
# define SUHOSIN_MM_SET_END_CANARY(block) do { \
639
	char *p = SUHOSIN_MM_END_CANARY_PTR(block); \
640
	memcpy(p, &heap->canary_3, CANARY_SIZE); \
641
	} while (0)
642
643
#else
644
645
# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION)
646
# define SUHOSIN_MM_SET_CANARIES(block)
647
# define SUHOSIN_MM_END_CANARY_PTR(block)
648
# define SUHOSIN_MM_SET_END_CANARY(block)
649
650
#endif
651
652
653
#if ZEND_MM_HEAP_PROTECTION
654
655
# define ZEND_MM_CHECK_PROTECTION(block) \
656
	do { \
657
		if ((block)->debug.start_magic != _mem_block_start_magic || \
658
		    memcmp(ZEND_MM_END_MAGIC_PTR(block), &_mem_block_end_magic, END_MAGIC_SIZE) != 0) { \
659
		    zend_mm_panic("zend_mm_heap corrupted"); \
660
		} \
661
	} while (0)
662
663
# define ZEND_MM_END_MAGIC_PTR(block) \
664
	(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block_canary*)(block))->debug.size)
665
666
# define END_MAGIC_SIZE sizeof(unsigned int)
667
668
# define ZEND_MM_SET_BLOCK_SIZE(block, __size) do { \
669
		char *p; \
670
		((zend_mm_block_canary*)(block))->debug.size = (__size); \
671
		p = ZEND_MM_END_MAGIC_PTR(block); \
672
		((zend_mm_block_canary*)(block))->debug.start_magic = _mem_block_start_magic; \
673
		memcpy(p, &_mem_block_end_magic, END_MAGIC_SIZE); \
674
	} while (0)
675
676
static unsigned int _mem_block_start_magic = 0;
677
static unsigned int _mem_block_end_magic   = 0;
678
679
#else
680
681
# if ZEND_DEBUG
682
#  define ZEND_MM_SET_BLOCK_SIZE(block, _size) \
683
	((zend_mm_block_canary*)(block))->debug.size = (_size)
684
# else
685
#  define ZEND_MM_SET_BLOCK_SIZE(block, _size)
686
# endif
687
688
# define ZEND_MM_CHECK_PROTECTION(block)
689
690
# define END_MAGIC_SIZE 0
691
692
#endif
693
694
#if ZEND_MM_SAFE_UNLINKING
695
# define ZEND_MM_CHECK_BLOCK_LINKAGE(block) \
696
	if (UNEXPECTED((block)->info._size != ZEND_MM_BLOCK_AT(block, ZEND_MM_FREE_BLOCK_SIZE(block))->info._prev) || \
697
		UNEXPECTED(!UNEXPECTED(ZEND_MM_IS_FIRST_BLOCK(block)) && \
698
	    UNEXPECTED(ZEND_MM_PREV_BLOCK(block)->info._size != (block)->info._prev))) { \
699
	    zend_mm_panic("zend_mm_heap corrupted"); \
700
	}
701
#define ZEND_MM_CHECK_TREE(block) \
702
	if (UNEXPECTED(*((block)->parent) != (block))) { \
703
		zend_mm_panic("zend_mm_heap corrupted"); \
704
	}
705
#else
706
# define ZEND_MM_CHECK_BLOCK_LINKAGE(block)
707
# define ZEND_MM_CHECK_TREE(block)
708
#endif
709
710
#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
711
712
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;
713
void _zend_mm_free_canary_int(zend_mm_heap_canary *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
714
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);
715
716
717
static inline unsigned int zend_mm_high_bit(size_t _size)
718
{
719
#if defined(__GNUC__) && defined(i386)
720
	unsigned int n;
721
722
	__asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm"  (_size));
723
	return n;
724
#elif defined(__GNUC__) && defined(__x86_64__)
725
	unsigned long n;
726
727
        __asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm"  (_size));
728
        return (unsigned int)n;
729
#elif defined(_MSC_VER) && defined(_M_IX86)
730
	__asm {
731
		bsr eax, _size
732
	}
733
#else
734
	unsigned int n = 0;
735
	while (_size != 0) {
736
		_size = _size >> 1;
737
		n++;
738
	}
739
	return n-1;
740
#endif
741
}
742
743
static inline unsigned int zend_mm_low_bit(size_t _size)
744
{
745
#if defined(__GNUC__) && defined(i386)
746
	unsigned int n;
747
748
	__asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm"  (_size));
749
	return n;
750
#elif defined(__GNUC__) && defined(__x86_64__)
751
        unsigned long n;
752
753
        __asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm"  (_size));
754
        return (unsigned int)n;
755
#elif defined(_MSC_VER) && defined(_M_IX86)
756
	__asm {
757
		bsf eax, _size
758
   }
759
#else
760
	static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
761
	unsigned int n;
762
	unsigned int index = 0;
763
764
	n = offset[_size & 15];
765
	while (n == 4) {
766
		_size >>= 4;
767
		index += n;
768
		n = offset[_size & 15];
769
	}
770
771
	return index + n;
772
#endif
773
}
774
775
static void zend_mm_add_to_rest_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
776
{
777
	zend_mm_free_block_canary *prev, *next;
778
779
	ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
780
781
	if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {
782
		mm_block->parent = NULL;
783
	}
784
785
	prev = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
786
	next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
787
	mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
788
	mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
789
	prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
790
}
791
792
static void zend_mm_add_to_free_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
793
{
794
	size_t size;
795
	size_t index;
796
797
	ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
798
799
	size = ZEND_MM_FREE_BLOCK_SIZE(mm_block);
800
	if (EXPECTED(!ZEND_MM_SMALL_SIZE(size))) {
801
		zend_mm_free_block_canary **p;
802
803
		index = ZEND_MM_LARGE_BUCKET_INDEX(size);
804
		p = &heap->large_free_buckets[index];
805
		mm_block->child[0] = mm_block->child[1] = NULL;
806
		if (!*p) {
807
			*p = mm_block;
808
			mm_block->parent = p;
809
			mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
810
			heap->large_free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
811
		} else {
812
			size_t m;
813
814
			for (m = size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
815
				zend_mm_free_block_canary *prev = *p;
816
817
				if (ZEND_MM_FREE_BLOCK_SIZE(prev) != size) {
818
					p = &prev->child[(m >> (ZEND_MM_NUM_BUCKETS-1)) & 1];
819
					if (!*p) {
820
						*p = mm_block;
821
						mm_block->parent = p;
822
						mm_block->prev_free_block = mm_block->next_free_block = SUHOSIN_MANGLE_PTR(mm_block);
823
						break;
824
					}
825
				} else {
826
					zend_mm_free_block_canary *next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
827
828
					prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
829
					mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
830
					mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
831
					mm_block->parent = NULL;
832
					break;
833
				}
834
			}
835
		}
836
	} else {
837
		zend_mm_free_block_canary *prev, *next;
838
839
		index = ZEND_MM_BUCKET_INDEX(size);
840
841
		prev = ZEND_MM_SMALL_FREE_BUCKET(heap, index);
842
		if (SUHOSIN_MANGLE_PTR(prev->prev_free_block) == prev) {
843
			heap->free_bitmap |= (ZEND_MM_LONG_CONST(1) << index);
844
		}
845
		next = SUHOSIN_MANGLE_PTR(prev->next_free_block);
846
847
		mm_block->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
848
		mm_block->next_free_block = SUHOSIN_MANGLE_PTR(next);
849
		prev->next_free_block = next->prev_free_block = SUHOSIN_MANGLE_PTR(mm_block);
850
	}
851
}
852
853
static void zend_mm_remove_from_free_list(zend_mm_heap_canary *heap, zend_mm_free_block_canary *mm_block)
854
{
855
	zend_mm_free_block_canary *prev = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
856
	zend_mm_free_block_canary *next = SUHOSIN_MANGLE_PTR(mm_block->next_free_block);
857
858
	ZEND_MM_CHECK_MAGIC(mm_block, MEM_BLOCK_FREED);
859
860
	if (EXPECTED(prev == mm_block)) {
861
		zend_mm_free_block_canary **rp, **cp;
862
863
#if SUHOSIN_PATCH
864
                if (next != mm_block) {
865
                        zend_suhosin_log(S_MEMORY, "zend_mm_heap corrupted at %p", mm_block);
866
                        _exit(1);
867
                }
868
#endif
869
#if ZEND_MM_SAFE_UNLINKING
870
		if (UNEXPECTED(next != mm_block)) {
871
			zend_mm_panic("zend_mm_heap corrupted");
872
		}
873
#endif
874
875
		rp = &mm_block->child[mm_block->child[1] != NULL];
876
		prev = *rp;
877
		if (EXPECTED(prev == NULL)) {
878
			size_t index = ZEND_MM_LARGE_BUCKET_INDEX(ZEND_MM_FREE_BLOCK_SIZE(mm_block));
879
880
			ZEND_MM_CHECK_TREE(mm_block);
881
			*mm_block->parent = NULL;
882
			if (mm_block->parent == &heap->large_free_buckets[index]) {
883
				heap->large_free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
884
		    }
885
		} else {
886
			while (*(cp = &(prev->child[prev->child[1] != NULL])) != NULL) {
887
				prev = *cp;
888
				rp = cp;
889
			}
890
			*rp = NULL;
891
892
subst_block:
893
			ZEND_MM_CHECK_TREE(mm_block);
894
			*mm_block->parent = prev;
895
			prev->parent = mm_block->parent;
896
			if ((prev->child[0] = mm_block->child[0])) {
897
				ZEND_MM_CHECK_TREE(prev->child[0]);
898
				prev->child[0]->parent = &prev->child[0];
899
			}
900
			if ((prev->child[1] = mm_block->child[1])) {
901
				ZEND_MM_CHECK_TREE(prev->child[1]);
902
				prev->child[1]->parent = &prev->child[1];
903
			}
904
		}
905
	} else {
906
907
#if SUHOSIN_PATCH
908
                if (SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block || SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block) {
909
                        zend_suhosin_log(S_MEMORY, "zend_mm_head corrupted at %p", mm_block);
910
		        _exit(1);
911
                }
912
#endif    
913
914
#if ZEND_MM_SAFE_UNLINKING
915
		if (UNEXPECTED(SUHOSIN_MANGLE_PTR(prev->next_free_block) != mm_block) || UNEXPECTED(SUHOSIN_MANGLE_PTR(next->prev_free_block) != mm_block)) {
916
			zend_mm_panic("zend_mm_heap corrupted");
917
		}
918
#endif
919
920
		prev->next_free_block = SUHOSIN_MANGLE_PTR(next);
921
		next->prev_free_block = SUHOSIN_MANGLE_PTR(prev);
922
923
		if (EXPECTED(ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block)))) {
924
			if (EXPECTED(prev == next)) {
925
				size_t index = ZEND_MM_BUCKET_INDEX(ZEND_MM_FREE_BLOCK_SIZE(mm_block));
926
927
				if (EXPECTED(heap->free_buckets[index*2] == heap->free_buckets[index*2+1])) {
928
					heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
929
				}
930
			}
931
		} else if (UNEXPECTED(mm_block->parent != NULL)) {
932
			goto subst_block;
933
		}
934
	}
935
}
936
937
static void zend_mm_init(zend_mm_heap_canary *heap)
938
{
939
	zend_mm_free_block_canary* p;
940
	int i;
941
942
	heap->free_bitmap = 0;
943
	heap->large_free_bitmap = 0;
944
#if ZEND_MM_CACHE
945
	heap->cached = 0;
946
	memset(heap->cache, 0, sizeof(heap->cache));
947
#endif
948
#if ZEND_MM_CACHE_STAT
949
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
950
		heap->cache_stat[i].count = 0;
951
	}
952
#endif
953
	p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
954
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
955
		p->next_free_block = SUHOSIN_MANGLE_PTR(p);
956
		p->prev_free_block = SUHOSIN_MANGLE_PTR(p);
957
		p = (zend_mm_free_block_canary*)((char*)p + sizeof(zend_mm_free_block_canary*) * 2);
958
		heap->large_free_buckets[i] = NULL;
959
	}
960
	heap->rest_buckets[0] = heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(heap));
961
#if SUHOSIN_PATCH
962
        if (SUHOSIN_CONFIG(SUHOSIN_MM_USE_CANARY_PROTECTION)) {
963
	        zend_canary(&heap->canary_1, sizeof(heap->canary_1));
964
	        zend_canary(&heap->canary_2, sizeof(heap->canary_2));
965
	        zend_canary(&heap->canary_3, sizeof(heap->canary_3));
966
	}
967
#endif
968
}
969
970
static void zend_mm_del_segment(zend_mm_heap_canary *heap, zend_mm_segment *segment)
971
{
972
	zend_mm_segment **p = &heap->segments_list;
973
974
	while (*p != segment) {
975
		p = &(*p)->next_segment;
976
	}
977
	*p = segment->next_segment;
978
	heap->real_size -= segment->size;
979
	ZEND_MM_STORAGE_FREE(segment);
980
}
981
982
#if ZEND_MM_CACHE
983
static void zend_mm_free_cache(zend_mm_heap_canary *heap)
984
{
985
	int i;
986
987
	for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
988
		/* SUHOSIN_MANGLE_PTR should NOT affect NULL pointers */
989
		if (heap->cache[i]) {
990
			zend_mm_free_block_canary *mm_block = SUHOSIN_MANGLE_PTR(heap->cache[i]);
991
992
			while (mm_block) {
993
				size_t size = ZEND_MM_BLOCK_SIZE(mm_block);
994
				zend_mm_free_block_canary *q = SUHOSIN_MANGLE_PTR(mm_block->prev_free_block);
995
				zend_mm_block_canary *next_block = ZEND_MM_NEXT_BLOCK(mm_block);
996
997
				heap->cached -= size;
998
999
				if (ZEND_MM_PREV_BLOCK_IS_FREE(mm_block)) {
1000
					mm_block = (zend_mm_free_block_canary*)ZEND_MM_PREV_BLOCK(mm_block);
1001
					size += ZEND_MM_FREE_BLOCK_SIZE(mm_block);
1002
					zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) mm_block);
1003
				}
1004
				if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
1005
					size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
1006
					zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
1007
				}
1008
				ZEND_MM_BLOCK(mm_block, ZEND_MM_FREE_BLOCK, size);
1009
1010
				if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
1011
				    ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_NEXT_BLOCK(mm_block))) {
1012
					zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE));
1013
				} else {
1014
					zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) mm_block);
1015
				}
1016
1017
				mm_block = q;
1018
			}
1019
			heap->cache[i] = NULL;
1020
#if ZEND_MM_CACHE_STAT
1021
			heap->cache_stat[i].count = 0;
1022
#endif
1023
		}
1024
	}
1025
}
1026
#endif
1027
1028
#if ZEND_MM_HEAP_PROTECTION || ZEND_MM_COOKIES
1029
static void zend_mm_random(unsigned char *buf, size_t size) /* {{{ */
1030
{
1031
	size_t i = 0;
1032
	unsigned char t;
1033
1034
#ifdef ZEND_WIN32
1035
	HCRYPTPROV   hCryptProv;
1036
	int has_context = 0;
1037
1038
	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)) {
1039
		/* Could mean that the key container does not exist, let try 
1040
		   again by asking for a new one */
1041
		if (GetLastError() == NTE_BAD_KEYSET) {
1042
			if (CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
1043
				has_context = 1;
1044
			}
1045
		}
1046
	} else {
1047
		has_context = 1;
1048
	}
1049
	if (has_context) {
1050
		do {
1051
			BOOL ret = CryptGenRandom(hCryptProv, size, buf);
1052
			CryptReleaseContext(hCryptProv, 0);
1053
			if (ret) {
1054
				while (i < size && buf[i] != 0) {
1055
					i++;
1056
				}
1057
				if (i == size) {
1058
					return;
1059
				}
1060
		   }
1061
		} while (0);
1062
	}
1063
#elif defined(HAVE_DEV_URANDOM)
1064
	int fd = open("/dev/urandom", 0);
1065
1066
	if (fd >= 0) {
1067
		if (read(fd, buf, size) == size) {
1068
			while (i < size && buf[i] != 0) {
1069
				i++;
1070
			}
1071
			if (i == size) {
1072
				close(fd);
1073
			    return;
1074
			}
1075
		}
1076
		close(fd);
1077
	}
1078
#endif
1079
	t = (unsigned char)getpid();
1080
	while (i < size) {
1081
		do {
1082
			buf[i] = ((unsigned char)rand()) ^ t;
1083
		} while (buf[i] == 0);
1084
		t = buf[i++] << 1;
1085
    }
1086
}
1087
/* }}} */
1088
#endif
1089
1090
1091
/* Notes:
1092
 * - This function may alter the block_sizes values to match platform alignment
1093
 * - This function does *not* perform sanity checks on the arguments
1094
 */
1095
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)
1096
{
1097
	zend_mm_storage *storage;
1098
	zend_mm_heap_canary    *heap;
1099
        zend_mm_free_block_canary *tmp;
1100
1101
#if 0
1102
	int i;
1103
1104
	printf("ZEND_MM_ALIGNMENT=%d\n", ZEND_MM_ALIGNMENT);
1105
	printf("ZEND_MM_ALIGNMENT_LOG2=%d\n", ZEND_MM_ALIGNMENT_LOG2);
1106
	printf("ZEND_MM_MIN_SIZE=%d\n", ZEND_MM_MIN_SIZE);
1107
	printf("ZEND_MM_MAX_SMALL_SIZE=%d\n", ZEND_MM_MAX_SMALL_SIZE);
1108
	printf("ZEND_MM_ALIGNED_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_HEADER_SIZE);
1109
	printf("ZEND_MM_ALIGNED_FREE_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_FREE_HEADER_SIZE);
1110
	printf("ZEND_MM_MIN_ALLOC_BLOCK_SIZE=%d\n", ZEND_MM_MIN_ALLOC_BLOCK_SIZE);
1111
	printf("ZEND_MM_ALIGNED_MIN_HEADER_SIZE=%d\n", ZEND_MM_ALIGNED_MIN_HEADER_SIZE);
1112
	printf("ZEND_MM_ALIGNED_SEGMENT_SIZE=%d\n", ZEND_MM_ALIGNED_SEGMENT_SIZE);
1113
	for (i = 0; i < ZEND_MM_MAX_SMALL_SIZE; i++) {
1114
		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)));
1115
	}
1116
	exit(0);
1117
#endif
1118
1119
#if ZEND_MM_HEAP_PROTECTION
1120
	if (_mem_block_start_magic == 0) {
1121
		zend_mm_random((unsigned char*)&_mem_block_start_magic, sizeof(_mem_block_start_magic));
1122
	}
1123
	if (_mem_block_end_magic == 0) {
1124
		zend_mm_random((unsigned char*)&_mem_block_end_magic, sizeof(_mem_block_end_magic));
1125
	}
1126
#endif
1127
#if ZEND_MM_COOKIES
1128
	if (_zend_mm_cookie == 0) {
1129
		zend_mm_random((unsigned char*)&_zend_mm_cookie, sizeof(_zend_mm_cookie));
1130
	}
1131
#endif
1132
1133
        /* get the pointer guardian and ensure low 3 bits are 1 */
1134
        if (SUHOSIN_POINTER_GUARD == 0) {
1135
                zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
1136
                SUHOSIN_POINTER_GUARD |= 7;
1137
        }
1138
1139
	if (zend_mm_low_bit(block_size) != zend_mm_high_bit(block_size)) {
1140
		fprintf(stderr, "'block_size' must be a power of two\n");
1141
/* See http://support.microsoft.com/kb/190351 */
1142
#ifdef PHP_WIN32
1143
		fflush(stderr);
1144
#endif
1145
		exit(255);
1146
	}
1147
	storage = handlers->init(params);
1148
	if (!storage) {
1149
		fprintf(stderr, "Cannot initialize zend_mm storage [%s]\n", handlers->name);
1150
/* See http://support.microsoft.com/kb/190351 */
1151
#ifdef PHP_WIN32
1152
		fflush(stderr);
1153
#endif
1154
		exit(255);
1155
	}
1156
	storage->handlers = handlers;
1157
1158
	heap = malloc(sizeof(struct _zend_mm_heap_canary));
1159
	if (heap == NULL) {
1160
		fprintf(stderr, "Cannot allocate heap for zend_mm storage [%s]\n", handlers->name);
1161
#ifdef PHP_WIN32
1162
		fflush(stderr);
1163
#endif
1164
		exit(255);
1165
	}
1166
1167
	heap->storage = storage;
1168
	heap->block_size = block_size;
1169
	heap->compact_size = 0;
1170
	heap->segments_list = NULL;
1171
	zend_mm_init(heap);
1172
# if ZEND_MM_CACHE_STAT
1173
	memset(heap->cache_stat, 0, sizeof(heap->cache_stat));
1174
# endif
1175
1176
	heap->use_zend_alloc = 1;
1177
	heap->real_size = 0;
1178
	heap->overflow = 0;
1179
	heap->real_peak = 0;
1180
	heap->limit = ZEND_MM_LONG_CONST(1)<<(ZEND_MM_NUM_BUCKETS-2);
1181
	heap->size = 0;
1182
	heap->peak = 0;
1183
	heap->internal = internal;
1184
	heap->reserve = NULL;
1185
	heap->reserve_size = reserve_size;
1186
	if (reserve_size > 0) {
1187
		heap->reserve = _zend_mm_alloc((zend_mm_heap *)heap, reserve_size ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1188
	}
1189
	if (internal) {
1190
		int i;
1191
		zend_mm_free_block_canary *p, *q, *orig;
1192
		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);
1193
1194
		*mm_heap = *heap;
1195
1196
		p = ZEND_MM_SMALL_FREE_BUCKET(mm_heap, 0);
1197
		orig = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
1198
		for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
1199
			q = p;
1200
			while (SUHOSIN_MANGLE_PTR(q->prev_free_block) != orig) {
1201
				q = SUHOSIN_MANGLE_PTR(q->prev_free_block);
1202
			}
1203
			q->prev_free_block = SUHOSIN_MANGLE_PTR(p);
1204
			q = p;
1205
			while (SUHOSIN_MANGLE_PTR(q->next_free_block) != orig) {
1206
				q = SUHOSIN_MANGLE_PTR(q->next_free_block);
1207
			}
1208
			q->next_free_block = SUHOSIN_MANGLE_PTR(p);
1209
			p = (zend_mm_free_block_canary*)((char*)p + sizeof(zend_mm_free_block_canary*) * 2);
1210
			orig = (zend_mm_free_block_canary*)((char*)orig + sizeof(zend_mm_free_block_canary*) * 2);
1211
			if (mm_heap->large_free_buckets[i]) {
1212
				mm_heap->large_free_buckets[i]->parent = &mm_heap->large_free_buckets[i];
1213
			}
1214
		}
1215
		mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = SUHOSIN_MANGLE_PTR(ZEND_MM_REST_BUCKET(mm_heap));
1216
1217
		free(heap);
1218
		heap = mm_heap;
1219
	}
1220
	return heap;
1221
}
1222
1223
zend_mm_heap_canary *__zend_mm_startup_canary(void)
1224
{
1225
	int i;
1226
	size_t seg_size;
1227
	char *mem_type = getenv("ZEND_MM_MEM_TYPE");
1228
	char *tmp;
1229
	const zend_mm_mem_handlers *handlers;
1230
	zend_mm_heap_canary *heap;
1231
1232
	if (mem_type == NULL) {
1233
		i = 0;
1234
	} else {
1235
		for (i = 0; mem_handlers[i].name; i++) {
1236
			if (strcmp(mem_handlers[i].name, mem_type) == 0) {
1237
				break;
1238
			}
1239
		}
1240
		if (!mem_handlers[i].name) {
1241
			fprintf(stderr, "Wrong or unsupported zend_mm storage type '%s'\n", mem_type);
1242
			fprintf(stderr, "  supported types:\n");
1243
/* See http://support.microsoft.com/kb/190351 */
1244
#ifdef PHP_WIN32
1245
			fflush(stderr);
1246
#endif
1247
			for (i = 0; mem_handlers[i].name; i++) {
1248
				fprintf(stderr, "    '%s'\n", mem_handlers[i].name);
1249
			}
1250
/* See http://support.microsoft.com/kb/190351 */
1251
#ifdef PHP_WIN32
1252
			fflush(stderr);
1253
#endif
1254
			exit(255);
1255
		}
1256
	}
1257
	handlers = &mem_handlers[i];
1258
1259
	tmp = getenv("ZEND_MM_SEG_SIZE");
1260
	if (tmp) {
1261
		seg_size = zend_atoi(tmp, 0);
1262
		if (zend_mm_low_bit(seg_size) != zend_mm_high_bit(seg_size)) {
1263
			fprintf(stderr, "ZEND_MM_SEG_SIZE must be a power of two\n");
1264
/* See http://support.microsoft.com/kb/190351 */
1265
#ifdef PHP_WIN32
1266
			fflush(stderr);
1267
#endif
1268
			exit(255);
1269
		} else if (seg_size < ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE) {
1270
			fprintf(stderr, "ZEND_MM_SEG_SIZE is too small\n");
1271
/* See http://support.microsoft.com/kb/190351 */
1272
#ifdef PHP_WIN32
1273
			fflush(stderr);
1274
#endif
1275
			exit(255);
1276
		}
1277
	} else {
1278
		seg_size = ZEND_MM_SEG_SIZE;
1279
	}
1280
1281
	heap = __zend_mm_startup_canary_ex(handlers, seg_size, ZEND_MM_RESERVE_SIZE, 0, NULL);
1282
	if (heap) {
1283
		tmp = getenv("ZEND_MM_COMPACT");
1284
		if (tmp) {
1285
			heap->compact_size = zend_atoi(tmp, 0);
1286
		} else {
1287
			heap->compact_size = 2 * 1024 * 1024;
1288
		}
1289
	}
1290
	return heap;
1291
}
1292
1293
#if ZEND_DEBUG
1294
static long zend_mm_find_leaks(zend_mm_segment *segment, zend_mm_block_canary *b)
1295
{
1296
	long leaks = 0;
1297
	zend_mm_block_canary *p, *q;
1298
1299
	p = ZEND_MM_NEXT_BLOCK(b);
1300
	while (1) {
1301
		if (ZEND_MM_IS_GUARD_BLOCK(p)) {
1302
			ZEND_MM_CHECK_MAGIC(p, MEM_BLOCK_GUARD);
1303
			segment = segment->next_segment;
1304
			if (!segment) {
1305
				break;
1306
			}
1307
			p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
1308
			continue;
1309
		}
1310
		q = ZEND_MM_NEXT_BLOCK(p);
1311
		if (q <= p ||
1312
		    (char*)q > (char*)segment + segment->size ||
1313
		    p->info._size != q->info._prev) {
1314
		    zend_mm_panic("zend_mm_heap corrupted");
1315
		}
1316
		if (!ZEND_MM_IS_FREE_BLOCK(p)) {
1317
			if (p->magic == MEM_BLOCK_VALID) {
1318
				if (p->debug.filename==b->debug.filename && p->debug.lineno==b->debug.lineno) {
1319
					ZEND_MM_SET_MAGIC(p, MEM_BLOCK_LEAK);
1320
					leaks++;
1321
				}
1322
#if ZEND_MM_CACHE
1323
			} else if (p->magic == MEM_BLOCK_CACHED) {
1324
				/* skip it */
1325
#endif
1326
			} else if (p->magic != MEM_BLOCK_LEAK) {
1327
			    zend_mm_panic("zend_mm_heap corrupted");
1328
			}
1329
		}
1330
		p = q;
1331
	}
1332
	return leaks;
1333
}
1334
1335
static void zend_mm_check_leaks(zend_mm_heap_canary *heap TSRMLS_DC)
1336
{
1337
	zend_mm_segment *segment = heap->segments_list;
1338
	zend_mm_block_canary *p, *q;
1339
	zend_uint total = 0;
1340
1341
	if (!segment) {
1342
		return;
1343
	}
1344
	p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
1345
	while (1) {
1346
		q = ZEND_MM_NEXT_BLOCK(p);
1347
		if (q <= p ||
1348
		    (char*)q > (char*)segment + segment->size ||
1349
		    p->info._size != q->info._prev) {
1350
			zend_mm_panic("zend_mm_heap corrupted");
1351
		}
1352
		if (!ZEND_MM_IS_FREE_BLOCK(p)) {
1353
			if (p->magic == MEM_BLOCK_VALID) {
1354
				long repeated;
1355
				zend_leak_info leak;
1356
1357
				ZEND_MM_SET_MAGIC(p, MEM_BLOCK_LEAK);
1358
1359
				leak.addr = ZEND_MM_DATA_OF(p);
1360
				leak.size = p->debug.size;
1361
				leak.filename = p->debug.filename;
1362
				leak.lineno = p->debug.lineno;
1363
				leak.orig_filename = p->debug.orig_filename;
1364
				leak.orig_lineno = p->debug.orig_lineno;
1365
1366
				zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
1367
				zend_message_dispatcher(ZMSG_MEMORY_LEAK_DETECTED, &leak TSRMLS_CC);
1368
				repeated = zend_mm_find_leaks(segment, p);
1369
				total += 1 + repeated;
1370
				if (repeated) {
1371
					zend_message_dispatcher(ZMSG_MEMORY_LEAK_REPEATED, (void *)(zend_uintptr_t)repeated TSRMLS_CC);
1372
				}
1373
#if ZEND_MM_CACHE
1374
			} else if (p->magic == MEM_BLOCK_CACHED) {
1375
				/* skip it */
1376
#endif
1377
			} else if (p->magic != MEM_BLOCK_LEAK) {
1378
				zend_mm_panic("zend_mm_heap corrupted");
1379
			}
1380
		}
1381
		if (ZEND_MM_IS_GUARD_BLOCK(q)) {
1382
			segment = segment->next_segment;
1383
			if (!segment) {
1384
				break;
1385
			}
1386
			q = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
1387
		}
1388
		p = q;
1389
	}
1390
	if (total) {
1391
		zend_message_dispatcher(ZMSG_MEMORY_LEAKS_GRAND_TOTAL, &total TSRMLS_CC);
1392
	}
1393
}
1394
1395
static int zend_mm_check_ptr(zend_mm_heap_canary *heap, void *ptr, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1396
{
1397
	zend_mm_block_canary *p;
1398
	int no_cache_notice = 0;
1399
	int had_problems = 0;
1400
	int valid_beginning = 1;
1401
1402
	if (silent==2) {
1403
		silent = 1;
1404
		no_cache_notice = 1;
1405
	} else if (silent==3) {
1406
		silent = 0;
1407
		no_cache_notice = 1;
1408
	}
1409
	if (!silent) {
1410
		TSRMLS_FETCH();
1411
		
1412
		zend_message_dispatcher(ZMSG_LOG_SCRIPT_NAME, NULL TSRMLS_CC);
1413
		zend_debug_alloc_output("---------------------------------------\n");
1414
		zend_debug_alloc_output("%s(%d) : Block "PTR_FMT" status:\n" ZEND_FILE_LINE_RELAY_CC, ptr);
1415
		if (__zend_orig_filename) {
1416
			zend_debug_alloc_output("%s(%d) : Actual location (location was relayed)\n" ZEND_FILE_LINE_ORIG_RELAY_CC);
1417
		}
1418
		if (!ptr) {
1419
			zend_debug_alloc_output("NULL\n");
1420
			zend_debug_alloc_output("---------------------------------------\n");
1421
			return 0;
1422
		}
1423
	}
1424
1425
	if (!ptr) {
1426
		if (silent) {
1427
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1428
		}
1429
	}
1430
1431
	p = ZEND_MM_HEADER_OF(ptr);
1432
1433
#ifdef ZTS
1434
	if (ZEND_MM_BAD_THREAD_ID(p)) {
1435
		if (!silent) {
1436
			zend_debug_alloc_output("Invalid pointer: ((thread_id=0x%0.8X) != (expected=0x%0.8X))\n", (long)p->thread_id, (long)tsrm_thread_id());
1437
			had_problems = 1;
1438
		} else {
1439
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1440
		}
1441
	}
1442
#endif
1443
1444
	if (p->info._size != ZEND_MM_NEXT_BLOCK(p)->info._prev) {
1445
		if (!silent) {
1446
			zend_debug_alloc_output("Invalid pointer: ((size="PTR_FMT") != (next.prev="PTR_FMT"))\n", p->info._size, ZEND_MM_NEXT_BLOCK(p)->info._prev);
1447
			had_problems = 1;
1448
		} else {
1449
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1450
		}
1451
	}
1452
	if (p->info._prev != ZEND_MM_GUARD_BLOCK &&
1453
	    ZEND_MM_PREV_BLOCK(p)->info._size != p->info._prev) {
1454
		if (!silent) {
1455
			zend_debug_alloc_output("Invalid pointer: ((prev="PTR_FMT") != (prev.size="PTR_FMT"))\n", p->info._prev, ZEND_MM_PREV_BLOCK(p)->info._size);
1456
			had_problems = 1;
1457
		} else {
1458
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1459
		}
1460
	}
1461
1462
	if (had_problems) {
1463
		zend_debug_alloc_output("---------------------------------------\n");
1464
		return 0;
1465
	}
1466
1467
	if (!silent) {
1468
		zend_debug_alloc_output("%10s\t","Beginning:  ");
1469
	}
1470
1471
	if (!ZEND_MM_IS_USED_BLOCK(p)) {
1472
		if (!silent) {
1473
			if (p->magic != MEM_BLOCK_FREED) {
1474
				zend_debug_alloc_output("Freed (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_FREED);
1475
			} else {
1476
				zend_debug_alloc_output("Freed\n");
1477
			}
1478
			had_problems = 1;
1479
		} else {
1480
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1481
		}
1482
	} else if (ZEND_MM_IS_GUARD_BLOCK(p)) {
1483
		if (!silent) {
1484
			if (p->magic != MEM_BLOCK_FREED) {
1485
				zend_debug_alloc_output("Guard (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_FREED);
1486
			} else {
1487
				zend_debug_alloc_output("Guard\n");
1488
			}
1489
			had_problems = 1;
1490
		} else {
1491
			return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1492
		}
1493
	} else {
1494
		switch (p->magic) {
1495
			case MEM_BLOCK_VALID:
1496
			case MEM_BLOCK_LEAK:
1497
				if (!silent) {
1498
					zend_debug_alloc_output("OK (allocated on %s:%d, %d bytes)\n", p->debug.filename, p->debug.lineno, (int)p->debug.size);
1499
				}
1500
				break; /* ok */
1501
			case MEM_BLOCK_CACHED:
1502
				if (!no_cache_notice) {
1503
					if (!silent) {
1504
						zend_debug_alloc_output("Cached\n");
1505
						had_problems = 1;
1506
					} else {
1507
						return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1508
					}
1509
				}
1510
			case MEM_BLOCK_FREED:
1511
				if (!silent) {
1512
					zend_debug_alloc_output("Freed (invalid)\n");
1513
					had_problems = 1;
1514
				} else {
1515
					return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1516
				}
1517
				break;
1518
			case MEM_BLOCK_GUARD:
1519
				if (!silent) {
1520
					zend_debug_alloc_output("Guard (invalid)\n");
1521
					had_problems = 1;
1522
				} else {
1523
					return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1524
				}
1525
				break;
1526
			default:
1527
				if (!silent) {
1528
					zend_debug_alloc_output("Unknown (magic=0x%0.8X, expected=0x%0.8X)\n", p->magic, MEM_BLOCK_VALID);
1529
					had_problems = 1;
1530
					valid_beginning = 0;
1531
				} else {
1532
					return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1533
				}
1534
				break;
1535
		}
1536
	}
1537
1538
#if ZEND_MM_HEAP_PROTECTION
1539
	if (!valid_beginning) {
1540
		if (!silent) {
1541
			zend_debug_alloc_output("%10s\t", "Start:");
1542
			zend_debug_alloc_output("Unknown\n");
1543
			zend_debug_alloc_output("%10s\t", "End:");
1544
			zend_debug_alloc_output("Unknown\n");
1545
		}
1546
	} else {
1547
		char *end_magic = ZEND_MM_END_MAGIC_PTR(p);
1548
1549
		if (p->debug.start_magic == _mem_block_start_magic) {
1550
			if (!silent) {
1551
				zend_debug_alloc_output("%10s\t", "Start:");
1552
				zend_debug_alloc_output("OK\n");
1553
			}
1554
		} else {
1555
			char *overflow_ptr, *magic_ptr=(char *) &_mem_block_start_magic;
1556
			int overflows=0;
1557
			int i;
1558
1559
			if (silent) {
1560
				return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1561
			}
1562
			had_problems = 1;
1563
			overflow_ptr = (char *) &p->debug.start_magic;
1564
			i = END_MAGIC_SIZE;
1565
			while (--i >= 0) {
1566
				if (overflow_ptr[i]!=magic_ptr[i]) {
1567
					overflows++;
1568
				}
1569
			}
1570
			zend_debug_alloc_output("%10s\t", "Start:");
1571
			zend_debug_alloc_output("Overflown (magic=0x%0.8X instead of 0x%0.8X)\n", p->debug.start_magic, _mem_block_start_magic);
1572
			zend_debug_alloc_output("%10s\t","");
1573
			if (overflows >= END_MAGIC_SIZE) {
1574
				zend_debug_alloc_output("At least %d bytes overflown\n", END_MAGIC_SIZE);
1575
			} else {
1576
				zend_debug_alloc_output("%d byte(s) overflown\n", overflows);
1577
			}
1578
		}
1579
		if (memcmp(end_magic, &_mem_block_end_magic, END_MAGIC_SIZE)==0) {
1580
			if (!silent) {
1581
				zend_debug_alloc_output("%10s\t", "End:");
1582
				zend_debug_alloc_output("OK\n");
1583
			}
1584
		} else {
1585
			char *overflow_ptr, *magic_ptr=(char *) &_mem_block_end_magic;
1586
			int overflows=0;
1587
			int i;
1588
1589
			if (silent) {
1590
				return _mem_block_check(ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1591
			}
1592
			had_problems = 1;
1593
			overflow_ptr = (char *) end_magic;
1594
1595
			for (i=0; i < END_MAGIC_SIZE; i++) {
1596
				if (overflow_ptr[i]!=magic_ptr[i]) {
1597
					overflows++;
1598
				}
1599
			}
1600
1601
			zend_debug_alloc_output("%10s\t", "End:");
1602
			zend_debug_alloc_output("Overflown (magic=0x%0.8X instead of 0x%0.8X)\n", *end_magic, _mem_block_end_magic);
1603
			zend_debug_alloc_output("%10s\t","");
1604
			if (overflows >= END_MAGIC_SIZE) {
1605
				zend_debug_alloc_output("At least %d bytes overflown\n", END_MAGIC_SIZE);
1606
			} else {
1607
				zend_debug_alloc_output("%d byte(s) overflown\n", overflows);
1608
			}
1609
		}
1610
	}
1611
#endif
1612
1613
	if (!silent) {
1614
		zend_debug_alloc_output("---------------------------------------\n");
1615
	}
1616
	return ((!had_problems) ? 1 : 0);
1617
}
1618
1619
static int zend_mm_check_heap(zend_mm_heap_canary *heap, int silent ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1620
{
1621
	zend_mm_segment *segment = heap->segments_list;
1622
	zend_mm_block_canary *p, *q;
1623
	int errors = 0;
1624
1625
	if (!segment) {
1626
		return 0;
1627
	}
1628
	p = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
1629
	while (1) {
1630
		q = ZEND_MM_NEXT_BLOCK(p);
1631
		if (q <= p ||
1632
		    (char*)q > (char*)segment + segment->size ||
1633
		    p->info._size != q->info._prev) {
1634
			zend_mm_panic("zend_mm_heap corrupted");
1635
		}
1636
		if (!ZEND_MM_IS_FREE_BLOCK(p)) {
1637
			if (p->magic == MEM_BLOCK_VALID || p->magic == MEM_BLOCK_LEAK) {
1638
				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)) {
1639
					errors++;
1640
				}
1641
#if ZEND_MM_CACHE
1642
			} else if (p->magic == MEM_BLOCK_CACHED) {
1643
				/* skip it */
1644
#endif
1645
			} else if (p->magic != MEM_BLOCK_LEAK) {
1646
				zend_mm_panic("zend_mm_heap corrupted");
1647
			}
1648
		}
1649
		if (ZEND_MM_IS_GUARD_BLOCK(q)) {
1650
			segment = segment->next_segment;
1651
			if (!segment) {
1652
				return errors;
1653
			}
1654
			q = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
1655
		}
1656
		p = q;
1657
	}
1658
}
1659
#endif
1660
1661
void __zend_mm_shutdown_canary(zend_mm_heap_canary *heap, int full_shutdown, int silent TSRMLS_DC)
1662
{
1663
	zend_mm_storage *storage;
1664
	zend_mm_segment *segment;
1665
	zend_mm_segment *prev;
1666
	int internal;
1667
1668
	if (heap->reserve) {
1669
#if ZEND_DEBUG
1670
		if (!silent) {
1671
			_zend_mm_free(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1672
		}
1673
#endif
1674
		heap->reserve = NULL;
1675
	}
1676
1677
#if ZEND_MM_CACHE_STAT
1678
	if (full_shutdown) {
1679
		FILE *f;
1680
1681
		f = fopen("zend_mm.log", "w");
1682
		if (f) {
1683
			int i,j;
1684
			size_t size, true_size, min_size, max_size;
1685
			int hit = 0, miss = 0;
1686
1687
			fprintf(f, "\nidx min_size max_size true_size  max_len     hits   misses\n");
1688
			size = 0;
1689
			while (1) {
1690
				true_size = ZEND_MM_TRUE_SIZE(size);
1691
				if (ZEND_MM_SMALL_SIZE(true_size)) {
1692
					min_size = size;
1693
					i = ZEND_MM_BUCKET_INDEX(true_size);
1694
					size++;
1695
					while (1) {
1696
						true_size = ZEND_MM_TRUE_SIZE(size);
1697
						if (ZEND_MM_SMALL_SIZE(true_size)) {
1698
							j = ZEND_MM_BUCKET_INDEX(true_size);
1699
							if (j > i) {
1700
								max_size = size-1;
1701
								break;
1702
							}
1703
						} else {
1704
							max_size = size-1;
1705
							break;
1706
						}
1707
						size++;
1708
					}
1709
					hit += heap->cache_stat[i].hit;
1710
					miss += heap->cache_stat[i].miss;
1711
					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);
1712
				} else {
1713
					break;
1714
				}
1715
			}
1716
			fprintf(f, "                                        %8d %8d\n", hit, miss);
1717
			fprintf(f, "                                        %8d %8d\n", heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit, heap->cache_stat[ZEND_MM_NUM_BUCKETS].miss);
1718
			fclose(f);
1719
		}
1720
	}
1721
#endif
1722
1723
#if ZEND_DEBUG
1724
	if (!silent) {
1725
		zend_mm_check_leaks(heap TSRMLS_CC);
1726
	}
1727
#endif
1728
1729
	internal = heap->internal;
1730
	storage = heap->storage;
1731
	segment = heap->segments_list;
1732
	while (segment) {
1733
		prev = segment;
1734
		segment = segment->next_segment;
1735
		ZEND_MM_STORAGE_FREE(prev);
1736
	}
1737
	if (full_shutdown) {
1738
		storage->handlers->dtor(storage);
1739
		if (!internal) {
1740
			free(heap);
1741
		}
1742
	} else {
1743
		if (heap->compact_size &&
1744
		    heap->real_peak > heap->compact_size) {
1745
			storage->handlers->compact(storage);
1746
		}
1747
		heap->segments_list = NULL;
1748
		zend_mm_init(heap);
1749
		heap->real_size = 0;
1750
		heap->real_peak = 0;
1751
		heap->size = 0;
1752
		heap->peak = 0;
1753
		if (heap->reserve_size) {
1754
			heap->reserve = _zend_mm_alloc((zend_mm_heap *)heap, heap->reserve_size  ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1755
		}
1756
		heap->overflow = 0;
1757
	}
1758
}
1759
1760
static void zend_mm_safe_error(zend_mm_heap_canary *heap,
1761
	const char *format,
1762
	size_t limit,
1763
#if ZEND_DEBUG
1764
	const char *filename,
1765
	uint lineno,
1766
#endif
1767
	size_t size)
1768
{
1769
	if (heap->reserve) {
1770
		_zend_mm_free_canary_int(heap, heap->reserve ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
1771
		heap->reserve = NULL;
1772
	}
1773
	if (heap->overflow == 0) {
1774
		char *error_filename;
1775
		uint error_lineno;
1776
		TSRMLS_FETCH();
1777
		if (zend_is_compiling(TSRMLS_C)) {
1778
			error_filename = zend_get_compiled_filename(TSRMLS_C);
1779
			error_lineno = zend_get_compiled_lineno(TSRMLS_C);
1780
		} else if (EG(in_execution)) {
1781
			error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
1782
			error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
1783
		} else {
1784
			error_filename = NULL;
1785
			error_lineno = 0;
1786
		}
1787
		if (!error_filename) {
1788
			error_filename = "Unknown";
1789
		}
1790
		heap->overflow = 1;
1791
		zend_try {
1792
			zend_error_noreturn(E_ERROR,
1793
				format,
1794
				limit,
1795
#if ZEND_DEBUG
1796
				filename,
1797
				lineno,
1798
#endif
1799
				size);
1800
		} zend_catch {
1801
			if (heap->overflow == 2) {
1802
				fprintf(stderr, "\nFatal error: ");
1803
				fprintf(stderr,
1804
					format,
1805
					limit,
1806
#if ZEND_DEBUG
1807
					filename,
1808
					lineno,
1809
#endif
1810
					size);
1811
				fprintf(stderr, " in %s on line %d\n", error_filename, error_lineno);
1812
			}
1813
/* See http://support.microsoft.com/kb/190351 */
1814
#ifdef PHP_WIN32
1815
			fflush(stderr);
1816
#endif
1817
		} zend_end_try();
1818
	} else {
1819
		heap->overflow = 2;
1820
	}
1821
	zend_bailout();
1822
}
1823
1824
static zend_mm_free_block_canary *zend_mm_search_large_block(zend_mm_heap_canary *heap, size_t true_size)
1825
{
1826
	zend_mm_free_block_canary *best_fit;
1827
	size_t index = ZEND_MM_LARGE_BUCKET_INDEX(true_size);
1828
	size_t bitmap = heap->large_free_bitmap >> index;
1829
	zend_mm_free_block_canary *p;
1830
1831
	if (bitmap == 0) {
1832
		return NULL;
1833
	}
1834
1835
	if (UNEXPECTED((bitmap & 1) != 0)) {
1836
		/* Search for best "large" free block */
1837
		zend_mm_free_block_canary *rst = NULL;
1838
		size_t m;
1839
		size_t best_size = -1;
1840
1841
		best_fit = NULL;
1842
		p = heap->large_free_buckets[index];
1843
		for (m = true_size << (ZEND_MM_NUM_BUCKETS - index); ; m <<= 1) {
1844
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1845
				return SUHOSIN_MANGLE_PTR(p->next_free_block);
1846
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size &&
1847
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1848
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1849
				best_fit = p;
1850
			}
1851
			if ((m & (ZEND_MM_LONG_CONST(1) << (ZEND_MM_NUM_BUCKETS-1))) == 0) {
1852
				if (p->child[1]) {
1853
					rst = p->child[1];
1854
				}
1855
				if (p->child[0]) {
1856
					p = p->child[0];
1857
				} else {
1858
					break;
1859
				}
1860
			} else if (p->child[1]) {
1861
				p = p->child[1];
1862
			} else {
1863
				break;
1864
			}
1865
		}
1866
1867
		for (p = rst; p; p = p->child[p->child[0] != NULL]) {
1868
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1869
				return SUHOSIN_MANGLE_PTR(p->next_free_block);
1870
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
1871
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1872
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1873
				best_fit = p;
1874
			}
1875
		}
1876
1877
		if (best_fit) {
1878
			return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
1879
		}
1880
		bitmap = bitmap >> 1;
1881
		if (!bitmap) {
1882
			return NULL;
1883
		}
1884
		index++;
1885
	}
1886
1887
	/* Search for smallest "large" free block */
1888
	best_fit = p = heap->large_free_buckets[index + zend_mm_low_bit(bitmap)];
1889
	while ((p = p->child[p->child[0] != NULL])) {
1890
		if (ZEND_MM_FREE_BLOCK_SIZE(p) < ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {
1891
			best_fit = p;
1892
		}
1893
	}
1894
	return SUHOSIN_MANGLE_PTR(best_fit->next_free_block);
1895
}
1896
1897
void *_zend_mm_alloc_canary_int(zend_mm_heap_canary *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
1898
{
1899
	zend_mm_free_block_canary *best_fit;
1900
	size_t true_size = ZEND_MM_TRUE_SIZE(size);
1901
	size_t block_size;
1902
	size_t remaining_size;
1903
	size_t segment_size;
1904
	zend_mm_segment *segment;
1905
	int keep_rest = 0;
1906
	
1907
	if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) {
1908
		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
1909
		size_t bitmap;
1910
1911
		if (UNEXPECTED(true_size < size)) {
1912
			goto out_of_memory;
1913
		}
1914
#if ZEND_MM_CACHE
1915
		if (EXPECTED(heap->cache[index] != NULL)) {
1916
			/* Get block from cache */
1917
#if ZEND_MM_CACHE_STAT
1918
			heap->cache_stat[index].count--;
1919
			heap->cache_stat[index].hit++;
1920
#endif
1921
			best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
1922
			heap->cache[index] = best_fit->prev_free_block;
1923
			heap->cached -= true_size;
1924
#if SUHOSIN_PATCH
1925
                        SUHOSIN_MM_SET_CANARIES(best_fit);
1926
                        ((zend_mm_block_canary*)best_fit)->info.size = size;
1927
                        SUHOSIN_MM_SET_END_CANARY(best_fit);
1928
#endif			
1929
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
1930
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
1931
			return ZEND_MM_DATA_OF(best_fit);
1932
 		}
1933
#if ZEND_MM_CACHE_STAT
1934
		heap->cache_stat[index].miss++;
1935
#endif
1936
#endif
1937
1938
		bitmap = heap->free_bitmap >> index;
1939
		if (bitmap) {
1940
			/* Found some "small" free block that can be used */
1941
			index += zend_mm_low_bit(bitmap);
1942
			best_fit = SUHOSIN_MANGLE_PTR(heap->free_buckets[index*2]);
1943
#if ZEND_MM_CACHE_STAT
1944
			heap->cache_stat[ZEND_MM_NUM_BUCKETS].hit++;
1945
#endif
1946
			goto zend_mm_finished_searching_for_block;
1947
		}
1948
	}
1949
1950
#if ZEND_MM_CACHE_STAT
1951
	heap->cache_stat[ZEND_MM_NUM_BUCKETS].miss++;
1952
#endif
1953
1954
	best_fit = zend_mm_search_large_block(heap, true_size);
1955
1956
	if (!best_fit && heap->real_size >= heap->limit - heap->block_size) {
1957
		zend_mm_free_block_canary *p = SUHOSIN_MANGLE_PTR(heap->rest_buckets[0]);
1958
		size_t best_size = -1;
1959
1960
		while (p != ZEND_MM_REST_BUCKET(heap)) {
1961
			if (UNEXPECTED(ZEND_MM_FREE_BLOCK_SIZE(p) == true_size)) {
1962
				best_fit = p;
1963
				goto zend_mm_finished_searching_for_block;
1964
			} else if (ZEND_MM_FREE_BLOCK_SIZE(p) > true_size &&
1965
			           ZEND_MM_FREE_BLOCK_SIZE(p) < best_size) {
1966
				best_size = ZEND_MM_FREE_BLOCK_SIZE(p);
1967
				best_fit = p;
1968
			}
1969
			p = SUHOSIN_MANGLE_PTR(p->prev_free_block);
1970
		}
1971
	}
1972
1973
	if (!best_fit) {
1974
		if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
1975
			/* Make sure we add a memory block which is big enough,
1976
			   segment must have header "size" and trailer "guard" block */
1977
			segment_size = true_size + ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE;
1978
			segment_size = (segment_size + (heap->block_size-1)) & ~(heap->block_size-1);
1979
			keep_rest = 1;
1980
		} else {
1981
			segment_size = heap->block_size;
1982
		}
1983
1984
		HANDLE_BLOCK_INTERRUPTIONS();
1985
1986
		if (segment_size < true_size ||
1987
		    heap->real_size + segment_size > heap->limit) {
1988
			/* Memory limit overflow */
1989
#if ZEND_MM_CACHE
1990
			zend_mm_free_cache(heap);
1991
#endif
1992
			HANDLE_UNBLOCK_INTERRUPTIONS();
1993
#if ZEND_DEBUG
1994
			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);
1995
#else
1996
			zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %lu bytes)", heap->limit, size);
1997
#endif
1998
		}
1999
2000
		segment = (zend_mm_segment *) ZEND_MM_STORAGE_ALLOC(segment_size);
2001
2002
		if (!segment) {
2003
			/* Storage manager cannot allocate memory */
2004
#if ZEND_MM_CACHE
2005
			zend_mm_free_cache(heap);
2006
#endif
2007
			HANDLE_UNBLOCK_INTERRUPTIONS();
2008
out_of_memory:
2009
#if ZEND_DEBUG
2010
			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);
2011
#else
2012
			zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %lu bytes)", heap->real_size, size);
2013
#endif
2014
			return NULL;
2015
		}
2016
2017
		heap->real_size += segment_size;
2018
		if (heap->real_size > heap->real_peak) {
2019
			heap->real_peak = heap->real_size;
2020
		}
2021
2022
		segment->size = segment_size;
2023
		segment->next_segment = heap->segments_list;
2024
		heap->segments_list = segment;
2025
2026
		best_fit = (zend_mm_free_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2027
		ZEND_MM_MARK_FIRST_BLOCK(best_fit);
2028
2029
		block_size = segment_size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE;
2030
2031
		ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(best_fit, block_size));
2032
2033
	} else {
2034
zend_mm_finished_searching_for_block:
2035
		/* remove from free list */
2036
		HANDLE_BLOCK_INTERRUPTIONS();
2037
		ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_FREED);
2038
		ZEND_MM_CHECK_COOKIE(best_fit);
2039
		ZEND_MM_CHECK_BLOCK_LINKAGE(best_fit);
2040
		zend_mm_remove_from_free_list(heap, best_fit);
2041
2042
		block_size = ZEND_MM_FREE_BLOCK_SIZE(best_fit);
2043
	}
2044
2045
	remaining_size = block_size - true_size;
2046
2047
	if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
2048
		true_size = block_size;
2049
		ZEND_MM_BLOCK(best_fit, ZEND_MM_USED_BLOCK, true_size);
2050
	} else {
2051
		zend_mm_free_block_canary *new_free_block;
2052
2053
		/* prepare new free block */
2054
		ZEND_MM_BLOCK(best_fit, ZEND_MM_USED_BLOCK, true_size);
2055
		new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(best_fit, true_size);
2056
		ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
2057
2058
		/* add the new free block to the free list */
2059
		if (EXPECTED(!keep_rest)) {
2060
			zend_mm_add_to_free_list(heap, new_free_block);
2061
		} else {
2062
			zend_mm_add_to_rest_list(heap, new_free_block);
2063
		}
2064
	}
2065
2066
	ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
2067
2068
#if SUHOSIN_PATCH
2069
        SUHOSIN_MM_SET_CANARIES(best_fit);
2070
        ((zend_mm_block_canary*)best_fit)->info.size = size;
2071
        SUHOSIN_MM_SET_END_CANARY(best_fit);
2072
#endif
2073
        
2074
	heap->size += true_size;
2075
	if (heap->peak < heap->size) {
2076
		heap->peak = heap->size;
2077
	}
2078
2079
	HANDLE_UNBLOCK_INTERRUPTIONS();
2080
	return ZEND_MM_DATA_OF(best_fit);
2081
}
2082
2083
2084
void _zend_mm_free_canary_int(zend_mm_heap_canary *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
2085
{
2086
	zend_mm_block_canary *mm_block;
2087
	zend_mm_block_canary *next_block;
2088
	size_t size;
2089
2090
	if (!ZEND_MM_VALID_PTR(p)) {
2091
		return;
2092
	}
2093
2094
	mm_block = ZEND_MM_HEADER_OF(p);
2095
	size = ZEND_MM_BLOCK_SIZE(mm_block);
2096
#if SUHOSIN_PATCH
2097
        SUHOSIN_MM_CHECK_CANARIES(mm_block, "efree()");
2098
#endif    
2099
	ZEND_MM_CHECK_PROTECTION(mm_block);
2100
2101
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2102
	memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->debug.size);
2103
#endif
2104
#if SUHOSIN_PATCH
2105
        if (UNEXPECTED(SUHOSIN_CONFIG(SUHOSIN_MM_DESTROY_FREE_MEMORY))) {
2106
                memset(ZEND_MM_DATA_OF(mm_block), 0x5a, mm_block->info.size);
2107
        }
2108
#endif
2109
#if ZEND_MM_CACHE
2110
	if (EXPECTED(ZEND_MM_SMALL_SIZE(size)) && EXPECTED(heap->cached < ZEND_MM_CACHE_SIZE)) {
2111
		size_t index = ZEND_MM_BUCKET_INDEX(size);
2112
		zend_mm_free_block_canary **cache = &heap->cache[index];
2113
2114
		((zend_mm_free_block_canary*)mm_block)->prev_free_block = *cache;
2115
		*cache = (zend_mm_free_block_canary*)SUHOSIN_MANGLE_PTR(mm_block);
2116
		heap->cached += size;
2117
		ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2118
#if ZEND_MM_CACHE_STAT
2119
		if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
2120
			heap->cache_stat[index].max_count = heap->cache_stat[index].count;
2121
		}
2122
#endif
2123
		return;
2124
	}
2125
#endif
2126
2127
	HANDLE_BLOCK_INTERRUPTIONS();
2128
2129
	heap->size -= size;
2130
2131
	next_block = ZEND_MM_BLOCK_AT(mm_block, size);
2132
	if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
2133
		zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
2134
		size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
2135
	}
2136
	if (ZEND_MM_PREV_BLOCK_IS_FREE(mm_block)) {
2137
		mm_block = ZEND_MM_PREV_BLOCK(mm_block);
2138
		zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) mm_block);
2139
		size += ZEND_MM_FREE_BLOCK_SIZE(mm_block);
2140
	}
2141
	if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2142
	    ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(mm_block, size))) {
2143
		zend_mm_del_segment(heap, (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE));
2144
	} else {
2145
		ZEND_MM_BLOCK(mm_block, ZEND_MM_FREE_BLOCK, size);
2146
		zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) mm_block);
2147
	}
2148
	HANDLE_UNBLOCK_INTERRUPTIONS();
2149
}
2150
2151
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)
2152
{
2153
	zend_mm_block_canary *mm_block = ZEND_MM_HEADER_OF(p);
2154
	zend_mm_block_canary *next_block;
2155
	size_t true_size;
2156
	size_t orig_size;
2157
	void *ptr;
2158
2159
	if (UNEXPECTED(!p) || !ZEND_MM_VALID_PTR(p)) {
2160
		return _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2161
	}
2162
	mm_block = ZEND_MM_HEADER_OF(p);
2163
	true_size = ZEND_MM_TRUE_SIZE(size);
2164
	orig_size = ZEND_MM_BLOCK_SIZE(mm_block);
2165
#if SUHOSIN_PATCH
2166
        SUHOSIN_MM_CHECK_CANARIES(mm_block, "erealloc()");
2167
#endif	
2168
	ZEND_MM_CHECK_PROTECTION(mm_block);
2169
2170
	if (UNEXPECTED(true_size < size)) {
2171
		goto out_of_memory;
2172
	}
2173
2174
	if (true_size <= orig_size) {
2175
		size_t remaining_size = orig_size - true_size;
2176
2177
		if (remaining_size >= ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
2178
			zend_mm_free_block_canary *new_free_block;
2179
2180
			HANDLE_BLOCK_INTERRUPTIONS();
2181
			next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
2182
			if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
2183
				remaining_size += ZEND_MM_FREE_BLOCK_SIZE(next_block);
2184
				zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
2185
			}
2186
2187
			/* prepare new free block */
2188
			ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
2189
			new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
2190
2191
			ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
2192
2193
			/* add the new free block to the free list */
2194
			zend_mm_add_to_free_list(heap, new_free_block);
2195
			heap->size += (true_size - orig_size);
2196
			HANDLE_UNBLOCK_INTERRUPTIONS();
2197
		}
2198
		ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
2199
#if SUHOSIN_PATCH
2200
                SUHOSIN_MM_SET_CANARIES(mm_block);
2201
                ((zend_mm_block_canary*)mm_block)->info.size = size;
2202
                SUHOSIN_MM_SET_END_CANARY(mm_block);
2203
#endif
2204
		return p;
2205
	}
2206
2207
#if ZEND_MM_CACHE
2208
	if (ZEND_MM_SMALL_SIZE(true_size)) {
2209
		size_t index = ZEND_MM_BUCKET_INDEX(true_size);
2210
		
2211
		if (heap->cache[index] != NULL) {
2212
			zend_mm_free_block_canary *best_fit;
2213
			zend_mm_free_block_canary **cache;
2214
2215
#if ZEND_MM_CACHE_STAT
2216
			heap->cache_stat[index].count--;
2217
			heap->cache_stat[index].hit++;
2218
#endif
2219
			best_fit = SUHOSIN_MANGLE_PTR(heap->cache[index]);
2220
			heap->cache[index] = best_fit->prev_free_block;
2221
			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
2222
			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);                        	
2223
#if SUHOSIN_PATCH
2224
                        SUHOSIN_MM_SET_CANARIES(best_fit);
2225
                        ((zend_mm_block_canary*)best_fit)->info.size = size;
2226
                        SUHOSIN_MM_SET_END_CANARY(best_fit);
2227
#endif
2228
2229
			ptr = ZEND_MM_DATA_OF(best_fit);
2230
2231
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2232
			memcpy(ptr, p, mm_block->debug.size);
2233
#else
2234
			memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
2235
#endif
2236
2237
			heap->cached -= true_size - orig_size;
2238
2239
			index = ZEND_MM_BUCKET_INDEX(orig_size);
2240
			cache = &heap->cache[index];
2241
2242
			((zend_mm_free_block_canary*)mm_block)->prev_free_block = *cache;
2243
			*cache = (zend_mm_free_block_canary*)SUHOSIN_MANGLE_PTR(mm_block);
2244
			ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_CACHED);
2245
#if ZEND_MM_CACHE_STAT
2246
			if (++heap->cache_stat[index].count > heap->cache_stat[index].max_count) {
2247
				heap->cache_stat[index].max_count = heap->cache_stat[index].count;
2248
			}
2249
#endif
2250
			return ptr;
2251
		}
2252
	}
2253
#endif
2254
2255
	next_block = ZEND_MM_BLOCK_AT(mm_block, orig_size);
2256
2257
	if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
2258
		ZEND_MM_CHECK_COOKIE(next_block);
2259
		ZEND_MM_CHECK_BLOCK_LINKAGE(next_block);
2260
		if (orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block) >= true_size) {
2261
			size_t block_size = orig_size + ZEND_MM_FREE_BLOCK_SIZE(next_block);
2262
			size_t remaining_size = block_size - true_size;
2263
2264
			HANDLE_BLOCK_INTERRUPTIONS();
2265
			zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
2266
2267
			if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
2268
				true_size = block_size;
2269
				ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
2270
			} else {
2271
				zend_mm_free_block_canary *new_free_block;
2272
2273
				/* prepare new free block */
2274
				ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
2275
				new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
2276
				ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
2277
2278
				/* add the new free block to the free list */
2279
				if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2280
				    ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(new_free_block, remaining_size))) {
2281
					zend_mm_add_to_rest_list(heap, new_free_block);
2282
				} else {
2283
					zend_mm_add_to_free_list(heap, new_free_block);
2284
				}
2285
			}
2286
			ZEND_MM_SET_DEBUG_INFO(mm_block, size, 0, 0);
2287
			heap->size = heap->size + true_size - orig_size;
2288
			if (heap->peak < heap->size) {
2289
				heap->peak = heap->size;
2290
			}
2291
			HANDLE_UNBLOCK_INTERRUPTIONS();
2292
#if SUHOSIN_PATCH
2293
                        SUHOSIN_MM_SET_CANARIES(mm_block);
2294
                        ((zend_mm_block_canary*)mm_block)->info.size = size;
2295
                        SUHOSIN_MM_SET_END_CANARY(mm_block);
2296
#endif
2297
			return p;
2298
		} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) &&
2299
				   ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_BLOCK_AT(next_block, ZEND_MM_FREE_BLOCK_SIZE(next_block)))) {
2300
			HANDLE_BLOCK_INTERRUPTIONS();
2301
			zend_mm_remove_from_free_list(heap, (zend_mm_free_block_canary *) next_block);
2302
			goto realloc_segment;
2303
		}
2304
	} else if (ZEND_MM_IS_FIRST_BLOCK(mm_block) && ZEND_MM_IS_GUARD_BLOCK(next_block)) {
2305
		zend_mm_segment *segment;
2306
		zend_mm_segment *segment_copy;
2307
		size_t segment_size;
2308
		size_t block_size;
2309
		size_t remaining_size;
2310
2311
		HANDLE_BLOCK_INTERRUPTIONS();
2312
realloc_segment:
2313
		/* segment size, size of block and size of guard block */
2314
		if (true_size > heap->block_size - (ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE)) {
2315
			segment_size = true_size+ZEND_MM_ALIGNED_SEGMENT_SIZE+ZEND_MM_ALIGNED_HEADER_SIZE;
2316
			segment_size = (segment_size + (heap->block_size-1)) & ~(heap->block_size-1);
2317
		} else {
2318
			segment_size = heap->block_size;
2319
		}
2320
2321
		segment_copy = (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE);
2322
		if (segment_size < true_size ||
2323
		    heap->real_size + segment_size - segment_copy->size > heap->limit) {
2324
			if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
2325
				zend_mm_add_to_free_list(heap, (zend_mm_free_block_canary *) next_block);
2326
			}
2327
#if ZEND_MM_CACHE
2328
			zend_mm_free_cache(heap);
2329
#endif
2330
			HANDLE_UNBLOCK_INTERRUPTIONS();
2331
#if ZEND_DEBUG
2332
			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);
2333
#else
2334
			zend_mm_safe_error(heap, "Allowed memory size of %ld bytes exhausted (tried to allocate %ld bytes)", heap->limit, size);
2335
#endif
2336
			return NULL;
2337
		}
2338
2339
		segment = ZEND_MM_STORAGE_REALLOC(segment_copy, segment_size);
2340
		if (!segment) {
2341
#if ZEND_MM_CACHE
2342
			zend_mm_free_cache(heap);
2343
#endif
2344
			HANDLE_UNBLOCK_INTERRUPTIONS();
2345
out_of_memory:
2346
#if ZEND_DEBUG
2347
			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);
2348
#else
2349
			zend_mm_safe_error(heap, "Out of memory (allocated %ld) (tried to allocate %ld bytes)", heap->real_size, size);
2350
#endif
2351
			return NULL;
2352
		}
2353
		heap->real_size += segment_size - segment->size;
2354
		if (heap->real_size > heap->real_peak) {
2355
			heap->real_peak = heap->real_size;
2356
		}
2357
2358
		segment->size = segment_size;
2359
2360
		if (segment != segment_copy) {
2361
			zend_mm_segment **seg = &heap->segments_list;
2362
			while (*seg != segment_copy) {
2363
				seg = &(*seg)->next_segment;
2364
			}
2365
			*seg = segment;
2366
			mm_block = (zend_mm_block_canary *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
2367
			ZEND_MM_MARK_FIRST_BLOCK(mm_block);
2368
		}
2369
2370
		block_size = segment_size - ZEND_MM_ALIGNED_SEGMENT_SIZE - ZEND_MM_ALIGNED_HEADER_SIZE;
2371
		remaining_size = block_size - true_size;
2372
2373
		/* setup guard block */
2374
		ZEND_MM_LAST_BLOCK(ZEND_MM_BLOCK_AT(mm_block, block_size));
2375
2376
		if (remaining_size < ZEND_MM_ALIGNED_MIN_HEADER_SIZE) {
2377
			true_size = block_size;
2378
			ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
2379
		} else {
2380
			zend_mm_free_block_canary *new_free_block;
2381
2382
			/* prepare new free block */
2383
			ZEND_MM_BLOCK(mm_block, ZEND_MM_USED_BLOCK, true_size);
2384
			new_free_block = (zend_mm_free_block_canary *) ZEND_MM_BLOCK_AT(mm_block, true_size);
2385
			ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size);
2386
2387
			/* add the new free block to the free list */
2388
			zend_mm_add_to_rest_list(heap, new_free_block);
2389
		}
2390
2391
		ZEND_MM_SET_DEBUG_INFO(mm_block, size, 1, 1);
2392
2393
		heap->size = heap->size + true_size - orig_size;
2394
		if (heap->peak < heap->size) {
2395
			heap->peak = heap->size;
2396
		}
2397
2398
		HANDLE_UNBLOCK_INTERRUPTIONS();
2399
#if SUHOSIN_PATCH
2400
                SUHOSIN_MM_SET_CANARIES(mm_block);
2401
                ((zend_mm_block_canary*)mm_block)->info.size = size;
2402
                SUHOSIN_MM_SET_END_CANARY(mm_block);
2403
#endif
2404
		return ZEND_MM_DATA_OF(mm_block);
2405
	}
2406
2407
	ptr = _zend_mm_alloc_canary_int(heap, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2408
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2409
	memcpy(ptr, p, mm_block->debug.size);
2410
#else
2411
	memcpy(ptr, p, orig_size - ZEND_MM_ALIGNED_HEADER_SIZE - CANARY_SIZE);
2412
#endif
2413
	_zend_mm_free_canary_int(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2414
	return ptr;
2415
}
2416
2417
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)
2418
{
2419
	zend_mm_block_canary *mm_block;
2420
2421
	if (!ZEND_MM_VALID_PTR(p)) {
2422
		return 0;
2423
	}
2424
	mm_block = ZEND_MM_HEADER_OF(p);
2425
	ZEND_MM_CHECK_PROTECTION(mm_block);
2426
#if ZEND_DEBUG || ZEND_MM_HEAP_PROTECTION
2427
	return mm_block->debug.size;
2428
#else
2429
	return ZEND_MM_BLOCK_SIZE(mm_block);
2430
#endif
2431
}
2432
2433
#if defined(__GNUC__) && defined(i386)
2434
2435
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
2436
{
2437
	size_t res = nmemb;
2438
	unsigned long overflow = 0;
2439
2440
	__asm__ ("mull %3\n\taddl %4,%0\n\tadcl %1,%1"
2441
	     : "=&a"(res), "=&d" (overflow)
2442
	     : "%0"(res),
2443
	       "rm"(size),
2444
	       "rm"(offset));
2445
	
2446
	if (UNEXPECTED(overflow)) {
2447
		zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
2448
		return 0;
2449
	}
2450
	return res;
2451
}
2452
2453
#elif defined(__GNUC__) && defined(__x86_64__)
2454
2455
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
2456
{
2457
        size_t res = nmemb;
2458
        unsigned long overflow = 0;
2459
2460
        __asm__ ("mulq %3\n\taddq %4,%0\n\tadcq %1,%1"
2461
             : "=&a"(res), "=&d" (overflow)
2462
             : "%0"(res),
2463
               "rm"(size),
2464
               "rm"(offset));
2465
2466
        if (UNEXPECTED(overflow)) {
2467
                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
2468
                return 0;
2469
        }
2470
        return res;
2471
}
2472
2473
#elif SIZEOF_SIZE_T == 4 && defined(HAVE_ZEND_LONG64)
2474
2475
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
2476
{
2477
	zend_ulong64 res = (zend_ulong64)nmemb * (zend_ulong64)size + (zend_ulong64)offset;
2478
2479
	if (UNEXPECTED(res > (zend_ulong64)0xFFFFFFFFL)) {
2480
		zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
2481
		return 0;
2482
	}
2483
	return (size_t) res;
2484
}
2485
2486
#else
2487
2488
static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
2489
{
2490
	size_t res = nmemb * size + offset;
2491
	double _d  = (double)nmemb * (double)size + (double)offset;
2492
	double _delta = (double)res - _d;
2493
2494
	if (UNEXPECTED((_d + _delta ) != _d)) {
2495
		zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
2496
		return 0;
2497
	}
2498
	return res;
2499
}
2500
#endif
2501
2502
/*
2503
 * Local variables:
2504
 * tab-width: 4
2505
 * c-basic-offset: 4
2506
 * indent-tabs-mode: t
2507
 * End:
2508
 */
2509
(-)php-5.3.9/Zend/zend_canary.c (+66 lines)
Line 0 Link Here
1
/*
2
   +----------------------------------------------------------------------+
3
   | Suhosin-Patch for PHP                                                |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 2004-2009 Stefan Esser                                 |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.02 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available at through the world-wide-web at                           |
10
   | http://www.php.net/license/2_02.txt.                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Stefan Esser <stefan.esser@sektioneins.de>                   |
16
   +----------------------------------------------------------------------+
17
 */
18
/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
19
20
#include "zend.h"
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
25
26
#if SUHOSIN_PATCH
27
28
static size_t last_canary = 0x73625123;
29
30
/* will be replaced later with more compatible method */
31
ZEND_API void zend_canary(void *buf, int len)
32
{
33
	time_t t;
34
	size_t canary;
35
	int fd;
36
	
37
#ifndef PHP_WIN32
38
	fd = open("/dev/urandom", 0);
39
	if (fd != -1) {
40
		int r = read(fd, buf, len);
41
		close(fd);
42
		if (r == len) {
43
			return;
44
		}
45
	}
46
#endif	
47
	/* not good but we never want to do this */
48
	time(&t);
49
	canary = *(unsigned int *)&t + getpid() << 16 + last_canary;
50
	last_canary ^= (canary << 5) | (canary >> (32-5));
51
	/* When we ensure full win32 compatibility in next version
52
	   we will replace this with the random number code from zend_alloc.c */
53
        memcpy(buf, &canary, len);
54
}
55
56
#endif
57
58
59
/*
60
 * Local variables:
61
 * tab-width: 4
62
 * c-basic-offset: 4
63
 * End:
64
 * vim600: sw=4 ts=4 fdm=marker
65
 * vim<600: sw=4 ts=4
66
 */
(-)php-5.3.9/Zend/zend_compile.c (+5 lines)
Lines 73-78 Link Here
73
}
73
}
74
/* }}} */
74
/* }}} */
75
75
76
#if SUHOSIN_PATCH
77
void *suhosin_zend_destroy_property_info_internal = zend_destroy_property_info_internal;
78
void *suhosin_zend_destroy_property_info = zend_destroy_property_info;
79
#endif
80
76
static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */
81
static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */
77
{
82
{
78
	char char_pos_buf[32];
83
	char char_pos_buf[32];
(-)php-5.3.9/Zend/zend_compile.h (+5 lines)
Lines 607-612 Link Here
607
ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC);
607
ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC);
608
ZEND_API size_t zend_dirname(char *path, size_t len);
608
ZEND_API size_t zend_dirname(char *path, size_t len);
609
609
610
#if SUHOSIN_PATCH
611
extern void *suhosin_zend_destroy_property_info_internal;
612
extern void *suhosin_zend_destroy_property_info;
613
#endif
614
610
int zendlex(znode *zendlval TSRMLS_DC);
615
int zendlex(znode *zendlval TSRMLS_DC);
611
616
612
/* BEGIN: OPCODES */
617
/* BEGIN: OPCODES */
(-)php-5.3.9/Zend/zend_constants.c (+70 lines)
Lines 113-118 Link Here
113
113
114
	REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
114
	REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
115
115
116
#if SUHOSIN_PATCH
117
	REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
118
	REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
119
	REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
120
	REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
121
	REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
122
	REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
123
	REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
124
	REGISTER_MAIN_LONG_CONSTANT("S_SESSION", S_SESSION, CONST_PERSISTENT | CONST_CS);
125
	REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
126
	REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
127
	REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
128
129
	/* error levels */
130
	REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
131
	REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
132
	REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
133
	REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); 
134
	REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
135
	REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
136
	REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
137
	REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
138
	/* facility: type of program logging the message */
139
	REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
140
	REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
141
	REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
142
	REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
143
	REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
144
	REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
145
	REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
146
#ifdef LOG_NEWS
147
	/* No LOG_NEWS on HP-UX */
148
	REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
149
#endif
150
#ifdef LOG_UUCP
151
	/* No LOG_UUCP on HP-UX */
152
	REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
153
#endif
154
#ifdef LOG_CRON
155
	/* apparently some systems don't have this one */
156
	REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
157
#endif
158
#ifdef LOG_AUTHPRIV
159
	/* AIX doesn't have LOG_AUTHPRIV */
160
	REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
161
#endif
162
#ifndef PHP_WIN32
163
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
164
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
165
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
166
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
167
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
168
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
169
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
170
	REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
171
#endif
172
	/* options */
173
	REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
174
	REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
175
	REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
176
	REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
177
#ifdef LOG_NOWAIT
178
	REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
179
#endif
180
#ifdef LOG_PERROR
181
	/* AIX doesn't have LOG_PERROR */
182
	REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
183
#endif
184
#endif
185
116
	REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
186
	REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
117
	REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
187
	REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
118
	/* true/false constants */
188
	/* true/false constants */
(-)php-5.3.9/Zend/zend_errors.h (+14 lines)
Lines 41-46 Link Here
41
#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)
41
#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)
42
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
42
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
43
43
44
#if SUHOSIN_PATCH
45
#define S_MEMORY			(1<<0L)
46
#define S_MISC				(1<<1L)
47
#define S_VARS				(1<<2L)
48
#define S_FILES				(1<<3L)
49
#define S_INCLUDE			(1<<4L)
50
#define S_SQL				(1<<5L)
51
#define S_EXECUTOR			(1<<6L)
52
#define S_MAIL				(1<<7L)
53
#define S_SESSION			(1<<8L)
54
#define S_INTERNAL			(1<<29L)
55
#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_SESSION | S_MISC | S_SQL | S_EXECUTOR)
56
#endif
57
44
#endif /* ZEND_ERRORS_H */
58
#endif /* ZEND_ERRORS_H */
45
59
46
/*
60
/*
(-)php-5.3.9/Zend/zend_hash.c (+204 lines)
Lines 20-25 Link Here
20
/* $Id$ */
20
/* $Id$ */
21
21
22
#include "zend.h"
22
#include "zend.h"
23
#include "zend_compile.h"
23
24
24
#define CONNECT_TO_BUCKET_DLLIST(element, list_head)		\
25
#define CONNECT_TO_BUCKET_DLLIST(element, list_head)		\
25
	(element)->pNext = (list_head);							\
26
	(element)->pNext = (list_head);							\
Lines 136-141 Link Here
136
	}
137
	}
137
138
138
139
140
#if SUHOSIN_PATCH
141
#ifdef ZTS
142
static MUTEX_T zend_hash_dprot_mx_reader;
143
static MUTEX_T zend_hash_dprot_mx_writer;
144
static unsigned int zend_hash_dprot_reader;
145
#endif
146
static unsigned int zend_hash_dprot_counter;
147
static unsigned int zend_hash_dprot_curmax;
148
static dtor_func_t *zend_hash_dprot_table = NULL;
149
150
static void zend_hash_dprot_begin_read()
151
{
152
#ifdef ZTS
153
	tsrm_mutex_lock(zend_hash_dprot_mx_reader);
154
	if ((++(zend_hash_dprot_reader)) == 1) {
155
		tsrm_mutex_lock(zend_hash_dprot_mx_writer);
156
	}
157
	tsrm_mutex_unlock(zend_hash_dprot_mx_reader);
158
#endif
159
}
160
161
static void zend_hash_dprot_end_read()
162
{
163
#ifdef ZTS
164
	tsrm_mutex_lock(zend_hash_dprot_mx_reader);
165
	if ((--(zend_hash_dprot_reader)) == 0) {
166
		tsrm_mutex_unlock(zend_hash_dprot_mx_writer);
167
	}
168
	tsrm_mutex_unlock(zend_hash_dprot_mx_reader);
169
#endif
170
}
171
172
static void zend_hash_dprot_begin_write()
173
{
174
#ifdef ZTS
175
	tsrm_mutex_lock(zend_hash_dprot_mx_writer);
176
#endif
177
}
178
179
static void zend_hash_dprot_end_write()
180
{
181
#ifdef ZTS
182
	tsrm_mutex_unlock(zend_hash_dprot_mx_writer);
183
#endif
184
}
185
186
/*ZEND_API void zend_hash_dprot_dtor()
187
{
188
#ifdef ZTS
189
	tsrm_mutex_free(zend_hash_dprot_mx_reader);
190
	tsrm_mutex_free(zend_hash_dprot_mx_writer);
191
#endif	
192
	free(zend_hash_dprot_table);
193
}*/
194
195
static void zend_hash_add_destructor(dtor_func_t pDestructor)
196
{
197
	int left, right, mid;
198
	zend_bool found = 0;
199
	unsigned long value;
200
	
201
	if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR || pDestructor == ZVAL_INTERNAL_PTR_DTOR
202
	    || pDestructor == ZEND_FUNCTION_DTOR || pDestructor == ZEND_CLASS_DTOR) {
203
		return;
204
	}
205
	
206
	if (zend_hash_dprot_table == NULL) {
207
#ifdef ZTS
208
		zend_hash_dprot_mx_reader = tsrm_mutex_alloc();
209
		zend_hash_dprot_mx_writer = tsrm_mutex_alloc();
210
		zend_hash_dprot_reader = 0;
211
#endif	
212
		zend_hash_dprot_counter = 0;
213
		zend_hash_dprot_curmax = 256;
214
		zend_hash_dprot_table = (dtor_func_t *) malloc(256 * sizeof(dtor_func_t));
215
	}
216
	
217
	zend_hash_dprot_begin_write();
218
219
	if (zend_hash_dprot_counter == 0) {
220
		zend_hash_dprot_counter++;
221
		zend_hash_dprot_table[0] = pDestructor;
222
	} else {
223
		value = (unsigned long) pDestructor;
224
		left = 0;
225
		right = zend_hash_dprot_counter-1;
226
		mid = 0;
227
		
228
		while (left < right) {
229
			mid = (right - left) >> 1;
230
			mid += left;
231
			if ((unsigned long)zend_hash_dprot_table[mid] == value) {
232
				found = 1;
233
				break;
234
			}
235
			if (value < (unsigned long)zend_hash_dprot_table[mid]) {
236
				right = mid-1;
237
			} else {
238
				left = mid+1;
239
			}
240
		}
241
		if ((unsigned long)zend_hash_dprot_table[left] == value) {
242
			found = 1;
243
		}
244
		
245
		if (!found) {
246
		
247
			if (zend_hash_dprot_counter >= zend_hash_dprot_curmax) {
248
				zend_hash_dprot_curmax += 256;
249
				zend_hash_dprot_table = (dtor_func_t *) realloc(zend_hash_dprot_table, zend_hash_dprot_curmax * sizeof(dtor_func_t));
250
			}
251
			
252
			if ((unsigned long)zend_hash_dprot_table[left] < value) {
253
				memmove(zend_hash_dprot_table+left+2, zend_hash_dprot_table+left+1, (zend_hash_dprot_counter-left-1)*sizeof(dtor_func_t));
254
				zend_hash_dprot_table[left+1] = pDestructor;
255
			} else {
256
				memmove(zend_hash_dprot_table+left+1, zend_hash_dprot_table+left, (zend_hash_dprot_counter-left)*sizeof(dtor_func_t));
257
				zend_hash_dprot_table[left] = pDestructor;
258
			}
259
260
			zend_hash_dprot_counter++;
261
		}
262
	}
263
	
264
	zend_hash_dprot_end_write();
265
}
266
267
static void zend_hash_check_destructor(dtor_func_t pDestructor)
268
{
269
	unsigned long value;
270
	
271
	if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR || pDestructor == ZVAL_INTERNAL_PTR_DTOR
272
#ifdef ZEND_ENGINE_2
273
		|| pDestructor == suhosin_zend_destroy_property_info_internal || pDestructor == suhosin_zend_destroy_property_info
274
#endif
275
	    || pDestructor == ZEND_FUNCTION_DTOR || pDestructor == ZEND_CLASS_DTOR) {
276
		return;
277
	}
278
279
	zend_hash_dprot_begin_read();
280
	
281
	if (zend_hash_dprot_counter > 0) {
282
		int left, right, mid;
283
		zend_bool found = 0;
284
	
285
		value = (unsigned long) pDestructor;
286
		left = 0;
287
		right = zend_hash_dprot_counter-1;
288
		
289
		while (left < right) {
290
			mid = (right - left) >> 1;
291
			mid += left;
292
			if ((unsigned long)zend_hash_dprot_table[mid] == value) {
293
				found = 1;
294
				break;
295
			}
296
			if (value < (unsigned long)zend_hash_dprot_table[mid]) {
297
				right = mid-1;
298
			} else {
299
				left = mid+1;
300
			}
301
		}
302
		if ((unsigned long)zend_hash_dprot_table[left] == value) {
303
			found = 1;
304
		}
305
		
306
		if (!found) {
307
			zend_hash_dprot_end_read();
308
		
309
			zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown Hashtable destructor");
310
			if (SUHOSIN_CONFIG(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR) == 0) {
311
			        _exit(1);
312
		        }
313
			return;
314
		}
315
	
316
	} else {
317
		zend_hash_dprot_end_read();
318
	
319
		zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown Hashtable destructor");
320
		if (SUHOSIN_CONFIG(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR) == 0) {
321
		        _exit(1);
322
	        }
323
		return;	        
324
	}
325
	
326
	zend_hash_dprot_end_read();
327
}
328
329
#else
330
#define zend_hash_add_destructor(pDestructor) do {} while(0)
331
#define zend_hash_check_destructor(pDestructor) do {} while(0)
332
#endif
139
333
140
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)
334
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)
141
{
335
{
Lines 156-161 Link Here
156
350
157
	ht->nTableMask = ht->nTableSize - 1;
351
	ht->nTableMask = ht->nTableSize - 1;
158
	ht->pDestructor = pDestructor;
352
	ht->pDestructor = pDestructor;
353
	zend_hash_add_destructor(pDestructor);
159
	ht->arBuckets = NULL;
354
	ht->arBuckets = NULL;
160
	ht->pListHead = NULL;
355
	ht->pListHead = NULL;
161
	ht->pListTail = NULL;
356
	ht->pListTail = NULL;
Lines 233-238 Link Here
233
					return FAILURE;
428
					return FAILURE;
234
				}
429
				}
235
#endif
430
#endif
431
				zend_hash_check_destructor(ht->pDestructor);
236
				if (ht->pDestructor) {
432
				if (ht->pDestructor) {
237
					ht->pDestructor(p->pData);
433
					ht->pDestructor(p->pData);
238
				}
434
				}
Lines 298-303 Link Here
298
					return FAILURE;
494
					return FAILURE;
299
				}
495
				}
300
#endif
496
#endif
497
				zend_hash_check_destructor(ht->pDestructor);
301
				if (ht->pDestructor) {
498
				if (ht->pDestructor) {
302
					ht->pDestructor(p->pData);
499
					ht->pDestructor(p->pData);
303
				}
500
				}
Lines 373-378 Link Here
373
				return FAILURE;
570
				return FAILURE;
374
			}
571
			}
375
#endif
572
#endif
573
			zend_hash_check_destructor(ht->pDestructor);
376
			if (ht->pDestructor) {
574
			if (ht->pDestructor) {
377
				ht->pDestructor(p->pData);
575
				ht->pDestructor(p->pData);
378
			}
576
			}
Lines 496-501 Link Here
496
			if (ht->pInternalPointer == p) {
694
			if (ht->pInternalPointer == p) {
497
				ht->pInternalPointer = p->pListNext;
695
				ht->pInternalPointer = p->pListNext;
498
			}
696
			}
697
			zend_hash_check_destructor(ht->pDestructor);
499
			if (ht->pDestructor) {
698
			if (ht->pDestructor) {
500
				ht->pDestructor(p->pData);
699
				ht->pDestructor(p->pData);
501
			}
700
			}
Lines 522-527 Link Here
522
	SET_INCONSISTENT(HT_IS_DESTROYING);
721
	SET_INCONSISTENT(HT_IS_DESTROYING);
523
722
524
	p = ht->pListHead;
723
	p = ht->pListHead;
724
	zend_hash_check_destructor(ht->pDestructor);
525
	while (p != NULL) {
725
	while (p != NULL) {
526
		q = p;
726
		q = p;
527
		p = p->pListNext;
727
		p = p->pListNext;
Lines 554-559 Link Here
554
	ht->nNextFreeElement = 0;
754
	ht->nNextFreeElement = 0;
555
	ht->pInternalPointer = NULL;
755
	ht->pInternalPointer = NULL;
556
756
757
	zend_hash_check_destructor(ht->pDestructor);
557
	while (p != NULL) {
758
	while (p != NULL) {
558
		q = p;
759
		q = p;
559
		p = p->pListNext;
760
		p = p->pListNext;
Lines 608-613 Link Here
608
	ht->nNumOfElements--;
809
	ht->nNumOfElements--;
609
	HANDLE_UNBLOCK_INTERRUPTIONS();
810
	HANDLE_UNBLOCK_INTERRUPTIONS();
610
811
812
	zend_hash_check_destructor(ht->pDestructor);
611
	if (ht->pDestructor) {
813
	if (ht->pDestructor) {
612
		ht->pDestructor(p->pData);
814
		ht->pDestructor(p->pData);
613
	}
815
	}
Lines 628-633 Link Here
628
	IS_CONSISTENT(ht);
830
	IS_CONSISTENT(ht);
629
831
630
	p = ht->pListHead;
832
	p = ht->pListHead;
833
	zend_hash_check_destructor(ht->pDestructor);
631
	while (p != NULL) {
834
	while (p != NULL) {
632
		p = zend_hash_apply_deleter(ht, p);
835
		p = zend_hash_apply_deleter(ht, p);
633
	}
836
	}
Lines 1180-1185 Link Here
1180
1383
1181
	IS_CONSISTENT(ht);
1384
	IS_CONSISTENT(ht);
1182
1385
1386
	zend_hash_check_destructor(ht->pDestructor);
1183
	if (p) {
1387
	if (p) {
1184
		if (key_type == HASH_KEY_IS_LONG) {
1388
		if (key_type == HASH_KEY_IS_LONG) {
1185
			str_length = 0;
1389
			str_length = 0;
(-)php-5.3.9/Zend/zend_llist.c (+192 lines)
Lines 23-28 Link Here
23
#include "zend_llist.h"
23
#include "zend_llist.h"
24
#include "zend_qsort.h"
24
#include "zend_qsort.h"
25
25
26
#if SUHOSIN_PATCH
27
#ifdef ZTS
28
static MUTEX_T zend_llist_dprot_mx_reader;
29
static MUTEX_T zend_llist_dprot_mx_writer;
30
static unsigned int zend_llist_dprot_reader;
31
#endif
32
static unsigned int zend_llist_dprot_counter;
33
static unsigned int zend_llist_dprot_curmax;
34
static llist_dtor_func_t *zend_llist_dprot_table = NULL;
35
36
static void zend_llist_dprot_begin_read()
37
{
38
#ifdef ZTS
39
	tsrm_mutex_lock(zend_llist_dprot_mx_reader);
40
	if ((++(zend_llist_dprot_reader)) == 1) {
41
		tsrm_mutex_lock(zend_llist_dprot_mx_writer);
42
	}
43
	tsrm_mutex_unlock(zend_llist_dprot_mx_reader);
44
#endif
45
}
46
47
static void zend_llist_dprot_end_read()
48
{
49
#ifdef ZTS
50
	tsrm_mutex_lock(zend_llist_dprot_mx_reader);
51
	if ((--(zend_llist_dprot_reader)) == 0) {
52
		tsrm_mutex_unlock(zend_llist_dprot_mx_writer);
53
	}
54
	tsrm_mutex_unlock(zend_llist_dprot_mx_reader);
55
#endif
56
}
57
58
static void zend_llist_dprot_begin_write()
59
{
60
#ifdef ZTS
61
	tsrm_mutex_lock(zend_llist_dprot_mx_writer);
62
#endif
63
}
64
65
static void zend_llist_dprot_end_write()
66
{
67
#ifdef ZTS
68
	tsrm_mutex_unlock(zend_llist_dprot_mx_writer);
69
#endif
70
}
71
72
/*ZEND_API void zend_llist_dprot_dtor()
73
{
74
#ifdef ZTS
75
	tsrm_mutex_free(zend_llist_dprot_mx_reader);
76
	tsrm_mutex_free(zend_llist_dprot_mx_writer);
77
#endif	
78
	free(zend_llist_dprot_table);
79
}*/
80
81
static void zend_llist_add_destructor(llist_dtor_func_t pDestructor)
82
{
83
	int left, right, mid;
84
	zend_bool found = 0;
85
	unsigned long value;
86
	
87
	if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR) {
88
		return;
89
	}
90
	
91
	if (zend_llist_dprot_table == NULL) {
92
#ifdef ZTS
93
		zend_llist_dprot_mx_reader = tsrm_mutex_alloc();
94
		zend_llist_dprot_mx_writer = tsrm_mutex_alloc();
95
		zend_llist_dprot_reader = 0;
96
#endif	
97
		zend_llist_dprot_counter = 0;
98
		zend_llist_dprot_curmax = 256;
99
		zend_llist_dprot_table = (llist_dtor_func_t *) malloc(256 * sizeof(llist_dtor_func_t));
100
	}
101
	
102
	zend_llist_dprot_begin_write();
103
104
	if (zend_llist_dprot_counter == 0) {
105
		zend_llist_dprot_counter++;
106
		zend_llist_dprot_table[0] = pDestructor;
107
	} else {
108
		value = (unsigned long) pDestructor;
109
		left = 0;
110
		right = zend_llist_dprot_counter-1;
111
		mid = 0;
112
		
113
		while (left < right) {
114
			mid = (right - left) >> 1;
115
			mid += left;
116
			if ((unsigned long)zend_llist_dprot_table[mid] == value) {
117
				found = 1;
118
				break;
119
			}
120
			if (value < (unsigned long)zend_llist_dprot_table[mid]) {
121
				right = mid-1;
122
			} else {
123
				left = mid+1;
124
			}
125
		}
126
		if ((unsigned long)zend_llist_dprot_table[left] == value) {
127
			found = 1;
128
		}
129
		
130
		if (!found) {
131
		
132
			if (zend_llist_dprot_counter >= zend_llist_dprot_curmax) {
133
				zend_llist_dprot_curmax += 256;
134
				zend_llist_dprot_table = (llist_dtor_func_t *) realloc(zend_llist_dprot_table, zend_llist_dprot_curmax * sizeof(llist_dtor_func_t));
135
			}
136
			
137
			if ((unsigned long)zend_llist_dprot_table[left] < value) {
138
				memmove(zend_llist_dprot_table+left+2, zend_llist_dprot_table+left+1, (zend_llist_dprot_counter-left-1)*sizeof(llist_dtor_func_t));
139
				zend_llist_dprot_table[left+1] = pDestructor;
140
			} else {
141
				memmove(zend_llist_dprot_table+left+1, zend_llist_dprot_table+left, (zend_llist_dprot_counter-left)*sizeof(llist_dtor_func_t));
142
				zend_llist_dprot_table[left] = pDestructor;
143
			}
144
145
			zend_llist_dprot_counter++;
146
		}
147
	}
148
	
149
	zend_llist_dprot_end_write();
150
}
151
152
static void zend_llist_check_destructor(llist_dtor_func_t pDestructor)
153
{
154
	unsigned long value;
155
	
156
	if (pDestructor == NULL || pDestructor == ZVAL_PTR_DTOR) {
157
		return;
158
	}
159
160
	zend_llist_dprot_begin_read();
161
	
162
	if (zend_llist_dprot_counter > 0) {
163
		int left, right, mid;
164
		zend_bool found = 0;
165
	
166
		value = (unsigned long) pDestructor;
167
		left = 0;
168
		right = zend_llist_dprot_counter-1;
169
		
170
		while (left < right) {
171
			mid = (right - left) >> 1;
172
			mid += left;
173
			if ((unsigned long)zend_llist_dprot_table[mid] == value) {
174
				found = 1;
175
				break;
176
			}
177
			if (value < (unsigned long)zend_llist_dprot_table[mid]) {
178
				right = mid-1;
179
			} else {
180
				left = mid+1;
181
			}
182
		}
183
		if ((unsigned long)zend_llist_dprot_table[left] == value) {
184
			found = 1;
185
		}
186
		
187
		if (!found) {
188
			zend_llist_dprot_end_read();
189
		
190
		        zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown llist destructor");
191
			if (SUHOSIN_CONFIG(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR) == 0) {
192
			        _exit(1);
193
		        }
194
			return;
195
		}
196
	
197
	} else {
198
		zend_llist_dprot_end_read();
199
	
200
	        zend_suhosin_log(S_MEMORY, "possible memory corruption detected - unknown llist destructor");
201
		if (SUHOSIN_CONFIG(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR) == 0) {
202
		        _exit(1);
203
	        }
204
		return;	        
205
	}
206
	
207
	zend_llist_dprot_end_read();
208
}
209
#else
210
#define zend_llist_add_destructor(pDestructor) do {} while(0)
211
#define zend_llist_check_destructor(pDestructor) do {} while(0)
212
#endif
213
26
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
214
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
27
{
215
{
28
	l->head  = NULL;
216
	l->head  = NULL;
Lines 30-35 Link Here
30
	l->count = 0;
218
	l->count = 0;
31
	l->size  = size;
219
	l->size  = size;
32
	l->dtor  = dtor;
220
	l->dtor  = dtor;
221
	zend_llist_add_destructor(dtor);
33
	l->persistent = persistent;
222
	l->persistent = persistent;
34
}
223
}
35
224
Lines 81-86 Link Here
81
			} else {\
270
			} else {\
82
				(l)->tail = (current)->prev;\
271
				(l)->tail = (current)->prev;\
83
			}\
272
			}\
273
			zend_llist_check_destructor((l)->dtor); \
84
			if ((l)->dtor) {\
274
			if ((l)->dtor) {\
85
				(l)->dtor((current)->data);\
275
				(l)->dtor((current)->data);\
86
			}\
276
			}\
Lines 108-113 Link Here
108
{
298
{
109
	zend_llist_element *current=l->head, *next;
299
	zend_llist_element *current=l->head, *next;
110
	
300
	
301
	zend_llist_check_destructor(l->dtor);
111
	while (current) {
302
	while (current) {
112
		next = current->next;
303
		next = current->next;
113
		if (l->dtor) {
304
		if (l->dtor) {
Lines 133-138 Link Here
133
	zend_llist_element *old_tail;
324
	zend_llist_element *old_tail;
134
	void *data;
325
	void *data;
135
326
327
	zend_llist_check_destructor((l)->dtor);
136
	if ((old_tail = l->tail)) {
328
	if ((old_tail = l->tail)) {
137
		if (old_tail->prev) {
329
		if (old_tail->prev) {
138
			old_tail->prev->next = NULL;
330
			old_tail->prev->next = NULL;
(-)php-5.3.9/Zend/zend_operators.c (-2 / +25 lines)
Lines 153-161 Link Here
153
		case IS_STRING:
153
		case IS_STRING:
154
			{
154
			{
155
				char *strval;
155
				char *strval;
156
                                int strl;
156
157
157
				strval = Z_STRVAL_P(op);
158
				strval = Z_STRVAL_P(op);
158
				if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
159
                                strl   = Z_STRLEN_P(op);
160
#if SUHOSIN_PATCH
161
                                Z_STRLEN_P(op) = 0;
162
#endif
163
				if ((Z_TYPE_P(op)=is_numeric_string(strval, strl, &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
159
					ZVAL_LONG(op, 0);
164
					ZVAL_LONG(op, 0);
160
				}
165
				}
161
				STR_FREE(strval);
166
				STR_FREE(strval);
Lines 187-193 Link Here
187
	} else {														\
192
	} else {														\
188
		switch (Z_TYPE_P(op)) {										\
193
		switch (Z_TYPE_P(op)) {										\
189
			case IS_STRING:											\
194
			case IS_STRING:											\
190
				{													\
195
				{ \
196
                                        Z_STRLEN(holder) = 0;													\
191
					if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {	\
197
					if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {	\
192
						ZVAL_LONG(&(holder), 0);							\
198
						ZVAL_LONG(&(holder), 0);							\
193
					}														\
199
					}														\
Lines 229-234 Link Here
229
				Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));	\
235
				Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));	\
230
				break;												\
236
				break;												\
231
			case IS_STRING:											\
237
			case IS_STRING:											\
238
                                Z_STRLEN(holder) = 0; \
232
				Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);	\
239
				Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);	\
233
				break;												\
240
				break;												\
234
			case IS_ARRAY:											\
241
			case IS_ARRAY:											\
Lines 271-276 Link Here
271
				Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0);			\
278
				Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0);			\
272
				break;												\
279
				break;												\
273
			case IS_STRING:											\
280
			case IS_STRING:											\
281
                                Z_STRLEN(holder) = 0; \
274
				if (Z_STRLEN_P(op) == 0								\
282
				if (Z_STRLEN_P(op) == 0								\
275
					|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {	\
283
					|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {	\
276
					Z_LVAL(holder) = 0;								\
284
					Z_LVAL(holder) = 0;								\
Lines 356-361 Link Here
356
			{
364
			{
357
				char *strval = Z_STRVAL_P(op);
365
				char *strval = Z_STRVAL_P(op);
358
366
367
#if SUHOSIN_PATCH
368
                                Z_STRLEN_P(op) = 0;
369
#endif
359
				Z_LVAL_P(op) = strtol(strval, NULL, base);
370
				Z_LVAL_P(op) = strtol(strval, NULL, base);
360
				STR_FREE(strval);
371
				STR_FREE(strval);
361
			}
372
			}
Lines 416-421 Link Here
416
			{
427
			{
417
				char *strval = Z_STRVAL_P(op);
428
				char *strval = Z_STRVAL_P(op);
418
429
430
#if SUHOSIN_PATCH
431
                                Z_STRLEN_P(op) = 0;
432
#endif
419
				Z_DVAL_P(op) = zend_strtod(strval, NULL);
433
				Z_DVAL_P(op) = zend_strtod(strval, NULL);
420
				STR_FREE(strval);
434
				STR_FREE(strval);
421
			}
435
			}
Lines 502-509 Link Here
502
516
503
				if (Z_STRLEN_P(op) == 0
517
				if (Z_STRLEN_P(op) == 0
504
					|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
518
					|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
519
#if SUHOSIN_PATCH
520
                                        Z_STRLEN_P(op) = 0;
521
#endif
505
					Z_LVAL_P(op) = 0;
522
					Z_LVAL_P(op) = 0;
506
				} else {
523
				} else {
524
#if SUHOSIN_PATCH
525
                                        Z_STRLEN_P(op) = 0;
526
#endif
507
					Z_LVAL_P(op) = 1;
527
					Z_LVAL_P(op) = 1;
508
				}
528
				}
509
				STR_FREE(strval);
529
				STR_FREE(strval);
Lines 617-622 Link Here
617
	*entry = *op;
637
	*entry = *op;
618
	INIT_PZVAL(entry);
638
	INIT_PZVAL(entry);
619
639
640
#if SUHOSIN_PATCH
641
        Z_STRLEN_P(op) = 0;
642
#endif
620
	switch (type) {
643
	switch (type) {
621
		case IS_ARRAY:
644
		case IS_ARRAY:
622
			ALLOC_HASHTABLE(Z_ARRVAL_P(op));
645
			ALLOC_HASHTABLE(Z_ARRVAL_P(op));
(-)php-5.3.9/Zend/zend_variables.c (+6 lines)
Lines 34-39 Link Here
34
		case IS_CONSTANT:
34
		case IS_CONSTANT:
35
			CHECK_ZVAL_STRING_REL(zvalue);
35
			CHECK_ZVAL_STRING_REL(zvalue);
36
			STR_FREE_REL(zvalue->value.str.val);
36
			STR_FREE_REL(zvalue->value.str.val);
37
#if SUHOSIN_PATCH
38
                        zvalue->value.str.len = 0;
39
#endif
37
			break;
40
			break;
38
		case IS_ARRAY:
41
		case IS_ARRAY:
39
		case IS_CONSTANT_ARRAY: {
42
		case IS_CONSTANT_ARRAY: {
Lines 78-83 Link Here
78
		case IS_CONSTANT:
81
		case IS_CONSTANT:
79
			CHECK_ZVAL_STRING_REL(zvalue);
82
			CHECK_ZVAL_STRING_REL(zvalue);
80
			free(zvalue->value.str.val);
83
			free(zvalue->value.str.val);
84
#if SUHOSIN_PATCH
85
                        zvalue->value.str.len = 0;
86
#endif
81
			break;
87
			break;
82
		case IS_ARRAY:
88
		case IS_ARRAY:
83
		case IS_CONSTANT_ARRAY:
89
		case IS_CONSTANT_ARRAY:
(-)php-5.3.9/configure (-2 / +5 lines)
Lines 27854-27859 Link Here
27854
27854
27855
fi
27855
fi
27856
27856
27857
cat >> confdefs.h <<\EOF
27858
#define SUHOSIN_PATCH 1
27859
EOF
27857
27860
27858
  echo "$as_me:$LINENO: checking for declared timezone" >&5
27861
  echo "$as_me:$LINENO: checking for declared timezone" >&5
27859
echo $ECHO_N "checking for declared timezone... $ECHO_C" >&6
27862
echo $ECHO_N "checking for declared timezone... $ECHO_C" >&6
Lines 146756-146762 Link Here
146756
       php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
146759
       php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
146757
       strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
146760
       strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
146758
       network.c php_open_temporary_file.c php_logos.c \
146761
       network.c php_open_temporary_file.c php_logos.c \
146759
       output.c getopt.c; do
146762
       output.c getopt.c suhosin_patch.c ; do
146760
146763
146761
      IFS=.
146764
      IFS=.
146762
      set $ac_src
146765
      set $ac_src
Lines 146960-146966 Link Here
146960
    zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
146963
    zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
146961
    zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
146964
    zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
146962
    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
146965
    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
146963
    zend_closures.c zend_float.c; do
146966
    zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c ; do
146964
146967
146965
      IFS=.
146968
      IFS=.
146966
      set $ac_src
146969
      set $ac_src
(-)php-5.3.9/configure.in (-2 / +3 lines)
Lines 289-294 Link Here
289
sinclude(TSRM/threads.m4)
289
sinclude(TSRM/threads.m4)
290
sinclude(TSRM/tsrm.m4)
290
sinclude(TSRM/tsrm.m4)
291
291
292
sinclude(main/suhosin_patch.m4)
292
293
293
divert(2)
294
divert(2)
294
295
Lines 1406-1412 Link Here
1406
       php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1407
       php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1407
       strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1408
       strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1408
       network.c php_open_temporary_file.c php_logos.c \
1409
       network.c php_open_temporary_file.c php_logos.c \
1409
       output.c getopt.c)
1410
       output.c getopt.c suhosin_patch.c )
1410
1411
1411
PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
1412
PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
1412
       plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c \
1413
       plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c \
Lines 1434-1440 Link Here
1434
    zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1435
    zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1435
    zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
1436
    zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
1436
    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
1437
    zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
1437
    zend_closures.c zend_float.c)
1438
    zend_closures.c zend_float.c zend_canary.c zend_alloc_canary.c )
1438
1439
1439
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1440
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1440
  PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
1441
  PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
(-)php-5.3.9/ext/standard/dl.c (+17 lines)
Lines 254-259 Link Here
254
			return FAILURE;
254
			return FAILURE;
255
		}
255
		}
256
	}
256
	}
257
258
#if SUHOSIN_PATCH
259
	if (strncmp("suhosin", module_entry->name, sizeof("suhosin")-1) == 0) {
260
		void *log_func;
261
		/* sucessfully loaded suhosin extension, now check for logging function replacement */
262
		log_func = (void *) DL_FETCH_SYMBOL(handle, "suhosin_log");
263
		if (log_func == NULL) {
264
			log_func = (void *) DL_FETCH_SYMBOL(handle, "_suhosin_log");
265
		}
266
		if (log_func != NULL) {
267
			zend_suhosin_log = log_func;
268
		} else {
269
                        zend_suhosin_log(S_MISC, "could not replace logging function");
270
		}
271
	}
272
#endif	
273
257
	return SUCCESS;
274
	return SUCCESS;
258
}
275
}
259
/* }}} */
276
/* }}} */
(-)php-5.3.9/ext/standard/info.c (+27 lines)
Lines 878-883 Link Here
878
		
878
		
879
		php_info_print_table_end();
879
		php_info_print_table_end();
880
880
881
		/* Suhosin Patch */
882
		php_info_print_box_start(0);
883
		if (expose_php && !sapi_module.phpinfo_as_text) {
884
			PUTS("<a href=\"http://www.suhosin.org\"><img border=\"0\" src=\"");
885
			if (SG(request_info).request_uri) {
886
				char *elem_esc = php_info_html_esc(SG(request_info).request_uri TSRMLS_CC);
887
				PUTS(elem_esc);
888
				efree(elem_esc);
889
			}
890
			PUTS("?="SUHOSIN_LOGO_GUID"\" alt=\"Suhosin logo\" /></a>\n");
891
		}
892
		PUTS("This server is protected with the Suhosin Patch ");
893
		if (sapi_module.phpinfo_as_text) {
894
			PUTS(SUHOSIN_PATCH_VERSION);
895
		} else {
896
			zend_html_puts(SUHOSIN_PATCH_VERSION, strlen(SUHOSIN_PATCH_VERSION) TSRMLS_CC);
897
		}
898
		PUTS(!sapi_module.phpinfo_as_text?"<br />":"\n");
899
		if (sapi_module.phpinfo_as_text) {
900
			PUTS("Copyright (c) 2006-2007 Hardened-PHP Project\n");
901
			PUTS("Copyright (c) 2007-2012 SektionEins GmbH\n");
902
		} else {
903
			PUTS("Copyright (c) 2006-2007 <a href=\"http://www.hardened-php.net/\">Hardened-PHP Project</a>\n");
904
			PUTS("Copyright (c) 2007-2012 <a href=\"http://www.sektioneins.de/\">SektionEins GmbH</a>\n");
905
		}
906
		php_info_print_box_end();
907
881
		/* Zend Engine */
908
		/* Zend Engine */
882
		php_info_print_box_start(0);
909
		php_info_print_box_start(0);
883
		if (expose_php && !sapi_module.phpinfo_as_text) {
910
		if (expose_php && !sapi_module.phpinfo_as_text) {
(-)php-5.3.9/ext/standard/syslog.c (+2 lines)
Lines 42-47 Link Here
42
 */
42
 */
43
PHP_MINIT_FUNCTION(syslog)
43
PHP_MINIT_FUNCTION(syslog)
44
{
44
{
45
#if !SUHOSIN_PATCH
45
	/* error levels */
46
	/* error levels */
46
	REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
47
	REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
47
	REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
48
	REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
Lines 97-102 Link Here
97
	/* AIX doesn't have LOG_PERROR */
98
	/* AIX doesn't have LOG_PERROR */
98
	REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
99
	REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
99
#endif
100
#endif
101
#endif
100
	BG(syslog_device)=NULL;
102
	BG(syslog_device)=NULL;
101
103
102
	return SUCCESS;
104
	return SUCCESS;
(-)php-5.3.9/main/fopen_wrappers.c (-6 / +1 lines)
Lines 85-97 Link Here
85
PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
85
PHPAPI ZEND_INI_MH(OnUpdateBaseDir)
86
{
86
{
87
	char **p, *pathbuf, *ptr, *end;
87
	char **p, *pathbuf, *ptr, *end;
88
#ifndef ZTS
89
	char *base = (char *) mh_arg2;
90
#else
91
	char *base = (char *) ts_resource(*((int *) mh_arg2));
92
#endif
93
88
94
	p = (char **) (base + (size_t) mh_arg1);
89
	p = &PG(open_basedir);
95
90
96
	if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {
91
	if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) {
97
		/* We're in a PHP_INI_SYSTEM context, no restrictions */
92
		/* We're in a PHP_INI_SYSTEM context, no restrictions */
(-)php-5.3.9/main/main.c (-2 / +17 lines)
Lines 91-96 Link Here
91
91
92
#include "SAPI.h"
92
#include "SAPI.h"
93
#include "rfc1867.h"
93
#include "rfc1867.h"
94
#if SUHOSIN_PATCH
95
#include "suhosin_globals.h"
96
#endif
94
97
95
#if HAVE_MMAP || defined(PHP_WIN32)
98
#if HAVE_MMAP || defined(PHP_WIN32)
96
# if HAVE_UNISTD_H
99
# if HAVE_UNISTD_H
Lines 504-510 Link Here
504
	STD_PHP_INI_ENTRY("extension_dir",			PHP_EXTENSION_DIR,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	extension_dir,			php_core_globals,	core_globals)
507
	STD_PHP_INI_ENTRY("extension_dir",			PHP_EXTENSION_DIR,		PHP_INI_SYSTEM,		OnUpdateStringUnempty,	extension_dir,			php_core_globals,	core_globals)
505
	STD_PHP_INI_ENTRY("include_path",			PHP_INCLUDE_PATH,		PHP_INI_ALL,		OnUpdateStringUnempty,	include_path,			php_core_globals,	core_globals)
508
	STD_PHP_INI_ENTRY("include_path",			PHP_INCLUDE_PATH,		PHP_INI_ALL,		OnUpdateStringUnempty,	include_path,			php_core_globals,	core_globals)
506
	PHP_INI_ENTRY("max_execution_time",			"30",		PHP_INI_ALL,			OnUpdateTimeout)
509
	PHP_INI_ENTRY("max_execution_time",			"30",		PHP_INI_ALL,			OnUpdateTimeout)
507
	STD_PHP_INI_ENTRY("open_basedir",			NULL,		PHP_INI_ALL,		OnUpdateBaseDir,			open_basedir,			php_core_globals,	core_globals)
510
	PHP_INI_ENTRY("open_basedir",			NULL,		PHP_INI_ALL,		OnUpdateBaseDir)
508
	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)
511
	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)
509
512
510
	STD_PHP_INI_BOOLEAN("file_uploads",			"1",		PHP_INI_SYSTEM,		OnUpdateBool,			file_uploads,			php_core_globals,	core_globals)
513
	STD_PHP_INI_BOOLEAN("file_uploads",			"1",		PHP_INI_SYSTEM,		OnUpdateBool,			file_uploads,			php_core_globals,	core_globals)
Lines 1810-1815 Link Here
1810
}
1813
}
1811
#endif
1814
#endif
1812
1815
1816
#if SUHOSIN_PATCH
1817
PHPAPI void suhosin_startup();
1818
#endif
1819
1813
/* {{{ php_module_startup
1820
/* {{{ php_module_startup
1814
 */
1821
 */
1815
int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules)
1822
int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules)
Lines 1858-1863 Link Here
1858
	php_win32_init_rng_lock();
1865
	php_win32_init_rng_lock();
1859
#endif
1866
#endif
1860
1867
1868
#if SUHOSIN_PATCH
1869
        suhosin_startup();
1870
#endif
1871
1861
	module_shutdown = 0;
1872
	module_shutdown = 0;
1862
	module_startup = 1;
1873
	module_startup = 1;
1863
	sapi_initialize_empty_request(TSRMLS_C);
1874
	sapi_initialize_empty_request(TSRMLS_C);
Lines 1980-1986 Link Here
1980
	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);
1991
	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);
1981
	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
1992
	REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
1982
	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
1993
	REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
1983
	REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
1994
#if SUHOSIN_PATCH
1995
        REGISTER_MAIN_LONG_CONSTANT("SUHOSIN_PATCH", 1, CONST_PERSISTENT | CONST_CS);
1996
        REGISTER_MAIN_STRINGL_CONSTANT("SUHOSIN_PATCH_VERSION", SUHOSIN_PATCH_VERSION, sizeof(SUHOSIN_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
1997
#endif	
1998
        REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
1984
	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
1999
	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
1985
	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
2000
	REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
1986
#ifdef ZEND_MULTIBYTE
2001
#ifdef ZEND_MULTIBYTE
(-)php-5.3.9/main/php.h (+4 lines)
Lines 449-454 Link Here
449
#endif
449
#endif
450
#endif /* !XtOffsetOf */
450
#endif /* !XtOffsetOf */
451
451
452
#if SUHOSIN_PATCH
453
#include "suhosin_patch.h"
454
#endif
455
452
#endif
456
#endif
453
457
454
/*
458
/*
(-)php-5.3.9/main/php_config.h.in (+3 lines)
Lines 405-410 Link Here
405
/* Define to 1 if you have the `alphasort' function. */
405
/* Define to 1 if you have the `alphasort' function. */
406
#undef HAVE_ALPHASORT
406
#undef HAVE_ALPHASORT
407
407
408
/* Suhosin-Patch for PHP */
409
#undef SUHOSIN_PATCH
410
408
/* Whether you have AOLserver */
411
/* Whether you have AOLserver */
409
#undef HAVE_AOLSERVER
412
#undef HAVE_AOLSERVER
410
413
(-)php-5.3.9/main/php_logos.c (-1 / +7 lines)
Lines 50-55 Link Here
50
	return zend_hash_del(&phpinfo_logo_hash, logo_string, strlen(logo_string));
50
	return zend_hash_del(&phpinfo_logo_hash, logo_string, strlen(logo_string));
51
}
51
}
52
52
53
#if SUHOSIN_PATCH
54
#include "suhosin_logo.h"
55
#endif
56
53
int php_init_info_logos(void)
57
int php_init_info_logos(void)
54
{
58
{
55
	if(zend_hash_init(&phpinfo_logo_hash, 0, NULL, NULL, 1)==FAILURE) 
59
	if(zend_hash_init(&phpinfo_logo_hash, 0, NULL, NULL, 1)==FAILURE) 
Lines 58-64 Link Here
58
	php_register_info_logo(PHP_LOGO_GUID    , "image/gif", php_logo    , sizeof(php_logo));
62
	php_register_info_logo(PHP_LOGO_GUID    , "image/gif", php_logo    , sizeof(php_logo));
59
	php_register_info_logo(PHP_EGG_LOGO_GUID, "image/gif", php_egg_logo, sizeof(php_egg_logo));
63
	php_register_info_logo(PHP_EGG_LOGO_GUID, "image/gif", php_egg_logo, sizeof(php_egg_logo));
60
	php_register_info_logo(ZEND_LOGO_GUID   , "image/gif", zend_logo   , sizeof(zend_logo));
64
	php_register_info_logo(ZEND_LOGO_GUID   , "image/gif", zend_logo   , sizeof(zend_logo));
61
65
#if SUHOSIN_PATCH
66
	php_register_info_logo(SUHOSIN_LOGO_GUID, "image/jpeg", suhosin_logo   , sizeof(suhosin_logo));
67
#endif
62
	return SUCCESS;
68
	return SUCCESS;
63
}
69
}
64
70
(-)php-5.3.9/main/snprintf.c (+9 lines)
Lines 782-787 Link Here
782
			 */
782
			 */
783
			switch (*fmt) {
783
			switch (*fmt) {
784
				case 'Z':
784
				case 'Z':
785
#if SUHOSIN_PATCH
786
					zend_suhosin_log(S_MISC, "'Z' specifier within format string");
787
					goto skip_output;
788
#else
785
					zvp = (zval*) va_arg(ap, zval*);
789
					zvp = (zval*) va_arg(ap, zval*);
786
					zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
790
					zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
787
					if (free_zcopy) {
791
					if (free_zcopy) {
Lines 792-797 Link Here
792
					if (adjust_precision && precision < s_len) {
796
					if (adjust_precision && precision < s_len) {
793
						s_len = precision;
797
						s_len = precision;
794
					}
798
					}
799
#endif
795
					break;
800
					break;
796
				case 'u':
801
				case 'u':
797
					switch(modifier) {
802
					switch(modifier) {
Lines 1093-1099 Link Here
1093
1098
1094
1099
1095
				case 'n':
1100
				case 'n':
1101
#if SUHOSIN_PATCH
1102
					zend_suhosin_log(S_MISC, "'n' specifier within format string");
1103
#else
1096
					*(va_arg(ap, int *)) = cc;
1104
					*(va_arg(ap, int *)) = cc;
1105
#endif
1097
					goto skip_output;
1106
					goto skip_output;
1098
1107
1099
					/*
1108
					/*
(-)php-5.3.9/main/spprintf.c (+9 lines)
Lines 390-395 Link Here
390
			 */
390
			 */
391
			switch (*fmt) {
391
			switch (*fmt) {
392
				case 'Z':
392
				case 'Z':
393
#if SUHOSIN_PATCH
394
					zend_suhosin_log(S_MISC, "'Z' specifier within format string");
395
					goto skip_output;
396
#else
393
					zvp = (zval*) va_arg(ap, zval*);
397
					zvp = (zval*) va_arg(ap, zval*);
394
					zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
398
					zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
395
					if (free_zcopy) {
399
					if (free_zcopy) {
Lines 400-405 Link Here
400
					if (adjust_precision && precision < s_len) {
404
					if (adjust_precision && precision < s_len) {
401
						s_len = precision;
405
						s_len = precision;
402
					}
406
					}
407
#endif
403
					break;
408
					break;
404
				case 'u':
409
				case 'u':
405
					switch(modifier) {
410
					switch(modifier) {
Lines 700-706 Link Here
700
705
701
706
702
				case 'n':
707
				case 'n':
708
#if SUHOSIN_PATCH
709
					zend_suhosin_log(S_MISC, "'n' specifier within format string");
710
#else
703
					*(va_arg(ap, int *)) = xbuf->len;
711
					*(va_arg(ap, int *)) = xbuf->len;
712
#endif
704
					goto skip_output;
713
					goto skip_output;
705
714
706
					/*
715
					/*
(-)php-5.3.9/main/suhosin_globals.h (+61 lines)
Line 0 Link Here
1
/*
2
   +----------------------------------------------------------------------+
3
   | Suhosin-Patch for PHP                                                |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 2004-2009 Stefan Esser                                 |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.02 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available at through the world-wide-web at                           |
10
   | http://www.php.net/license/2_02.txt.                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Stefan Esser <stefan.esser@sektioneins.de>                   |
16
   +----------------------------------------------------------------------+
17
 */
18
19
#ifndef SUHOSIN_GLOBALS_H
20
#define SUHOSIN_GLOBALS_H
21
22
typedef struct _suhosin_patch_globals suhosin_patch_globals_struct;
23
24
#ifdef ZTS
25
# define SPG(v) TSRMG(suhosin_patch_globals_id, suhosin_patch_globals_struct *, v)
26
extern int suhosin_patch_globals_id;
27
#else
28
# define SPG(v) (suhosin_patch_globals.v)
29
extern struct _suhosin_patch_globals suhosin_patch_globals;
30
#endif
31
32
33
struct _suhosin_patch_globals {
34
	/* logging */
35
	int log_syslog;
36
	int log_syslog_facility;
37
	int log_syslog_priority;
38
	int log_sapi;
39
	int log_script;
40
	int log_phpscript;
41
	char *log_scriptname;
42
	char *log_phpscriptname;
43
	zend_bool log_phpscript_is_safe;
44
	zend_bool log_use_x_forwarded_for;
45
	
46
	/* memory manager canary protection */
47
	unsigned int canary_1;
48
	unsigned int canary_2;
49
	unsigned int canary_3;
50
	unsigned int dummy;
51
};
52
53
54
#endif /* SUHOSIN_GLOBALS_H */
55
56
/*
57
 * Local variables:
58
 * tab-width: 4
59
 * c-basic-offset: 4
60
 * End:
61
 */
(-)php-5.3.9/main/suhosin_logo.h (+178 lines)
Line 0 Link Here
1
static unsigned char suhosin_logo[] =
2
	"\xff\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x01\x01\x00\x48"
3
	"\x00\x48\x00\x00\xff\xe1\x00\x16\x45\x78\x69\x66\x00\x00\x4d\x4d"
4
	"\x00\x2a\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\xff\xdb\x00\x43"
5
	"\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
6
	"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
7
	"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
8
	"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
9
	"\x01\xff\xc0\x00\x0b\x08\x00\x27\x00\x71\x01\x01\x22\x00\xff\xc4"
10
	"\x00\x1e\x00\x00\x02\x02\x02\x03\x01\x01\x00\x00\x00\x00\x00\x00"
11
	"\x00\x00\x00\x00\x09\x06\x08\x05\x07\x02\x03\x0a\x01\x04\xff\xc4"
12
	"\x00\x32\x10\x00\x01\x04\x03\x00\x02\x00\x05\x01\x05\x09\x01\x00"
13
	"\x00\x00\x00\x05\x02\x03\x04\x06\x01\x07\x08\x00\x09\x11\x12\x13"
14
	"\x14\x21\x15\x0a\x16\x31\x56\x96\x17\x18\x19\x23\x32\x41\x58\x98"
15
	"\xd4\xd6\xff\xda\x00\x08\x01\x01\x00\x00\x3f\x00\xf4\xc1\xe1\xe5"
16
	"\x69\xe9\x3e\xb9\xd1\x7c\x8a\x2e\x9d\x66\xe8\x3b\x29\x4d\x7f\x46"
17
	"\xba\x58\x55\x54\x8d\xb1\x5f\xaa\xd9\x8d\x51\x2b\xb6\x27\x5a\x69"
18
	"\xd1\x43\xaf\x16\x1a\xf0\xb2\xb1\xe9\x6d\x9f\xc2\xa4\x36\x18\xb5"
19
	"\x85\x10\x41\xbe\xfc\x09\xac\x49\x29\x11\xd4\x32\x97\xec\x08\x13"
20
	"\xc1\x2d\x20\xc3\x59\xeb\x26\x05\xd8\x6b\x76\x31\x43\x8f\x57\xcf"
21
	"\x84\x9f\x14\xa8\x53\x81\x0b\xc3\x64\x80\xa3\x02\x0a\x41\x75\xf8"
22
	"\x44\x85\x93\x81\x22\x3c\xd8\x13\xe1\xbe\xf4\x59\x91\x1f\x6a\x44"
23
	"\x77\x5c\x69\xc4\x2f\x39\x5f\x0f\x2a\x8d\xeb\xba\xf8\xc3\x56\x6c"
24
	"\x3b\x36\xa7\xda\xbd\x4d\xa1\xb5\x4e\xc6\xa7\xa4\x3a\xec\x15\x2d"
25
	"\xa5\xb3\xea\x5a\xdc\xac\x46\xac\x01\x60\xd8\x43\xc8\x8e\x8b\xb1"
26
	"\x40\x4c\x95\x8b\x34\x41\x28\x52\x91\x28\x43\xd3\xa3\xb6\xa7\x55"
27
	"\x15\xe7\x5a\x96\xcb\xf1\xda\xe5\x55\xee\xfe\x1e\xbd\xd9\x41\xd3"
28
	"\x28\xfd\x97\xca\x57\x2b\x85\x9c\xa4\x30\x95\xaa\xa5\x57\xa2\x35"
29
	"\x15\x86\xcb\x61\x34\x41\xe4\xc7\x80\x20\x18\x21\x17\x09\x85\x0b"
30
	"\x14\x9d\x21\x68\x62\x1c\x08\x11\x64\x4b\x92\xf2\xd2\xd3\x2d\x2d"
31
	"\x6a\xc2\x73\x6b\x3c\x3c\x8b\x9e\xbc\x52\xaa\xa4\xab\x81\x6c\xf6"
32
	"\xfa\xbd\x70\xc5\xc6\x7b\xc2\xaa\x22\x4f\x58\x04\x87\x25\x6a\x27"
33
	"\x1d\xa4\x3d\x20\x75\x72\x01\x09\x71\xe5\x1c\x9e\xc3\x2e\x36\xf3"
34
	"\xd0\xc6\x35\x2a\x43\x4d\x2d\x0e\x2d\xb4\xa1\x49\xce\x65\x1e\x52"
35
	"\x9e\xa1\xf6\x09\xcc\xdc\x63\x66\xa8\x01\xe9\x3b\x0d\xd7\x5a\x85"
36
	"\xbb\xc5\x65\xc0\x7b\x2e\x46\xa9\xd9\x56\x1d\x4c\x92\x72\x26\x4e"
37
	"\x86\xd5\x68\xae\xc4\xaa\x55\xce\xd7\x83\x59\xb3\x81\xee\xce\x74"
38
	"\x39\x39\x31\x9f\x8a\x25\xe8\xa5\xa5\xe5\x81\xf2\x11\x23\xcb\xa1"
39
	"\x1e\x43\x12\xe3\xb1\x2a\x2b\xcd\xc8\x8d\x25\x96\xa4\x47\x7d\x95"
40
	"\xa5\xc6\x9f\x61\xe4\x25\xc6\x5e\x69\xc4\xe7\x29\x5b\x6e\xb6\xa4"
41
	"\xad\x0b\x4e\x72\x95\x25\x58\x56\x33\x9c\x67\xce\xef\x0f\x17\xbf"
42
	"\x4c\x7b\x2d\xe6\xfe\x76\x35\x27\x5a\x07\x97\x67\xe8\xae\x8d\x71"
43
	"\x0f\xb2\x13\x99\xb9\xbc\x14\xad\xb3\xb7\xe6\x11\x6f\xe0\xda\x58"
44
	"\xb1\x08\xac\xa6\x6c\x2d\x7f\x05\xb7\x56\xd2\xe6\xcf\xbb\x4d\x0c"
45
	"\xe3\x50\xb2\xec\x91\xf0\x4a\xb8\xd6\x22\xb8\xa7\xf6\x67\xaf\xcf"
46
	"\x63\x7e\xd7\xe7\x42\xd8\xbd\xc3\x71\xa1\xf2\x7e\x9b\xa8\x97\x83"
47
	"\x6e\xd1\xdc\x4b\x06\x11\x2d\xae\x26\x61\x98\x72\x10\xf4\x42\x5d"
48
	"\x20\x4a\xa3\x73\xd7\xf2\xcd\x3c\x48\x32\xe4\x03\x9f\x80\x37\x08"
49
	"\x36\x11\xd0\xcb\x97\x6c\x08\xed\x6d\x33\x24\xa2\x1b\xb4\x77\xdf"
50
	"\x61\x5d\x5f\xc1\x43\xc2\x82\xeb\x0f\x5d\x84\x08\x68\xaa\xa4\x01"
51
	"\xe1\x19\xdf\xbc\x31\x65\xfe\xd1\xf5\x7d\x7a\xb2\x2a\x33\x50\x21"
52
	"\x2a\x56\x9d\xb1\x81\xab\xdb\x35\x78\x30\x83\xd9\x89\x1d\x31\xac"
53
	"\x96\x14\x07\x61\xbc\x20\x68\x42\x85\x33\x19\xac\xbe\xdb\x34\x56"
54
	"\xf1\xd5\xfd\x29\xa9\x28\xdb\xcb\x4c\x5a\x23\xdc\xf5\x96\xc5\x10"
55
	"\xa3\x35\x5b\x14\x68\xd3\x61\x62\x64\x76\x26\xcb\x17\x3e\x34\x98"
56
	"\x04\xa3\xc4\x20\x38\x90\x92\xe3\xc8\x07\x2c\x36\x74\x66\x26\x0e"
57
	"\x29\x02\x64\x29\x2d\x21\xe6\x16\x9c\x6b\xce\xa3\x89\xd9\x4f\xd3"
58
	"\xc4\xbd\xc5\x87\x79\x9c\x65\xf6\x39\x45\x60\xe8\xce\x9e\xab\x6d"
59
	"\x13\x15\x22\xe1\x5e\x4b\x38\x42\xc4\x1e\xd5\x76\xe0\xc5\xeb\x85"
60
	"\x07\x2d\x0f\xb8\xb6\xa6\xd6\x6d\x71\x0d\xa2\x43\x4c\x25\xea\xfa"
61
	"\xa1\xae\x4c\xe4\x7d\xbd\x76\xa9\xfb\x06\xc2\x83\x42\xeb\xad\xe7"
62
	"\xe9\x5f\x68\x6f\xba\xfb\x2f\x07\xce\xb8\x13\xc1\x9b\xeb\xb0\x76"
63
	"\x45\x57\x28\x7b\xea\xbe\x0f\xf4\x30\x7b\xa0\xed\xe4\x22\x93\x21"
64
	"\xfc\xbc\xe0\xb9\x75\xc1\x4f\xfc\xef\xb6\xfa\xa1\xfc\x64\xa1\x4a"
65
	"\x82\xc7\x33\xad\x75\xed\x82\xbd\x3d\xdb\xf7\xa8\xbe\x5e\xbb\x36"
66
	"\x62\x04\x9a\x2e\xc5\xd9\x9e\x9c\x3a\x0b\x98\x0b\x57\xac\xf1\x24"
67
	"\x62\x58\x83\x15\x5b\xa6\xf2\xda\x34\x70\x03\xce\x0f\x93\x1b\x12"
68
	"\xc7\xce\x54\x87\x33\x15\xd6\x53\x25\x1f\x2a\x90\x87\x12\xe3\x78"
69
	"\xef\x55\x77\x4d\x4a\xd8\x7e\xef\xd2\xfd\xd1\xaf\x3a\xaf\x55\xdb"
70
	"\x6a\x2d\x3d\x42\xac\x51\x79\xee\x91\xab\xe1\x05\x2d\x3c\x80\xa2"
71
	"\x43\xad\x22\x2e\xd5\x33\x13\xa4\x9e\x00\xe0\x04\x10\x84\xc8\xf2"
72
	"\x19\x30\x92\x1f\xaa\xc3\x28\xc9\x76\x30\x3f\xe9\x10\x61\x5e\x79"
73
	"\xd5\xf7\xdf\xd0\x54\xdb\xae\xb6\xae\xfa\xe8\xa3\x57\xe0\x6c\x2d"
74
	"\xf7\xbd\x49\xd6\x6e\x76\x79\xcc\x54\x0c\x5f\xff\x00\xbb\x06\x98"
75
	"\xa6\x9e\x89\x61\xb4\x6f\xc3\xe3\x6a\xc2\x4f\x59\x03\xc9\x80\x2c"
76
	"\x59\x24\x44\x70\x38\xd5\x96\x6a\x9e\x8b\x81\x64\xe5\xbc\xa0\x3c"
77
	"\x33\xaf\x17\x9d\xff\x00\x71\x1a\xd1\x3a\x80\x66\xb3\xd9\x31\x77"
78
	"\x0d\x12\xbd\xae\x29\xb5\x6a\xd6\xcf\x8d\x68\x87\x75\xcd\xe8\x65"
79
	"\x5a\xbe\x3c\x04\x7b\x34\xdb\x54\x19\xa4\x63\x9c\x2a\x5d\x23\xbe"
80
	"\xf4\xb1\x1c\x4d\x90\xec\x92\x2f\x49\x71\xf7\x14\xf2\x97\x9f\x15"
81
	"\x57\xed\x13\x21\x2a\xf5\x33\xd1\x2a\x52\x52\xac\xb7\x62\xd1\xcb"
82
	"\x46\x73\x8c\x67\x28\x56\x77\x86\xbf\x6f\x2a\x4e\x73\xfe\x95\x65"
83
	"\x0b\x5a\x3e\x38\xfc\xfc\xaa\x56\x3f\x86\x73\xe3\xb9\x4a\x52\x84"
84
	"\xa5\x08\x4e\x12\x94\x27\x09\x4a\x53\x8c\x61\x29\x4a\x71\xf0\x4a"
85
	"\x53\x8c\x7e\x31\x8c\x63\x18\xc6\x31\x8f\xc6\x31\xf8\xc7\x9f\x7c"
86
	"\xd5\xbb\xae\x5e\xe2\x1f\xab\x6e\x24\x34\x00\x8a\x25\x83\x70\x40"
87
	"\x1c\xcc\xda\x45\x7f\x66\x4e\x30\x2e\x94\x7e\x74\x49\xf0\xe4\x4e"
88
	"\x06\x5c\xa8\x2f\x89\x21\x2e\x98\x0e\xd9\x21\xc2\x0b\x21\x0f\xc4"
89
	"\x16\x6e\x48\xd9\xe4\xe3\x4a\x19\x1e\x64\x67\x54\xff\x00\x3a\x6d"
90
	"\x4f\x62\xb5\x00\x4a\xaa\x51\xfd\x2d\xe8\x0e\x6c\xaf\xc6\x7d\x6d"
91
	"\xc8\x88\xc7\x67\xea\x8a\x58\x02\x73\xe3\x65\x4d\xc9\x24\xc0\x3d"
92
	"\x57\xa3\x2e\x53\x16\x99\x4f\xe5\xe7\x19\x97\x3e\x3b\xcf\xc9\x4b"
93
	"\x99\x7f\x33\x25\xa5\xdf\xba\x77\x2b\xd3\x3e\xc2\x7b\x8b\x94\x07"
94
	"\xe9\x52\x5b\x43\x87\x34\x14\x86\x37\xcf\x41\x6b\x8e\x6a\xa5\x22"
95
	"\xab\xdb\x96\xa2\xcf\x46\xd8\x9b\x45\x93\xef\xd6\xdf\x3e\x99\x9c"
96
	"\x7e\x29\x10\x6b\x6c\xa2\xb8\x43\x05\x09\x44\x70\x8c\xb8\xaa\x54"
97
	"\x7c\x30\x36\x5e\x1c\x5e\x5b\x9f\x6c\x0d\x81\xee\xa0\x93\x8d\x67"
98
	"\x55\xf3\x87\xaf\xaa\x6b\x58\xf9\xbe\xb2\x36\x07\x42\x6e\xbd\x96"
99
	"\xe3\x9f\x1f\x8f\xc9\xf4\x9d\xae\x6a\x7d\x4c\x96\xbe\x5f\xc7\xcd"
100
	"\xf3\xb2\xf7\xcd\xf0\xcf\xc3\xe4\xf8\xfe\x37\x4f\x1c\x4d\xf6\x40"
101
	"\xf1\x6b\x7c\x4e\xe0\xa6\x71\xad\x56\xa7\x1c\x5c\x15\x6b\xfc\xf3"
102
	"\x01\x5d\xac\xf1\x75\x9a\x72\x6b\xaa\x28\xc5\x88\x6d\xfb\x33\x85"
103
	"\xe0\x4e\x61\xab\xeb\x31\x2c\x71\x08\x73\x11\x3b\xfc\xb5\xc0\x96"
104
	"\xcc\x87\x24\x44\xb5\x9b\x9e\xb3\x71\xba\xe9\xed\xb1\x4e\xd7\x76"
105
	"\x6c\xd2\xb6\x05\xb7\x5a\xde\xeb\x34\x5b\x96\x16\xfb\x59\xa9\x5c"
106
	"\x4f\x55\xca\x8a\xac\x59\xb0\xe4\x54\x39\x25\xbc\x81\x37\x2a\x09"
107
	"\x5f\x9e\x3b\x6b\x7d\x1f\x69\xf3\x34\x85\x39\x84\xa7\x28\x0b\xd3"
108
	"\xfd\xfb\x4b\x7a\xea\xe7\xd2\x3c\xd3\xda\x15\x68\xbc\x73\xd3\x22"
109
	"\x6f\xd7\x72\x5b\x2b\x66\xee\xa8\x0d\x54\xe8\x5b\xf9\x92\x96\x92"
110
	"\x93\xea\x97\x4a\xc7\x43\x10\x46\x35\xc5\xc0\x60\x8a\xe4\xc1\xb5"
111
	"\x36\xc6\xae\xed\xf7\x70\xa5\x86\x99\x3d\x91\xf8\xfd\x4e\x53\xeb"
112
	"\xbb\xbd\x6d\xec\x8f\xd7\x89\x3d\x31\x7f\xd7\x78\xba\x50\xbb\x74"
113
	"\x9d\xf6\xac\x4e\xb9\x03\x9c\x79\xd5\xe1\xbd\x17\x68\xd9\x13\x0b"
114
	"\x45\x75\x88\x00\x1d\x1f\xae\x73\x6a\x1d\x5c\x6e\x44\x9f\xa6\xfa"
115
	"\x4e\xd8\x25\x8b\xc0\xbc\xb2\x99\xe3\x17\x24\xb3\x23\xe2\x48\x8b"
116
	"\xfa\x22\xe7\x7e\x8f\xe6\x3f\x5f\x55\x0d\x75\xd3\x51\x0b\xd7\xed"
117
	"\xd3\x6f\x97\x3b\x85\x42\x80\x7e\x5f\xdc\x1b\xd6\xba\xee\xc4\x80"
118
	"\xce\x06\xa9\x15\x8c\x97\x5f\x40\x69\xb2\x4d\xc5\xb2\x5c\x1e\x01"
119
	"\x87\x7e\xe0\x36\x6d\x78\x80\x4e\x3c\x02\xec\x90\x1d\x11\x81\x74"
120
	"\xa5\x8b\xa4\xa0\x56\x06\xd5\x79\x72\x85\x57\x3b\xb2\x2e\xae\x90"
121
	"\x18\x8d\x91\xb2\x0e\x44\x19\xaa\xb4\xcc\x08\xed\x46\xfa\xd7\x2b"
122
	"\x78\x58\x72\x5d\xbb\x5e\x49\xe7\xee\xf3\x8a\x9d\x22\xa4\x19\xc8"
123
	"\xe7\x08\xc3\x90\x9b\x35\x9a\xa4\x25\x8c\x4b\x9b\xa7\xf8\xbf\x81"
124
	"\xf5\xdf\x22\x66\xf1\x7e\x9f\x66\x3d\xbb\xfa\x73\x73\x4d\xfd\x67"
125
	"\x7b\xf4\xce\xc3\x62\x2e\x6f\xbb\x0c\xa2\xdc\x69\xfc\x8a\x17\x0e"
126
	"\x3a\x9e\x83\x46\xd7\xe3\x5e\x65\x86\xc0\x51\x00\xbb\x91\xe3\xe1"
127
	"\xc1\x16\xc4\xe9\x65\x5c\x14\x3e\x44\x6a\x6b\xd1\x1e\xb0\x36\xdd"
128
	"\x0b\x7d\x8a\xeb\xaf\x58\x5b\x64\x3f\x38\xed\x52\x76\xe8\x46\xf7"
129
	"\x86\x84\xb3\x93\xb1\x0b\xe5\xfd\xfd\x0d\xe9\x6d\xe4\xf1\x1b\x1d"
130
	"\x56\xb4\x34\xe4\x6a\xf5\xa4\x9c\x2c\xc9\x64\x94\xc1\xf5\x79\x6d"
131
	"\x12\x96\xf3\x47\xc5\x48\xa8\xdb\xd8\x95\x64\x29\xcf\xf6\x88\xf1"
132
	"\x95\x7a\x98\xe8\xbc\x27\x19\xce\x73\x61\xd1\xb8\xc6\x31\x8c\xe7"
133
	"\x39\xce\x77\x9e\xbc\xc6\x31\x8c\x63\xf3\x9c\xe7\x39\xc6\x31\x8f"
134
	"\xf7\xce\x7e\x1e\x3b\x7f\x0f\x0f\x0f\x13\x57\xb9\x0a\xe1\x0b\x64"
135
	"\x5f\x58\x40\xc6\xc7\x7a\x4b\xf2\x3d\xbc\x71\xf4\xa7\xd2\xca\x14"
136
	"\xe2\x98\x1a\x30\x1e\xe0\x26\x5a\x6a\xf0\x9c\x67\x38\x66\x00\xb8"
137
	"\x72\xe6\xbe\xac\xfe\x12\xd3\x0b\x56\x73\x8c\x63\xc7\x2b\xe1\xe2"
138
	"\xe8\xdd\x7b\xff\x00\xd8\xe5\x23\x6c\xce\xa8\x69\xcf\x5e\x3a\xef"
139
	"\x77\xea\xe5\xab\x0e\x82\xdb\xd9\xed\x7a\x9e\xb8\x6d\x51\x32\xdb"
140
	"\x79\xc3\x36\x9a\x2d\xa3\x50\x39\x65\x0a\x63\x0e\xe5\xd4\x39\x12"
141
	"\xbf\x8b\x98\xa4\xa1\x2d\xad\xb3\xcf\x65\x6a\x43\x78\xb3\x3b\x07"
142
	"\xd8\xd5\xea\xae\x76\xad\x6f\xf5\xff\x00\xca\x93\xab\x96\xb0\x64"
143
	"\xeb\xd6\x4a\xd5\x87\xba\xec\x24\x60\x97\x06\x76\x03\xe3\x4c\x07"
144
	"\x29\x11\x8e\x34\x25\x02\x64\x29\xf0\x25\x48\x85\x3a\x33\x8b\x7a"
145
	"\x3c\x86\x1e\x75\xa5\x61\xc6\x97\x9f\x8d\x25\xf5\xc9\xcd\xde\xc9"
146
	"\x7d\x77\xf2\xc8\x7e\x70\xaf\x73\x5f\x2d\xec\xa2\x51\x2d\x96\xfb"
147
	"\x89\xad\x80\x57\xb2\x36\x1d\x7d\x83\x45\xac\xf3\xdb\xcc\x6c\x31"
148
	"\x4f\xcf\x30\x58\xd0\x12\x28\x90\x50\x42\x86\xfb\x48\x16\x3c\xc5"
149
	"\x9c\xf8\xe7\xcc\x29\x88\xb3\x4a\x4b\x4e\x6c\xbc\xdb\xc7\xbb\xe9"
150
	"\xb6\xa0\x8b\x11\xa1\x7d\x73\xd7\xe9\xbf\x7e\xc2\x6c\x10\x8d\xee"
151
	"\x9d\xef\x63\x3a\xe0\xf5\xbe\x8c\x3e\xa1\xc7\xc5\xd1\x00\x44\x1e"
152
	"\xf3\x51\xf2\xe2\xb0\xe3\xb5\x13\x7f\x32\xf1\x8c\xa6\x22\xfe\x1f"
153
	"\x49\x4d\xbb\xcf\x3a\x5d\xed\x4c\xd2\xfc\x85\xed\x23\xd6\xc7\x50"
154
	"\xb6\x5b\x3a\x16\x83\xb8\x6f\xfd\x32\x3f\xaa\x36\x34\xbb\xf5\x96"
155
	"\xa9\xab\xcf\x9f\x8f\xac\xc3\xca\xd5\x8b\xd8\x48\x9e\x79\xaa\x30"
156
	"\x87\xca\x58\x4d\x59\x96\xb9\x4f\xc5\x1b\x1c\xd2\xda\x5b\xe6\x57"
157
	"\x29\xa1\x28\x7a\x2b\x5b\xff\x00\x12\x2f\x5e\x3f\xf3\xbb\x8e\x7f"
158
	"\xec\xc6\x98\xff\x00\xed\x3c\xa6\xdd\xa9\xdc\x7e\xa0\xf7\xd6\x99"
159
	"\x31\xa2\xf7\xaf\x6b\xe9\x82\x74\x4b\x3d\x8f\x5e\x58\x0b\x33\xab"
160
	"\xef\xc3\xaf\x84\x64\xb9\xae\xb6\x25\x5f\x62\x8f\x1c\xe3\xf4\x51"
161
	"\xb7\x96\xe3\x0e\x30\x42\xa9\x18\x39\xbf\x9e\x2a\x1f\x74\x19\x02"
162
	"\x2d\x43\x93\x06\x63\xb1\xa7\x47\x6a\xfa\x9b\x6c\xeb\xbd\xe9\xae"
163
	"\x6a\x7b\x6f\x53\x5a\x60\x5d\xb5\xcd\xe8\x67\xeb\x35\x3b\x48\xc6"
164
	"\xa6\xb3\x04\xc8\xdf\xb8\x7e\x26\x64\xb0\xc9\x18\xb0\xa7\x33\xf2"
165
	"\x4a\x8b\x22\x3b\x8d\x4b\x89\x1d\xf6\x9d\x65\xc4\x38\xd2\x54\x9c"
166
	"\xe3\xcd\x89\xe1\xe1\xe6\x3e\x70\x81\x45\x1d\x18\xf9\x31\x83\xc8"
167
	"\xbe\x14\x82\x4b\x87\x7a\x74\x28\xd2\xdd\x12\x55\x30\xe6\x0e\x49"
168
	"\x31\x8e\x48\x69\xc5\xc0\x20\x91\xe4\x48\x41\x4c\xd8\xb9\x6a\x4e"
169
	"\x21\xce\x99\x1b\x0e\xfd\x09\x4f\xa1\x79\x0f\x0f\x0f\x0f\x0f\x0f"
170
	"\x0f\x3f\x3c\xb8\x71\x27\xc7\x72\x24\xe8\xb1\xa6\xc5\x7b\x18\xc3"
171
	"\xb1\xa5\xb0\xd4\x98\xee\xe3\x19\xc6\x71\x87\x19\x79\x2b\x6d\x78"
172
	"\xc6\x71\x8c\xe3\x0a\x4e\x71\x8c\xe3\x19\xfe\x38\xf2\x3b\xfb\x8b"
173
	"\x48\xfe\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe1\xfb\x8b\x48\xfe"
174
	"\x4e\xaa\xff\x00\x4f\x08\xff\x00\xc7\xe4\x95\x86\x18\x8a\xcb\x31"
175
	"\xa3\x32\xd4\x78\xf1\xdb\x43\x2c\x47\x61\xb4\x32\xcb\x2c\xb4\x9c"
176
	"\x21\xb6\x99\x69\xbc\x25\xb6\xdb\x6d\x18\xc2\x10\xda\x12\x94\xa1"
177
	"\x38\xc2\x53\x8c\x63\x18\xc7\x9d\xbe\x7f\xff\xd9"
178
	;
(-)php-5.3.9/main/suhosin_patch.c (+470 lines)
Line 0 Link Here
1
/*
2
   +----------------------------------------------------------------------+
3
   | Suhosin Patch for PHP                                                |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 2004-2010 Stefan Esser                                 |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.02 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available at through the world-wide-web at                           |
10
   | http://www.php.net/license/2_02.txt.                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Stefan Esser <sesser@hardened-php.net>                       |
16
   +----------------------------------------------------------------------+
17
 */
18
/* $Id: suhosin_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
19
20
#include "php.h"
21
22
#include <stdio.h>
23
#include <stdlib.h>
24
#include <sys/mman.h>
25
26
#if HAVE_UNISTD_H
27
#include <unistd.h>
28
#endif
29
#include "SAPI.h"
30
#include "php_globals.h"
31
32
#if SUHOSIN_PATCH
33
34
#ifdef HAVE_SYS_SOCKET_H
35
#include <sys/socket.h>
36
#endif
37
38
#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
39
#undef AF_UNIX
40
#endif
41
42
#if defined(AF_UNIX)
43
#include <sys/un.h>
44
#endif
45
46
#define SYSLOG_PATH  "/dev/log"
47
48
#ifdef PHP_WIN32
49
static HANDLE log_source = 0;
50
#endif
51
52
#include "snprintf.h"
53
54
#include "suhosin_patch.h"
55
56
#ifdef ZTS
57
#include "suhosin_globals.h"
58
int suhosin_patch_globals_id;
59
#else
60
struct _suhosin_patch_globals suhosin_patch_globals;
61
#endif
62
63
static char *suhosin_config = NULL;
64
65
static zend_intptr_t SUHOSIN_POINTER_GUARD = 0;
66
67
static void php_security_log(int loglevel, char *fmt, ...);
68
69
static void suhosin_patch_globals_ctor(suhosin_patch_globals_struct *suhosin_patch_globals TSRMLS_DC)
70
{
71
	memset(suhosin_patch_globals, 0, sizeof(*suhosin_patch_globals));
72
}
73
74
ZEND_API char suhosin_get_config(int element)
75
{
76
        return ((char *)SUHOSIN_MANGLE_PTR(suhosin_config))[element];
77
}
78
79
static void suhosin_set_config(int element, char value)
80
{
81
        ((char *)SUHOSIN_MANGLE_PTR(suhosin_config))[element] = value;
82
}
83
84
static void suhosin_read_configuration_from_environment()
85
{
86
        char *tmp;
87
        
88
        /* check if canary protection should be activated or not */
89
        tmp = getenv("SUHOSIN_MM_USE_CANARY_PROTECTION");
90
        /* default to activated */
91
        suhosin_set_config(SUHOSIN_MM_USE_CANARY_PROTECTION, 1);
92
        if (tmp) {
93
                int flag = zend_atoi(tmp, 0);
94
                suhosin_set_config(SUHOSIN_MM_USE_CANARY_PROTECTION, flag);
95
        }
96
        
97
        /* check if free memory should be overwritten with 0xFF or not */
98
        tmp = getenv("SUHOSIN_MM_DESTROY_FREE_MEMORY");
99
        /* default to deactivated */
100
        suhosin_set_config(SUHOSIN_MM_DESTROY_FREE_MEMORY, 0);
101
        if (tmp) {
102
                int flag = zend_atoi(tmp, 0);
103
                suhosin_set_config(SUHOSIN_MM_DESTROY_FREE_MEMORY, flag);
104
        }
105
        
106
        /* check if canary violations should be ignored */
107
        tmp = getenv("SUHOSIN_MM_IGNORE_CANARY_VIOLATION");
108
        /* default to NOT ignore */
109
        suhosin_set_config(SUHOSIN_MM_IGNORE_CANARY_VIOLATION, 0);
110
        if (tmp) {
111
                int flag = zend_atoi(tmp, 0);
112
                suhosin_set_config(SUHOSIN_MM_IGNORE_CANARY_VIOLATION, flag);
113
        }
114
115
        /* check if invalid hashtable destructors should be ignored */
116
        tmp = getenv("SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR");
117
        /* default to NOT ignore */
118
        suhosin_set_config(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR, 0);
119
        if (tmp) {
120
                int flag = zend_atoi(tmp, 0);
121
                suhosin_set_config(SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR, flag);
122
        }
123
124
        /* check if invalid linkedlist destructors should be ignored */
125
        tmp = getenv("SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR");
126
        /* default to NOT ignore */
127
        suhosin_set_config(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR, 0);
128
        if (tmp) {
129
                int flag = zend_atoi(tmp, 0);
130
                suhosin_set_config(SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR, flag);
131
        }
132
        
133
        suhosin_set_config(SUHOSIN_CONFIG_SET, 1);
134
}
135
136
static void suhosin_write_protect_configuration()
137
{
138
        /* check return value of mprotect() to ensure memory is read only now */
139
        if (mprotect(SUHOSIN_MANGLE_PTR(suhosin_config), sysconf(_SC_PAGESIZE), PROT_READ) != 0) {
140
                perror("suhosin");
141
                _exit(1);
142
        }
143
}
144
145
PHPAPI void suhosin_startup()
146
{
147
#ifdef ZTS
148
	ts_allocate_id(&suhosin_patch_globals_id, sizeof(suhosin_patch_globals_struct), (ts_allocate_ctor) suhosin_patch_globals_ctor, NULL);
149
#else
150
	suhosin_patch_globals_ctor(&suhosin_patch_globals TSRMLS_CC);
151
#endif
152
	zend_suhosin_log = php_security_log;
153
	
154
	/* get the pointer guardian and ensure low 3 bits are 1 */
155
        if (SUHOSIN_POINTER_GUARD == 0) {
156
                zend_canary(&SUHOSIN_POINTER_GUARD, sizeof(SUHOSIN_POINTER_GUARD));
157
                SUHOSIN_POINTER_GUARD |= 7;
158
        }
159
	
160
	if (!suhosin_config) {
161
#ifndef MAP_ANONYMOUS
162
#define MAP_ANONYMOUS MAP_ANON
163
#endif
164
		suhosin_config = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
165
		if (suhosin_config == MAP_FAILED) {
166
			perror("suhosin");
167
			_exit(1);
168
		}
169
                suhosin_config = SUHOSIN_MANGLE_PTR(suhosin_config);
170
	}
171
	if (!SUHOSIN_CONFIG(SUHOSIN_CONFIG_SET)) {
172
        suhosin_read_configuration_from_environment();
173
        suhosin_write_protect_configuration();
174
    }
175
}
176
177
static char *loglevel2string(int loglevel)
178
{
179
	switch (loglevel) {
180
	    case S_FILES:
181
		return "FILES";
182
	    case S_INCLUDE:
183
		return "INCLUDE";
184
	    case S_MEMORY:
185
		return "MEMORY";
186
	    case S_MISC:
187
		return "MISC";
188
		case S_SESSION:
189
		return "SESSION";
190
	    case S_SQL:
191
		return "SQL";
192
	    case S_EXECUTOR:
193
		return "EXECUTOR";
194
	    case S_VARS:
195
		return "VARS";
196
	    default:
197
		return "UNKNOWN";    
198
	}
199
}
200
201
static void php_security_log(int loglevel, char *fmt, ...)
202
{
203
	int s, r, i=0;
204
#if defined(AF_UNIX)
205
	struct sockaddr_un saun;
206
#endif
207
#ifdef PHP_WIN32
208
	LPTSTR strs[2];
209
	unsigned short etype;
210
	DWORD evid;
211
#endif
212
	char buf[4096+64];
213
	char error[4096+100];
214
	char *ip_address;
215
	char *fname;
216
	char *alertstring;
217
	int lineno;
218
	va_list ap;
219
	TSRMLS_FETCH();
220
221
	/*SDEBUG("(suhosin_log) loglevel: %d log_syslog: %u - log_sapi: %u - log_script: %u", loglevel, SPG(log_syslog), SPG(log_sapi), SPG(log_script));*/
222
	
223
	if (SPG(log_use_x_forwarded_for)) {
224
		ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
225
		if (ip_address == NULL) {
226
			ip_address = "X-FORWARDED-FOR not set";
227
		}
228
	} else {
229
		ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
230
		if (ip_address == NULL) {
231
			ip_address = "REMOTE_ADDR not set";
232
		}
233
	}
234
	
235
	
236
	va_start(ap, fmt);
237
	ap_php_vsnprintf(error, sizeof(error), fmt, ap);
238
	va_end(ap);
239
	while (error[i]) {
240
		if (error[i] < 32) error[i] = '.';
241
		i++;
242
	}
243
	
244
/*	if (SPG(simulation)) {
245
		alertstring = "ALERT-SIMULATION";
246
	} else { */
247
		alertstring = "ALERT";
248
/*	}*/
249
	
250
	if (zend_is_executing(TSRMLS_C)) {
251
		if (EG(current_execute_data)) {
252
			lineno = EG(current_execute_data)->opline->lineno;
253
			fname = EG(current_execute_data)->op_array->filename;
254
		} else {
255
			lineno = zend_get_executed_lineno(TSRMLS_C);
256
			fname = zend_get_executed_filename(TSRMLS_C);
257
		}
258
		ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno);
259
	} else {
260
		fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
261
		if (fname==NULL) {
262
			fname = "unknown";
263
		}
264
		ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname);
265
	}
266
			
267
	/* Syslog-Logging disabled? */
268
	if (((SPG(log_syslog)|S_INTERNAL) & loglevel)==0) {
269
		goto log_sapi;
270
	}	
271
	
272
#if defined(AF_UNIX)
273
	ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SPG(log_syslog_facility)|SPG(log_syslog_priority)),getpid(),buf);
274
275
	s = socket(AF_UNIX, SOCK_DGRAM, 0);
276
	if (s == -1) {
277
		goto log_sapi;
278
	}
279
	
280
	memset(&saun, 0, sizeof(saun));
281
	saun.sun_family = AF_UNIX;
282
	strcpy(saun.sun_path, SYSLOG_PATH);
283
	/*saun.sun_len = sizeof(saun);*/
284
	
285
	r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
286
	if (r) {
287
		close(s);
288
    		s = socket(AF_UNIX, SOCK_STREAM, 0);
289
		if (s == -1) {
290
			goto log_sapi;
291
		}
292
	
293
		memset(&saun, 0, sizeof(saun));
294
		saun.sun_family = AF_UNIX;
295
		strcpy(saun.sun_path, SYSLOG_PATH);
296
		/*saun.sun_len = sizeof(saun);*/
297
298
		r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
299
		if (r) { 
300
			close(s);
301
			goto log_sapi;
302
		}
303
	}
304
	send(s, error, strlen(error), 0);
305
	
306
	close(s);
307
#endif
308
#ifdef PHP_WIN32
309
	ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf);
310
311
	switch (SPG(log_syslog_priority)) {			/* translate UNIX type into NT type */
312
		case 1: /*LOG_ALERT:*/
313
			etype = EVENTLOG_ERROR_TYPE;
314
			break;
315
		case 6: /*LOG_INFO:*/
316
			etype = EVENTLOG_INFORMATION_TYPE;
317
			break;
318
		default:
319
			etype = EVENTLOG_WARNING_TYPE;
320
	}
321
	evid = loglevel;
322
	strs[0] = error;
323
	/* report the event */
324
	if (log_source == NULL) {
325
		log_source = RegisterEventSource(NULL, "Suhosin-Patch-" SUHOSIN_PATCH_VERSION);
326
	}
327
	ReportEvent(log_source, etype, (unsigned short) SPG(log_syslog_priority), evid, NULL, 1, 0, strs, NULL);
328
	
329
#endif
330
log_sapi:
331
	/* SAPI Logging activated? */
332
	/*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));*/
333
	if (((SPG(log_sapi)|S_INTERNAL) & loglevel)!=0) {
334
		sapi_module.log_message(buf);
335
	}
336
337
/*log_script:*/
338
	/* script logging activaed? */
339
	if (((SPG(log_script) & loglevel)!=0) && SPG(log_scriptname)!=NULL) {
340
		char cmd[8192], *cmdpos, *bufpos;
341
		FILE *in;
342
		int space;
343
		
344
		ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", SPG(log_scriptname), loglevel2string(loglevel));
345
		space = sizeof(cmd) - strlen(cmd);
346
		cmdpos = cmd + strlen(cmd);
347
		bufpos = buf;
348
		if (space <= 1) return;
349
		while (space > 2 && *bufpos) {
350
			if (*bufpos == '\'') {
351
				if (space<=5) break;
352
				*cmdpos++ = '\'';
353
				*cmdpos++ = '\\';
354
				*cmdpos++ = '\'';
355
				*cmdpos++ = '\'';
356
				bufpos++;
357
				space-=4;
358
			} else {
359
				*cmdpos++ = *bufpos++;
360
				space--;
361
			}
362
		}
363
		*cmdpos++ = '\'';
364
		*cmdpos = 0;
365
		
366
		if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
367
			php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", SPG(log_scriptname));
368
			return;
369
		}
370
		/* read and forget the result */
371
		while (1) {
372
			int readbytes = fread(cmd, 1, sizeof(cmd), in);
373
			if (readbytes<=0) {
374
				break;
375
			}
376
		}
377
		pclose(in);
378
	}
379
/*log_phpscript:*/
380
	if ((SPG(log_phpscript) & loglevel)!=0 && EG(in_execution) && SPG(log_phpscriptname) && SPG(log_phpscriptname)[0]) {
381
		zend_file_handle file_handle;
382
		zend_op_array *new_op_array;
383
		zval *result = NULL;
384
		
385
		/*long orig_execution_depth = SPG(execution_depth);*/
386
		zend_bool orig_safe_mode = PG(safe_mode);
387
		char *orig_basedir = PG(open_basedir);
388
		
389
		char *phpscript = SPG(log_phpscriptname);
390
/*SDEBUG("scriptname %s", SPG(log_phpscriptname));`*/
391
#ifdef ZEND_ENGINE_2
392
		if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) {
393
#else
394
		if (zend_open(phpscript, &file_handle) == SUCCESS && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
395
			file_handle.filename = phpscript;
396
			file_handle.free_filename = 0;
397
#endif		
398
			if (!file_handle.opened_path) {
399
				file_handle.opened_path = estrndup(phpscript, strlen(phpscript));
400
			}
401
			new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC);
402
			zend_destroy_file_handle(&file_handle TSRMLS_CC);
403
			if (new_op_array) {
404
				HashTable *active_symbol_table = EG(active_symbol_table);
405
				zval *zerror, *zerror_class;
406
				
407
				if (active_symbol_table == NULL) {
408
					active_symbol_table = &EG(symbol_table);
409
				}
410
				EG(return_value_ptr_ptr) = &result;
411
				EG(active_op_array) = new_op_array;
412
				
413
				MAKE_STD_ZVAL(zerror);
414
				MAKE_STD_ZVAL(zerror_class);
415
				ZVAL_STRING(zerror, buf, 1);
416
				ZVAL_LONG(zerror_class, loglevel);
417
418
				zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL);
419
				zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL);
420
				
421
				/*SPG(execution_depth) = 0;*/
422
				if (SPG(log_phpscript_is_safe)) {
423
					PG(safe_mode) = 0;
424
					PG(open_basedir) = NULL;
425
				}
426
				
427
				zend_execute(new_op_array TSRMLS_CC);
428
				
429
				/*SPG(execution_depth) = orig_execution_depth;*/
430
				PG(safe_mode) = orig_safe_mode;
431
				PG(open_basedir) = orig_basedir;
432
				
433
#ifdef ZEND_ENGINE_2
434
				destroy_op_array(new_op_array TSRMLS_CC);
435
#else
436
				destroy_op_array(new_op_array);
437
#endif
438
				efree(new_op_array);
439
#ifdef ZEND_ENGINE_2
440
				if (!EG(exception))
441
#endif			
442
				{
443
					if (EG(return_value_ptr_ptr)) {
444
						zval_ptr_dtor(EG(return_value_ptr_ptr));
445
						EG(return_value_ptr_ptr) = NULL;
446
					}
447
				}
448
			} else {
449
				php_security_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SPG(log_phpscriptname));
450
				return;
451
			}
452
		} else {
453
			php_security_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SPG(log_phpscriptname));
454
			return;
455
		}
456
	}
457
458
}
459
460
461
#endif
462
463
/*
464
 * Local variables:
465
 * tab-width: 4
466
 * c-basic-offset: 4
467
 * End:
468
 * vim600: sw=4 ts=4 fdm=marker
469
 * vim<600: sw=4 ts=4
470
 */
(-)php-5.3.9/main/suhosin_patch.h (+59 lines)
Line 0 Link Here
1
/*
2
   +----------------------------------------------------------------------+
3
   | Suhosin Patch for PHP                                                |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 2004-2010 Stefan Esser                                 |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.02 of the PHP license,      |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available at through the world-wide-web at                           |
10
   | http://www.php.net/license/2_02.txt.                                 |
11
   | If you did not receive a copy of the PHP license and are unable to   |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@php.net so we can mail you a copy immediately.               |
14
   +----------------------------------------------------------------------+
15
   | Author: Stefan Esser <stefan.esser@sektioneins.de>                   |
16
   +----------------------------------------------------------------------+
17
 */
18
19
#ifndef SUHOSIN_PATCH_H
20
#define SUHOSIN_PATCH_H
21
22
#if SUHOSIN_PATCH
23
24
#include "zend.h"
25
26
#define SUHOSIN_PATCH_VERSION "0.9.10"
27
28
#define SUHOSIN_LOGO_GUID "SUHO8567F54-D428-14d2-A769-00DA302A5F18"
29
30
#define SUHOSIN_CONFIG(idx) (suhosin_get_config(idx))
31
32
#define SUHOSIN_MM_USE_CANARY_PROTECTION        0
33
#define SUHOSIN_MM_DESTROY_FREE_MEMORY          1
34
#define SUHOSIN_MM_IGNORE_CANARY_VIOLATION      2
35
#define SUHOSIN_HT_IGNORE_INVALID_DESTRUCTOR    3
36
#define SUHOSIN_LL_IGNORE_INVALID_DESTRUCTOR    4
37
38
#define SUHOSIN_CONFIG_SET                      100
39
40
#include <sys/types.h>
41
#include <sys/stat.h>
42
#include <sys/mman.h>
43
44
#if defined(DARWIN)
45
#include <mach/vm_param.h>
46
#endif
47
48
#define SUHOSIN_MANGLE_PTR(ptr)   (ptr==NULL?NULL:((void *)((zend_intptr_t)(ptr)^SUHOSIN_POINTER_GUARD)))
49
50
#endif
51
52
#endif /* SUHOSIN_PATCH_H */
53
54
/*
55
 * Local variables:
56
 * tab-width: 4
57
 * c-basic-offset: 4
58
 * End:
59
 */
(-)php-5.3.9/main/suhosin_patch.m4 (+8 lines)
Line 0 Link Here
1
dnl
2
dnl $Id: suhosin_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
3
dnl
4
dnl This file contains Suhosin Patch for PHP specific autoconf functions.
5
dnl
6
7
AC_DEFINE(SUHOSIN_PATCH, 1, [Suhosin Patch])
8
(-)php-5.3.9/sapi/apache/mod_php5.c (+4 lines)
Lines 969-975 Link Here
969
	{
969
	{
970
		TSRMLS_FETCH();
970
		TSRMLS_FETCH();
971
		if (PG(expose_php)) {
971
		if (PG(expose_php)) {
972
#if SUHOSIN_PATCH
973
			ap_add_version_component("PHP/" PHP_VERSION " with Suhosin-Patch");
974
#else
972
			ap_add_version_component("PHP/" PHP_VERSION);
975
			ap_add_version_component("PHP/" PHP_VERSION);
976
#endif
973
		}
977
		}
974
	}
978
	}
975
#endif
979
#endif
(-)php-5.3.9/sapi/apache2filter/sapi_apache2.c (+4 lines)
Lines 583-589 Link Here
583
{
583
{
584
	TSRMLS_FETCH();
584
	TSRMLS_FETCH();
585
	if (PG(expose_php)) {
585
	if (PG(expose_php)) {
586
#if SUHOSIN_PATCH
587
		ap_add_version_component(p, "PHP/" PHP_VERSION " with Suhosin-Patch");
588
#else
586
		ap_add_version_component(p, "PHP/" PHP_VERSION);
589
		ap_add_version_component(p, "PHP/" PHP_VERSION);
590
#endif
587
	}
591
	}
588
}
592
}
589
593
(-)php-5.3.9/sapi/apache2handler/sapi_apache2.c (+4 lines)
Lines 407-413 Link Here
407
{
407
{
408
	TSRMLS_FETCH();
408
	TSRMLS_FETCH();
409
	if (PG(expose_php)) {
409
	if (PG(expose_php)) {
410
#if SUHOSIN_PATCH
411
		ap_add_version_component(p, "PHP/" PHP_VERSION " with Suhosin-Patch");
412
#else
410
		ap_add_version_component(p, "PHP/" PHP_VERSION);
413
		ap_add_version_component(p, "PHP/" PHP_VERSION);
414
#endif
411
	}
415
	}
412
}
416
}
413
417
(-)php-5.3.9/sapi/apache_hooks/mod_php5.c (+4 lines)
Lines 1256-1262 Link Here
1256
	{
1256
	{
1257
		TSRMLS_FETCH();
1257
		TSRMLS_FETCH();
1258
		if (PG(expose_php)) {
1258
		if (PG(expose_php)) {
1259
#if SUHOSIN_PATCH
1260
			ap_add_version_component("PHP/" PHP_VERSION " with Suhosin-Patch");
1261
#else
1259
			ap_add_version_component("PHP/" PHP_VERSION);
1262
			ap_add_version_component("PHP/" PHP_VERSION);
1263
#endif
1260
		}
1264
		}
1261
	}
1265
	}
1262
#endif
1266
#endif
(-)php-5.3.9/sapi/cgi/cgi_main.c (+8 lines)
Lines 1936-1946 Link Here
1936
								SG(headers_sent) = 1;
1936
								SG(headers_sent) = 1;
1937
								SG(request_info).no_headers = 1;
1937
								SG(request_info).no_headers = 1;
1938
							}
1938
							}
1939
#if SUHOSIN_PATCH
1940
#if ZEND_DEBUG
1941
							php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1942
#else
1943
							php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1944
#endif
1945
#else
1939
#if ZEND_DEBUG
1946
#if ZEND_DEBUG
1940
							php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1947
							php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1941
#else
1948
#else
1942
							php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1949
							php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1943
#endif
1950
#endif
1951
#endif
1944
							php_request_shutdown((void *) 0);
1952
							php_request_shutdown((void *) 0);
1945
							fcgi_shutdown();
1953
							fcgi_shutdown();
1946
							exit_status = 0;
1954
							exit_status = 0;
(-)php-5.3.9/sapi/cli/php_cli.c (-1 / +5 lines)
Lines 826-832 Link Here
826
				}
826
				}
827
827
828
				request_started = 1;
828
				request_started = 1;
829
				php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2012 The PHP Group\n%s",
829
				php_printf("PHP %s "
830
#if SUHOSIN_PATCH
831
					"with Suhosin-Patch "
832
#endif
833
					"(%s) (built: %s %s) %s\nCopyright (c) 1997-2012 The PHP Group\n%s",
830
					PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
834
					PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
831
#if ZEND_DEBUG && defined(HAVE_GCOV)
835
#if ZEND_DEBUG && defined(HAVE_GCOV)
832
					"(DEBUG GCOV)",
836
					"(DEBUG GCOV)",
(-)php-5.3.9/sapi/litespeed/lsapi_main.c (+8 lines)
Lines 718-728 Link Here
718
                break;
718
                break;
719
            case 'v':
719
            case 'v':
720
                if (php_request_startup(TSRMLS_C) != FAILURE) {
720
                if (php_request_startup(TSRMLS_C) != FAILURE) {
721
#if SUHOSIN_PATCH
722
  #if ZEND_DEBUG
723
					php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
724
  #else
725
					php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2011 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
726
  #endif
727
#else					
721
#if ZEND_DEBUG
728
#if ZEND_DEBUG
722
                    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());
729
                    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());
723
#else
730
#else
724
                    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());
731
                    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());
725
#endif
732
#endif
733
#endif
726
#ifdef PHP_OUTPUT_NEWAPI
734
#ifdef PHP_OUTPUT_NEWAPI
727
                    php_output_end_all(TSRMLS_C);
735
                    php_output_end_all(TSRMLS_C);
728
#else
736
#else
(-)php-5.3.9/sapi/milter/php_milter.c (+4 lines)
Lines 1111-1117 Link Here
1111
				}
1111
				}
1112
				SG(headers_sent) = 1;
1112
				SG(headers_sent) = 1;
1113
				SG(request_info).no_headers = 1;
1113
				SG(request_info).no_headers = 1;
1114
#if SUHOSIN_PATCH
1115
				php_printf("PHP %s with Suhosin-Patch (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1116
#else
1114
				php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1117
				php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2012 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
1118
#endif
1115
				php_end_ob_buffers(1 TSRMLS_CC);
1119
				php_end_ob_buffers(1 TSRMLS_CC);
1116
				exit(1);
1120
				exit(1);
1117
				break;
1121
				break;
(-)php-5.3.9/win32/build/config.w32 (-1 / +2 lines)
Lines 328-334 Link Here
328
	zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
328
	zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
329
	zend_object_handlers.c zend_objects_API.c \
329
	zend_object_handlers.c zend_objects_API.c \
330
	zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
330
	zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
331
	zend_float.c");
331
	zend_float.c zend_canary.c zend_alloc_canary.c");
332
332
333
if (VCVERS == 1200) {
333
if (VCVERS == 1200) {
334
	AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
334
	AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
Lines 385-390 Link Here
385
 
385
 
386
AC_DEFINE('HAVE_USLEEP', 1);
386
AC_DEFINE('HAVE_USLEEP', 1);
387
AC_DEFINE('HAVE_STRCOLL', 1);
387
AC_DEFINE('HAVE_STRCOLL', 1);
388
AC_DEFINE('SUHOSIN_PATCH', 1);
388
389
389
/* For snapshot builders, where can we find the additional
390
/* For snapshot builders, where can we find the additional
390
 * files that make up the snapshot template? */
391
 * files that make up the snapshot template? */
(-)php-5.3.9/win32/build/config.w32.h.in (+3 lines)
Lines 152-157 Link Here
152
/* Win32 supports strcoll */
152
/* Win32 supports strcoll */
153
#define HAVE_STRCOLL 1
153
#define HAVE_STRCOLL 1
154
154
155
/* Suhosin Patch support */
156
#define SUHOSIN_PATCH 1
157
155
/* Win32 supports socketpair by the emulation in win32/sockets.c */
158
/* Win32 supports socketpair by the emulation in win32/sockets.c */
156
#define HAVE_SOCKETPAIR 1
159
#define HAVE_SOCKETPAIR 1
157
#define HAVE_SOCKLEN_T 1
160
#define HAVE_SOCKLEN_T 1

Return to bug 411935