packages: php/suhosin.patch (NEW) - decompressed from http://download.suhos...

glen glen at pld-linux.org
Tue May 19 13:15:42 CEST 2009


Author: glen                         Date: Tue May 19 11:15:42 2009 GMT
Module: packages                      Tag: HEAD
---- Log message:
- decompressed from http://download.suhosin.org/suhosin-patch-5.2.9-0.9.7.patch.gz

---- Files affected:
packages/php:
   suhosin.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: packages/php/suhosin.patch
diff -u /dev/null packages/php/suhosin.patch:1.1
--- /dev/null	Tue May 19 13:15:42 2009
+++ packages/php/suhosin.patch	Tue May 19 13:15:37 2009
@@ -0,0 +1,2639 @@
+diff -Nura php-5.2.9/TSRM/TSRM.h suhosin-patch-5.2.9-0.9.7/TSRM/TSRM.h
+--- php-5.2.9/TSRM/TSRM.h	2008-12-31 12:17:31.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/TSRM/TSRM.h	2009-03-05 21:11:35.000000000 +0100
+@@ -38,6 +38,13 @@
+ typedef unsigned long tsrm_uintptr_t;
+ #endif
+ 
++#if SUHOSIN_PATCH
++# if HAVE_REALPATH
++#  undef realpath
++#  define realpath php_realpath
++# endif
++#endif
++
+ /* Only compile multi-threading functions if we're in ZTS mode */
+ #ifdef ZTS
+ 
+@@ -93,6 +100,7 @@
+ 
+ #define THREAD_HASH_OF(thr,ts)  (unsigned long)thr%(unsigned long)ts
+ 
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+diff -Nura php-5.2.9/TSRM/tsrm_virtual_cwd.c suhosin-patch-5.2.9-0.9.7/TSRM/tsrm_virtual_cwd.c
+--- php-5.2.9/TSRM/tsrm_virtual_cwd.c	2008-12-31 12:17:31.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/TSRM/tsrm_virtual_cwd.c	2009-03-05 21:37:36.000000000 +0100
+@@ -273,6 +273,191 @@
+ }
+ /* }}} */
+ 
++#if SUHOSIN_PATCH
++CWD_API char *php_realpath(const char *path, char *resolved)
++{
++     struct stat sb;
++     char *p, *q, *s;
++     size_t left_len, resolved_len;
++     unsigned symlinks;
++     int serrno, slen;
++     int is_dir = 1;
++     char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
++
++     serrno = errno;
++     symlinks = 0;
++     if (path[0] == '/') {
++             resolved[0] = '/';
++             resolved[1] = '\0';
++             if (path[1] == '\0')
++                 return (resolved);
++             resolved_len = 1;
++             left_len = strlcpy(left, path + 1, sizeof(left));
++     } else {
++             if (getcwd(resolved, PATH_MAX) == NULL) {
++                     strlcpy(resolved, ".", PATH_MAX);
++                     return (NULL);
++             }
++             resolved_len = strlen(resolved);
++             left_len = strlcpy(left, path, sizeof(left));
++     }
++     if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
++             errno = ENAMETOOLONG;
++             return (NULL);
++     }
++
++     /*
++      * Iterate over path components in `left'.
++      */
++     while (left_len != 0) {
++             /*
++              * Extract the next path component and adjust `left'
++              * and its length.
++              */
++             p = strchr(left, '/');
++             s = p ? p : left + left_len;
++             if (s - left >= sizeof(next_token)) {
++                     errno = ENAMETOOLONG;
++                     return (NULL);
++             }
++             memcpy(next_token, left, s - left);
++             next_token[s - left] = '\0';
++             left_len -= s - left;
++             if (p != NULL)
++                     memmove(left, s + 1, left_len + 1);
++             if (resolved[resolved_len - 1] != '/') {
++                     if (resolved_len + 1 >= PATH_MAX) {
++                             errno = ENAMETOOLONG;
++                             return (NULL);
++                     }
++                     resolved[resolved_len++] = '/';
++                     resolved[resolved_len] = '\0';
++             }
++             if (next_token[0] == '\0')
++                     continue;
++             else if (strcmp(next_token, ".") == 0){
++                     if (!is_dir) {
++                             resolved_len = strlcat(resolved, "#", PATH_MAX);
++                             if (resolved_len >= PATH_MAX) {
++                                     errno = ENAMETOOLONG;
++                                     return (NULL);
++                             }
++                             return resolved;
++                     }
++                     continue;
++             } else if (strcmp(next_token, "..") == 0) {
++                     /*
++                      * Strip the last path component except when we have
++                      * single "/"
++                      */
++                     if (!is_dir) {
++                             errno = ENOENT;
++                             return (NULL);
++                     }
++                     if (resolved_len > 1) {
++                             resolved[resolved_len - 1] = '\0';
++                             q = strrchr(resolved, '/');
++                             *q = '\0';
++                             resolved_len = q - resolved;
++                     }
++                     continue;
++             }
++
++             /*
++              * Append the next path component and lstat() it. If
++              * lstat() fails we still can return successfully if
++              * there are no more path components left.
++              */
++             resolved_len = strlcat(resolved, next_token, PATH_MAX);
++             if (resolved_len >= PATH_MAX) {
++                     errno = ENAMETOOLONG;
++                     return (NULL);
++             }
++             if (lstat(resolved, &sb) != 0) {
++                     if (errno == ENOENT) {
++		     if (p == NULL) {
++	         		errno = serrno;
++				return NULL;
++                     		return (resolved);
++    			} /*else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
++         				resolved_len = strlcat(resolved, "/", PATH_MAX);
++         				resolved_len = strlcat(resolved, left, PATH_MAX);
++         				if (resolved_len >= PATH_MAX) {
++                 				errno = ENAMETOOLONG;
++                 				return (NULL);
++         				}
++                         		errno = serrno;
++                         		return (resolved);
++				} */
++                     }
++                     return (NULL);
++             }
++             if (S_ISLNK(sb.st_mode)) {
++                     if (symlinks++ > MAXSYMLINKS) {
++                             errno = ELOOP;
++                             return (NULL);
++            	     }
++                     slen = readlink(resolved, symlink, sizeof(symlink) - 1);
++                     if (slen < 0)
++                             return (NULL);
++                     symlink[slen] = '\0';
++                     if (symlink[0] == '/') {
++                             resolved[1] = 0;
++                             resolved_len = 1;
++                     } else if (resolved_len > 1) {
++                             /* Strip the last path component. */
++                             resolved[resolved_len - 1] = '\0';
++                             q = strrchr(resolved, '/');
++                             *q = '\0';
++                             resolved_len = q - resolved;
++                     }
++
++                     /*
++                      * If there are any path components left, then
++                      * append them to symlink. The result is placed
++                      * in `left'.
++                      */
++                     if (p != NULL) {
++                             if (symlink[slen - 1] != '/') {
++                                     if (slen + 1 >= sizeof(symlink)) {
++                                             errno = ENAMETOOLONG;
++                                             return (NULL);
++                                     }
++                                     symlink[slen] = '/';
++                                     symlink[slen + 1] = 0;
++                             }
++                             left_len = strlcat(symlink, left, sizeof(left));
++                             if (left_len >= sizeof(left)) {
++                                     errno = ENAMETOOLONG;
++                                     return (NULL);
++                             }
++                     }
++                     left_len = strlcpy(left, symlink, sizeof(left));
++             } else {
++         		if (S_ISDIR(sb.st_mode)) {
++                 		is_dir = 1;
++         		} else {
++                 		is_dir = 0;
++         		}
++	    }
++     }
++
++     /*
++      * Remove trailing slash except when the resolved pathname
++      * is a single "/".
++      */
++     if (resolved_len > 1 && resolved[resolved_len - 1] == '/') {
++             if (!is_dir) {
++                     errno = ENOENT;
++                     return (NULL);
++             }
++             resolved[resolved_len - 1] = '\0';
++     }
++     return (resolved);
++}
++#endif
++
++
+ CWD_API void virtual_cwd_startup(void) /* {{{ */
+ {
+ 	char cwd[MAXPATHLEN];
+diff -Nura php-5.2.9/TSRM/tsrm_virtual_cwd.h suhosin-patch-5.2.9-0.9.7/TSRM/tsrm_virtual_cwd.h
+--- php-5.2.9/TSRM/tsrm_virtual_cwd.h	2008-12-31 12:17:32.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/TSRM/tsrm_virtual_cwd.h	2009-03-05 21:11:35.000000000 +0100
+@@ -139,6 +139,22 @@
+ 
+ typedef int (*verify_path_func)(const cwd_state *);
+ 
++#ifndef HAVE_STRLCPY
++CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
++#undef strlcpy
++#define strlcpy php_strlcpy
++#endif
++
++#ifndef HAVE_STRLCAT
++CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
++#undef strlcat
++#define strlcat php_strlcat
++#endif
++
++
++#if SUHOSIN_PATCH
++CWD_API char *php_realpath(const char *path, char *resolved);
++#endif
+ CWD_API void virtual_cwd_startup(void);
+ CWD_API void virtual_cwd_shutdown(void);
+ CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
+diff -Nura php-5.2.9/Zend/Makefile.am suhosin-patch-5.2.9-0.9.7/Zend/Makefile.am
+--- php-5.2.9/Zend/Makefile.am	2006-12-05 09:07:57.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/Makefile.am	2009-03-05 21:11:35.000000000 +0100
+@@ -17,7 +17,7 @@
+ 	zend_objects_API.c zend_ts_hash.c zend_stream.c \
+ 	zend_default_classes.c \
+ 	zend_iterators.c zend_interfaces.c zend_exceptions.c \
+-	zend_strtod.c zend_multibyte.c
++	zend_strtod.c zend_multibyte.c zend_canary.c
+ 
+ libZend_la_LDFLAGS =
+ libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
+diff -Nura php-5.2.9/Zend/Zend.dsp suhosin-patch-5.2.9-0.9.7/Zend/Zend.dsp
+--- php-5.2.9/Zend/Zend.dsp	2006-12-05 09:07:57.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/Zend.dsp	2009-03-05 21:15:17.000000000 +0100
+@@ -239,6 +239,10 @@
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=.\zend_canary.c
++# End Source File
++# Begin Source File
++
+ SOURCE=.\zend_ts_hash.c
+ # End Source File
+ # Begin Source File
+diff -Nura php-5.2.9/Zend/ZendTS.dsp suhosin-patch-5.2.9-0.9.7/Zend/ZendTS.dsp
+--- php-5.2.9/Zend/ZendTS.dsp	2006-12-05 09:07:57.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/ZendTS.dsp	2009-03-05 21:15:17.000000000 +0100
+@@ -273,6 +273,10 @@
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=.\zend_canary.c
++# End Source File
++# Begin Source File
++
+ SOURCE=.\zend_ts_hash.c
+ # End Source File
+ # Begin Source File
+diff -Nura php-5.2.9/Zend/zend.c suhosin-patch-5.2.9-0.9.7/Zend/zend.c
+--- php-5.2.9/Zend/zend.c	2008-12-31 12:17:32.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/zend.c	2009-03-05 21:11:35.000000000 +0100
+@@ -57,7 +57,9 @@
+ ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
+ int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
+ ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
+-
++#if SUHOSIN_PATCH
++ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
++#endif
+ void (*zend_on_timeout)(int seconds TSRMLS_DC);
+ 
+ static void (*zend_message_dispatcher_p)(long message, void *data);
+@@ -74,9 +76,88 @@
+ 	return SUCCESS;
+ }
+ 
++#if SUHOSIN_PATCH
++static ZEND_INI_MH(OnUpdateSuhosin_log_syslog)
++{
++	if (!new_value) {
++		SPG(log_syslog) = S_ALL & ~S_SQL | S_MEMORY;
++	} else {
++		SPG(log_syslog) = atoi(new_value) | S_MEMORY;
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_facility)
++{
++	if (!new_value) {
++		SPG(log_syslog_facility) = LOG_USER;
++	} else {
++		SPG(log_syslog_facility) = atoi(new_value);
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_syslog_priority)
++{
++	if (!new_value) {
++		SPG(log_syslog_priority) = LOG_ALERT;
++	} else {
++		SPG(log_syslog_priority) = atoi(new_value);
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_sapi)
++{
++	if (!new_value) {
++		SPG(log_sapi) = S_ALL & ~S_SQL;
++	} else {
++		SPG(log_sapi) = atoi(new_value);
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_script)
++{
++	if (!new_value) {
++		SPG(log_script) = S_ALL & ~S_MEMORY;
++	} else {
++		SPG(log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_scriptname)
++{
++	if (SPG(log_scriptname)) {
++		pefree(SPG(log_scriptname),1);
++	}
++        SPG(log_scriptname) = NULL;
++	if (new_value) {
++		SPG(log_scriptname) = pestrdup(new_value,1);
++	}
++	return SUCCESS;
++}
++static ZEND_INI_MH(OnUpdateSuhosin_log_phpscript)
++{
++	if (!new_value) {
++		SPG(log_phpscript) = S_ALL & ~S_MEMORY;
++	} else {
++		SPG(log_phpscript) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
++	}
++	return SUCCESS;
++}
++#endif
+ 
+ ZEND_INI_BEGIN()
+ 	ZEND_INI_ENTRY("error_reporting",				NULL,		ZEND_INI_ALL,		OnUpdateErrorReporting)
++#if SUHOSIN_PATCH
++	ZEND_INI_ENTRY("suhosin.log.syslog",			NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_syslog)
++	ZEND_INI_ENTRY("suhosin.log.syslog.facility",		NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_syslog_facility)
++	ZEND_INI_ENTRY("suhosin.log.syslog.priority",		NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_syslog_priority)
++	ZEND_INI_ENTRY("suhosin.log.sapi",				NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_sapi)
++	ZEND_INI_ENTRY("suhosin.log.script",			NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_script)
++	ZEND_INI_ENTRY("suhosin.log.script.name",			NULL,		ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_scriptname)
++	STD_ZEND_INI_BOOLEAN("suhosin.log.use-x-forwarded-for",	"0",		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateBool, log_use_x_forwarded_for,	suhosin_patch_globals_struct,	suhosin_patch_globals)
++	ZEND_INI_ENTRY("suhosin.log.phpscript",			"0",		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateSuhosin_log_phpscript)
++	STD_ZEND_INI_ENTRY("suhosin.log.phpscript.name",			NULL,		ZEND_INI_PERDIR|ZEND_INI_SYSTEM,	OnUpdateString, log_phpscriptname, suhosin_patch_globals_struct,	suhosin_patch_globals)
++	STD_ZEND_INI_BOOLEAN("suhosin.log.phpscript.is_safe",			"0",		ZEND_INI_SYSTEM,	OnUpdateBool, log_phpscript_is_safe,	suhosin_patch_globals_struct,	suhosin_patch_globals)
++#endif
+ 	STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode",	"0",	ZEND_INI_ALL,		OnUpdateBool,	ze1_compatibility_mode,	zend_executor_globals,	executor_globals)
+ #ifdef ZEND_MULTIBYTE
+ 	STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
+diff -Nura php-5.2.9/Zend/zend.h suhosin-patch-5.2.9-0.9.7/Zend/zend.h
+--- php-5.2.9/Zend/zend.h	2008-12-31 12:17:32.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/zend.h	2009-03-05 21:11:35.000000000 +0100
+@@ -532,6 +532,9 @@
+ extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
+ extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
+ extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
++#if SUHOSIN_PATCH
++extern ZEND_API void (*zend_suhosin_log)(int loglevel, char *fmt, ...);
++#endif
+ 
+ 
+ ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
+@@ -663,6 +666,13 @@
+ #include "zend_operators.h"
+ #include "zend_variables.h"
+ 
++#if SUHOSIN_PATCH
++#include "suhosin_globals.h"
++#include "php_syslog.h"
++
++ZEND_API size_t zend_canary();
++#endif
++
+ #endif /* ZEND_H */
+ 
+ /*
+diff -Nura php-5.2.9/Zend/zend_alloc.c suhosin-patch-5.2.9-0.9.7/Zend/zend_alloc.c
+--- php-5.2.9/Zend/zend_alloc.c	2009-01-25 15:04:09.000000000 +0100
++++ suhosin-patch-5.2.9-0.9.7/Zend/zend_alloc.c	2009-03-05 21:11:35.000000000 +0100
+@@ -311,13 +311,26 @@
+ #define	MEM_BLOCK_GUARD  0x2A8FCC84
+ #define	MEM_BLOCK_LEAK   0x6C5E8F2D
+ 
++#if SUHOSIN_PATCH
++# define CANARY_SIZE sizeof(size_t)
++#else
++# define CANARY_SIZE 0
++#endif
++
+ /* mm block type */
+ typedef struct _zend_mm_block_info {
+ #if ZEND_MM_COOKIES
+ 	size_t _cookie;
+ #endif
+-	size_t _size;
+-	size_t _prev;
++#if SUHOSIN_PATCH
++	size_t canary_1;
++#endif
++  	size_t _size;
++  	size_t _prev;
++#if SUHOSIN_PATCH
++	size_t size;
++	size_t canary_2;
++#endif
+ } zend_mm_block_info;
+ 
+ #if ZEND_DEBUG
+@@ -423,6 +436,9 @@
+ 		int miss;
+ 	} cache_stat[ZEND_MM_NUM_BUCKETS+1];
+ #endif
++#if SUHOSIN_PATCH
++	size_t              canary_1,canary_2,canary_3;
++#endif
+ };
+ 
+ #define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
+@@ -512,15 +528,15 @@
+ #define ZEND_MM_ALIGNED_SIZE(size)			((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
+ #define ZEND_MM_ALIGNED_HEADER_SIZE			ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block))
+ #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE	ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block))
+-#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE		ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE)
++#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE		ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE + CANARY_SIZE)
+ #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)
+ #define ZEND_MM_ALIGNED_SEGMENT_SIZE		ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
+ 
+-#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)
++#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)
+ 
+ #define ZEND_MM_MAX_SMALL_SIZE				((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
+ 
+-#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)))
++#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)))
+ 
+ #define ZEND_MM_BUCKET_INDEX(true_size)		((true_size>>ZEND_MM_ALIGNMENT_LOG2)-(ZEND_MM_ALIGNED_MIN_HEADER_SIZE>>ZEND_MM_ALIGNMENT_LOG2))
+ 
+@@ -582,6 +598,48 @@
+ 
+ #endif
+ 
++#if SUHOSIN_PATCH
++
++# define SUHOSIN_MM_CHECK_CANARIES(block, MFUNCTION) do { \
++        char *p = SUHOSIN_MM_END_CANARY_PTR(block); size_t check; \
++		if (((block)->info.canary_1 != heap->canary_1) || ((block)->info.canary_2 != heap->canary_2)) { \
++			canary_mismatch: \
++            zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected"); \
++            exit(1); \
++		} \
++        memcpy(&check, p, CANARY_SIZE); \
++        if (check != heap->canary_3) { \
++            zend_suhosin_log(S_MEMORY, "canary mismatch on " MFUNCTION " - heap overflow detected"); \
++            exit(1); \
++            goto canary_mismatch; \
++        } \
++	} while (0)
++
++# define SUHOSIN_MM_SET_CANARIES(block) do { \
++      (block)->info.canary_1 = heap->canary_1; \
++      (block)->info.canary_2 = heap->canary_2; \
++    } while (0)      
++
++# define SUHOSIN_MM_END_CANARY_PTR(block) \
++	(char *)(((char*)(ZEND_MM_DATA_OF(block))) + ((zend_mm_block*)(block))->info.size + END_MAGIC_SIZE)
++
++# define SUHOSIN_MM_SET_END_CANARY(block) do { \
++		char *p = SUHOSIN_MM_END_CANARY_PTR(block); \
++		memcpy(p, &heap->canary_3, CANARY_SIZE); \
++	} while (0)
++
++#else
++
++# define SUHOSIN_MM_CHECK_CANARIES(block)
++
++# define SUHOSIN_MM_SET_CANARIES(block)
++
++# define SUHOSIN_MM_END_CANARY_PTR(block)
++
++# define SUHOSIN_MM_SET_END_CANARY(block)
++
++#endif
++
+ 
+ #if ZEND_MM_HEAP_PROTECTION
+ 
+@@ -790,6 +848,12 @@
+ 	if (EXPECTED(prev == mm_block)) {
+ 		zend_mm_free_block **rp, **cp;
+ 
++#if SUHOSIN_PATCH
++        if (next != mm_block) {
++ 		    zend_suhosin_log(S_MEMORY, "heap corrupt on efree() - heap corruption detected");
++		    exit(1);
++        }
++#endif
+ #if ZEND_MM_SAFE_UNLINKING
+ 		if (UNEXPECTED(next != mm_block)) {
+ 			zend_mm_panic("zend_mm_heap corrupted");
+@@ -828,6 +892,12 @@
+ 		}
+ 	} else {
+ 
++#if SUHOSIN_PATCH
++        if (prev->next_free_block != mm_block || next->prev_free_block != mm_block) {
++ 		    zend_suhosin_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected");
++		    exit(1);
++        }
++#endif    
+ #if ZEND_MM_SAFE_UNLINKING
+ 		if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block != mm_block)) {
+ 			zend_mm_panic("zend_mm_heap corrupted");
+@@ -875,6 +945,11 @@
+ 		heap->large_free_buckets[i] = NULL;
+ 	}
+ 	heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
++#if SUHOSIN_PATCH
++	heap->canary_1 = zend_canary();
++	heap->canary_2 = zend_canary();
++	heap->canary_3 = zend_canary();
++#endif    
+ }
+ 
+ static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
+@@ -1779,6 +1854,11 @@
+ 			best_fit = heap->cache[index];
+ 			heap->cache[index] = best_fit->prev_free_block;
+ 			heap->cached -= true_size;
++#if SUHOSIN_PATCH
++            SUHOSIN_MM_SET_CANARIES(best_fit);
++            ((zend_mm_block*)best_fit)->info.size = size;
++            SUHOSIN_MM_SET_END_CANARY(best_fit);
++#endif
+ 			ZEND_MM_CHECK_MAGIC(best_fit, MEM_BLOCK_CACHED);
+ 			ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 0);
+ 			return ZEND_MM_DATA_OF(best_fit);
+@@ -1918,6 +1998,12 @@
+ 
+ 	ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);
+ 
++#if SUHOSIN_PATCH
++    SUHOSIN_MM_SET_CANARIES(best_fit);
++    ((zend_mm_block*)best_fit)->info.size = size;
++    SUHOSIN_MM_SET_END_CANARY(best_fit);
++#endif
++
+ 	heap->size += true_size;
+ 	if (heap->peak < heap->size) {
+ 		heap->peak = heap->size;
+@@ -1941,6 +2027,9 @@
+ 
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list