summaryrefslogtreecommitdiff
path: root/0.2.7
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:35:52 +0200
committerjvoisin2019-10-13 12:35:52 +0200
commit7ce0f98b0be3ad15a664e506dff461cf6d633a69 (patch)
tree1aae4c7d8fa8ac62609824629db9ba46add728cc /0.2.7
parentd24fe97bf9a1614acf4e7431d17b762a73642e15 (diff)
Add more patches
Diffstat (limited to '0.2.7')
-rw-r--r--0.2.7/hardened-php-4.3.10-0.2.7.patch5918
-rw-r--r--0.2.7/hardened-php-4.3.11-0.2.7.patch3417
-rw-r--r--0.2.7/hardened-php-5.0.4-0.2.7.patch3100
3 files changed, 12435 insertions, 0 deletions
diff --git a/0.2.7/hardened-php-4.3.10-0.2.7.patch b/0.2.7/hardened-php-4.3.10-0.2.7.patch
new file mode 100644
index 0000000..cb5c546
--- /dev/null
+++ b/0.2.7/hardened-php-4.3.10-0.2.7.patch
@@ -0,0 +1,5918 @@
1diff -Nur php-4.3.10/README.input_filter hardened-php-4.3.10-0.2.7/README.input_filter
2--- php-4.3.10/README.input_filter 1970-01-01 01:00:00.000000000 +0100
3+++ hardened-php-4.3.10-0.2.7/README.input_filter 2005-04-07 01:51:16.000000000 +0200
4@@ -0,0 +1,193 @@
5+Input Filter Support ported from PHP 5
6+--------------------------------------
7+
8+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
9+and can be quite difficult to prevent. Whenever you accept user data
10+and somehow display this data back to users, you are likely vulnerable
11+to XSS hacks.
12+
13+The Input Filter support in PHP 5 is aimed at providing the framework
14+through which a company-wide or site-wide security policy can be
15+enforced. It is implemented as a SAPI hook and is called from the
16+treat_data and post handler functions. To implement your own security
17+policy you will need to write a standard PHP extension.
18+
19+A simple implementation might look like the following. This stores the
20+original raw user data and adds a my_get_raw() function while the normal
21+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
22+data. In this simple example all I am doing is calling strip_tags() on
23+the data. If register_globals is turned on, the default globals that
24+are created will be stripped ($foo) while a $RAW_foo is created with the
25+original user input.
26+
27+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
28+ zval *post_array;
29+ zval *get_array;
30+ zval *cookie_array;
31+ZEND_END_MODULE_GLOBALS(my_input_filter)
32+
33+#ifdef ZTS
34+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
35+#else
36+#define IF_G(v) (my_input_filter_globals.v)
37+#endif
38+
39+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
40+
41+function_entry my_input_filter_functions[] = {
42+ PHP_FE(my_get_raw, NULL)
43+ {NULL, NULL, NULL}
44+};
45+
46+zend_module_entry my_input_filter_module_entry = {
47+ STANDARD_MODULE_HEADER,
48+ "my_input_filter",
49+ my_input_filter_functions,
50+ PHP_MINIT(my_input_filter),
51+ PHP_MSHUTDOWN(my_input_filter),
52+ NULL,
53+ PHP_RSHUTDOWN(my_input_filter),
54+ PHP_MINFO(my_input_filter),
55+ "0.1",
56+ STANDARD_MODULE_PROPERTIES
57+};
58+
59+PHP_MINIT_FUNCTION(my_input_filter)
60+{
61+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
62+
63+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
64+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
65+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
66+
67+ sapi_register_input_filter(my_sapi_input_filter);
68+ return SUCCESS;
69+}
70+
71+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
72+{
73+ if(IF_G(get_array)) {
74+ zval_ptr_dtor(&IF_G(get_array));
75+ IF_G(get_array) = NULL;
76+ }
77+ if(IF_G(post_array)) {
78+ zval_ptr_dtor(&IF_G(post_array));
79+ IF_G(post_array) = NULL;
80+ }
81+ if(IF_G(cookie_array)) {
82+ zval_ptr_dtor(&IF_G(cookie_array));
83+ IF_G(cookie_array) = NULL;
84+ }
85+ return SUCCESS;
86+}
87+
88+PHP_MINFO_FUNCTION(my_input_filter)
89+{
90+ php_info_print_table_start();
91+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
92+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
93+ php_info_print_table_end();
94+}
95+
96+/* The filter handler. If you return 1 from it, then PHP also registers the
97+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
98+ * you can use this if your filter already registers the variable under a
99+ * different name, or if you just don't want the variable registered at all. */
100+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
101+{
102+ zval new_var;
103+ zval *array_ptr = NULL;
104+ char *raw_var;
105+ int var_len;
106+
107+ assert(*val != NULL);
108+
109+ switch(arg) {
110+ case PARSE_GET:
111+ if(!IF_G(get_array)) {
112+ ALLOC_ZVAL(array_ptr);
113+ array_init(array_ptr);
114+ INIT_PZVAL(array_ptr);
115+ }
116+ IF_G(get_array) = array_ptr;
117+ break;
118+ case PARSE_POST:
119+ if(!IF_G(post_array)) {
120+ ALLOC_ZVAL(array_ptr);
121+ array_init(array_ptr);
122+ INIT_PZVAL(array_ptr);
123+ }
124+ IF_G(post_array) = array_ptr;
125+ break;
126+ case PARSE_COOKIE:
127+ if(!IF_G(cookie_array)) {
128+ ALLOC_ZVAL(array_ptr);
129+ array_init(array_ptr);
130+ INIT_PZVAL(array_ptr);
131+ }
132+ IF_G(cookie_array) = array_ptr;
133+ break;
134+ }
135+ Z_STRLEN(new_var) = val_len;
136+ Z_STRVAL(new_var) = estrndup(*val, val_len);
137+ Z_TYPE(new_var) = IS_STRING;
138+
139+ var_len = strlen(var);
140+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
141+ strcpy(raw_var, "RAW_");
142+ strlcat(raw_var,var,var_len+5);
143+
144+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
145+
146+ php_strip_tags(*val, val_len, NULL, NULL, 0);
147+
148+ *new_val_len = strlen(*val);
149+ return 1;
150+}
151+
152+PHP_FUNCTION(my_get_raw)
153+{
154+ long arg;
155+ char *var;
156+ int var_len;
157+ zval **tmp;
158+ zval *array_ptr = NULL;
159+ HashTable *hash_ptr;
160+ char *raw_var;
161+
162+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
163+ return;
164+ }
165+
166+ switch(arg) {
167+ case PARSE_GET:
168+ array_ptr = IF_G(get_array);
169+ break;
170+ case PARSE_POST:
171+ array_ptr = IF_G(post_array);
172+ break;
173+ case PARSE_COOKIE:
174+ array_ptr = IF_G(post_array);
175+ break;
176+ }
177+
178+ if(!array_ptr) RETURN_FALSE;
179+
180+ /*
181+ * I'm changing the variable name here because when running with register_globals on,
182+ * the variable will end up in the global symbol table
183+ */
184+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
185+ strcpy(raw_var, "RAW_");
186+ strlcat(raw_var,var,var_len+5);
187+ hash_ptr = HASH_OF(array_ptr);
188+
189+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
190+ *return_value = **tmp;
191+ zval_copy_ctor(return_value);
192+ } else {
193+ RETVAL_FALSE;
194+ }
195+ efree(raw_var);
196+}
197+
198diff -Nur php-4.3.10/TSRM/TSRM.h hardened-php-4.3.10-0.2.7/TSRM/TSRM.h
199--- php-4.3.10/TSRM/TSRM.h 2002-10-05 13:26:17.000000000 +0200
200+++ hardened-php-4.3.10-0.2.7/TSRM/TSRM.h 2005-04-07 01:51:16.000000000 +0200
201@@ -33,6 +33,13 @@
202 # define TSRM_API
203 #endif
204
205+#if HARDENED_PHP
206+# if HAVE_REALPATH
207+# undef realpath
208+# define realpath php_realpath
209+# endif
210+#endif
211+
212 /* Only compile multi-threading functions if we're in ZTS mode */
213 #ifdef ZTS
214
215@@ -90,6 +97,7 @@
216
217 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
218
219+
220 #ifdef __cplusplus
221 extern "C" {
222 #endif
223diff -Nur php-4.3.10/TSRM/tsrm_virtual_cwd.c hardened-php-4.3.10-0.2.7/TSRM/tsrm_virtual_cwd.c
224--- php-4.3.10/TSRM/tsrm_virtual_cwd.c 2004-12-02 02:04:46.000000000 +0100
225+++ hardened-php-4.3.10-0.2.7/TSRM/tsrm_virtual_cwd.c 2005-04-07 01:51:16.000000000 +0200
226@@ -17,7 +17,7 @@
227 +----------------------------------------------------------------------+
228 */
229
230-/* $Id: tsrm_virtual_cwd.c,v 1.41.2.8 2004/12/02 01:04:46 sesser Exp $ */
231+/* $Id: tsrm_virtual_cwd.c,v 1.41.2.4 2003/07/28 18:35:34 iliaa Exp $ */
232
233 #include <sys/types.h>
234 #include <sys/stat.h>
235@@ -192,6 +192,165 @@
236 return p;
237 }
238
239+#if HARDENED_PHP
240+CWD_API char *php_realpath(const char *path, char *resolved)
241+{
242+ struct stat sb;
243+ char *p, *q, *s;
244+ size_t left_len, resolved_len;
245+ unsigned symlinks;
246+ int serrno, slen;
247+ int is_dir = 1;
248+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
249+
250+ serrno = errno;
251+ symlinks = 0;
252+ if (path[0] == '/') {
253+ resolved[0] = '/';
254+ resolved[1] = '\0';
255+ if (path[1] == '\0')
256+ return (resolved);
257+ resolved_len = 1;
258+ left_len = strlcpy(left, path + 1, sizeof(left));
259+ } else {
260+ if (getcwd(resolved, PATH_MAX) == NULL) {
261+ strlcpy(resolved, ".", PATH_MAX);
262+ return (NULL);
263+ }
264+ resolved_len = strlen(resolved);
265+ left_len = strlcpy(left, path, sizeof(left));
266+ }
267+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
268+ errno = ENAMETOOLONG;
269+ return (NULL);
270+ }
271+
272+ /*
273+ * Iterate over path components in `left'.
274+ */
275+ while (left_len != 0) {
276+ /*
277+ * Extract the next path component and adjust `left'
278+ * and its length.
279+ */
280+ p = strchr(left, '/');
281+ s = p ? p : left + left_len;
282+ if (s - left >= sizeof(next_token)) {
283+ errno = ENAMETOOLONG;
284+ return (NULL);
285+ }
286+ memcpy(next_token, left, s - left);
287+ next_token[s - left] = '\0';
288+ left_len -= s - left;
289+ if (p != NULL)
290+ memmove(left, s + 1, left_len + 1);
291+ if (resolved[resolved_len - 1] != '/') {
292+ if (resolved_len + 1 >= PATH_MAX) {
293+ errno = ENAMETOOLONG;
294+ return (NULL);
295+ }
296+ resolved[resolved_len++] = '/';
297+ resolved[resolved_len] = '\0';
298+ }
299+ if (next_token[0] == '\0')
300+ continue;
301+ else if (strcmp(next_token, ".") == 0)
302+ continue;
303+ else if (strcmp(next_token, "..") == 0) {
304+ /*
305+ * Strip the last path component except when we have
306+ * single "/"
307+ */
308+ if (!is_dir) {
309+ errno = ENOENT;
310+ return (NULL);
311+ }
312+ if (resolved_len > 1) {
313+ resolved[resolved_len - 1] = '\0';
314+ q = strrchr(resolved, '/');
315+ *q = '\0';
316+ resolved_len = q - resolved;
317+ }
318+ continue;
319+ }
320+
321+ /*
322+ * Append the next path component and lstat() it. If
323+ * lstat() fails we still can return successfully if
324+ * there are no more path components left.
325+ */
326+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
327+ if (resolved_len >= PATH_MAX) {
328+ errno = ENAMETOOLONG;
329+ return (NULL);
330+ }
331+ if (lstat(resolved, &sb) != 0) {
332+ if (errno == ENOENT && p == NULL) {
333+ errno = serrno;
334+ return (resolved);
335+ }
336+ return (NULL);
337+ }
338+ if (S_ISLNK(sb.st_mode)) {
339+ if (symlinks++ > MAXSYMLINKS) {
340+ errno = ELOOP;
341+ return (NULL);
342+ }
343+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
344+ if (slen < 0)
345+ return (NULL);
346+ symlink[slen] = '\0';
347+ if (symlink[0] == '/') {
348+ resolved[1] = 0;
349+ resolved_len = 1;
350+ } else if (resolved_len > 1) {
351+ /* Strip the last path component. */
352+ resolved[resolved_len - 1] = '\0';
353+ q = strrchr(resolved, '/');
354+ *q = '\0';
355+ resolved_len = q - resolved;
356+ }
357+
358+ /*
359+ * If there are any path components left, then
360+ * append them to symlink. The result is placed
361+ * in `left'.
362+ */
363+ if (p != NULL) {
364+ if (symlink[slen - 1] != '/') {
365+ if (slen + 1 >= sizeof(symlink)) {
366+ errno = ENAMETOOLONG;
367+ return (NULL);
368+ }
369+ symlink[slen] = '/';
370+ symlink[slen + 1] = 0;
371+ }
372+ left_len = strlcat(symlink, left, sizeof(left));
373+ if (left_len >= sizeof(left)) {
374+ errno = ENAMETOOLONG;
375+ return (NULL);
376+ }
377+ }
378+ left_len = strlcpy(left, symlink, sizeof(left));
379+ } else {
380+ if (S_ISDIR(sb.st_mode)) {
381+ is_dir = 1;
382+ } else {
383+ is_dir = 0;
384+ }
385+ }
386+ }
387+
388+ /*
389+ * Remove trailing slash except when the resolved pathname
390+ * is a single "/".
391+ */
392+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
393+ resolved[resolved_len - 1] = '\0';
394+ return (resolved);
395+}
396+#endif
397+
398 CWD_API void virtual_cwd_startup(void)
399 {
400 char cwd[MAXPATHLEN];
401@@ -314,8 +473,7 @@
402 path = resolved_path;
403 path_length = strlen(path);
404 } else {
405- /* disable for now
406- return 1; */
407+ return 1;
408 }
409 }
410 } else { /* Concat current directory with relative path and then run realpath() on it */
411@@ -341,9 +499,8 @@
412 path = resolved_path;
413 path_length = strlen(path);
414 } else {
415- /* disable for now
416 free(tmp);
417- return 1; */
418+ return 1;
419 }
420 }
421 free(tmp);
422@@ -852,7 +1009,7 @@
423 dir_length = CWDG(cwd).cwd_length;
424 dir = CWDG(cwd).cwd;
425
426- ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length +1+1);
427+ ptr = command_line = (char *) malloc(command_length + sizeof("cd '' ; ") + dir_length +extra+1+1);
428 if (!command_line) {
429 return NULL;
430 }
431diff -Nur php-4.3.10/TSRM/tsrm_virtual_cwd.h hardened-php-4.3.10-0.2.7/TSRM/tsrm_virtual_cwd.h
432--- php-4.3.10/TSRM/tsrm_virtual_cwd.h 2003-09-20 04:08:12.000000000 +0200
433+++ hardened-php-4.3.10-0.2.7/TSRM/tsrm_virtual_cwd.h 2005-04-07 01:51:16.000000000 +0200
434@@ -128,6 +128,22 @@
435
436 typedef int (*verify_path_func)(const cwd_state *);
437
438+#ifndef HAVE_STRLCPY
439+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
440+#undef strlcpy
441+#define strlcpy php_strlcpy
442+#endif
443+
444+#ifndef HAVE_STRLCAT
445+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
446+#undef strlcat
447+#define strlcat php_strlcat
448+#endif
449+
450+
451+#if HARDENED_PHP
452+CWD_API char *php_realpath(const char *path, char *resolved);
453+#endif
454 CWD_API void virtual_cwd_startup(void);
455 CWD_API void virtual_cwd_shutdown(void);
456 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
457diff -Nur php-4.3.10/Zend/zend.c hardened-php-4.3.10-0.2.7/Zend/zend.c
458--- php-4.3.10/Zend/zend.c 2004-12-06 16:35:03.000000000 +0100
459+++ hardened-php-4.3.10-0.2.7/Zend/zend.c 2005-04-07 01:51:16.000000000 +0200
460@@ -53,6 +53,12 @@
461 ZEND_API void (*zend_unblock_interruptions)(void);
462 ZEND_API void (*zend_ticks_function)(int ticks);
463 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
464+#if HARDENED_PHP
465+ZEND_API void (*zend_security_log)(char *str);
466+#endif
467+#if HARDENED_PHP_INC_PROTECT
468+ZEND_API int (*zend_is_valid_include)(zval *z);
469+#endif
470
471 void (*zend_on_timeout)(int seconds TSRMLS_DC);
472
473@@ -424,6 +430,14 @@
474 extern zend_scanner_globals language_scanner_globals;
475 #endif
476
477+ /* Set up Hardened-PHP utility functions first */
478+#if HARDENED_PHP
479+ zend_security_log = utility_functions->security_log_function;
480+#endif
481+#if HARDENED_PHP_INC_PROTECT
482+ zend_is_valid_include = utility_functions->is_valid_include;
483+#endif
484+
485 #ifdef ZTS
486 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
487 #else
488diff -Nur php-4.3.10/Zend/zend.h hardened-php-4.3.10-0.2.7/Zend/zend.h
489--- php-4.3.10/Zend/zend.h 2004-07-28 21:06:48.000000000 +0200
490+++ hardened-php-4.3.10-0.2.7/Zend/zend.h 2005-04-07 01:51:16.000000000 +0200
491@@ -261,9 +261,9 @@
492 struct _zval_struct {
493 /* Variable information */
494 zvalue_value value; /* value */
495+ zend_uint refcount;
496 zend_uchar type; /* active type */
497 zend_uchar is_ref;
498- zend_ushort refcount;
499 };
500
501
502@@ -324,6 +324,12 @@
503 void (*ticks_function)(int ticks);
504 void (*on_timeout)(int seconds TSRMLS_DC);
505 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
506+#if HARDENED_PHP
507+ void (*security_log_function)(char *str);
508+#endif
509+#if HARDENED_PHP_INC_PROTECT
510+ int (*is_valid_include)(zval *z);
511+#endif
512 } zend_utility_functions;
513
514
515@@ -455,7 +461,16 @@
516 extern ZEND_API void (*zend_ticks_function)(int ticks);
517 extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
518 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
519+#if HARDENED_PHP
520+extern ZEND_API void (*zend_security_log)(char *str);
521+#endif
522+#if HARDENED_PHP_INC_PROTECT
523+extern ZEND_API int (*zend_is_valid_include)(zval *z);
524+#endif
525
526+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
527+ZEND_API unsigned int zend_canary(void);
528+#endif
529
530 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
531
532@@ -574,6 +589,10 @@
533 #define EMPTY_SWITCH_DEFAULT_CASE()
534 #endif
535
536+#if HARDENED_PHP
537+#include "hardened_globals.h"
538+#endif
539+
540 #endif /* ZEND_H */
541
542 /*
543diff -Nur php-4.3.10/Zend/zend_alloc.c hardened-php-4.3.10-0.2.7/Zend/zend_alloc.c
544--- php-4.3.10/Zend/zend_alloc.c 2004-08-27 18:51:25.000000000 +0200
545+++ hardened-php-4.3.10-0.2.7/Zend/zend_alloc.c 2005-04-07 01:51:16.000000000 +0200
546@@ -56,6 +56,11 @@
547 # define END_MAGIC_SIZE 0
548 #endif
549
550+#if HARDENED_PHP_MM_PROTECT
551+# define CANARY_SIZE sizeof(unsigned int)
552+#else
553+# define CANARY_SIZE 0
554+#endif
555
556 # if MEMORY_LIMIT
557 # if ZEND_DEBUG
558@@ -95,9 +100,17 @@
559 if (p==AG(head)) { \
560 AG(head) = p->pNext; \
561 } else { \
562+ if (p != p->pLast->pNext) { \
563+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
564+ exit(1); \
565+ } \
566 p->pLast->pNext = p->pNext; \
567 } \
568 if (p->pNext) { \
569+ if (p != p->pNext->pLast) { \
570+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
571+ exit(1); \
572+ } \
573 p->pNext->pLast = p->pLast; \
574 }
575
576@@ -129,6 +142,12 @@
577 DECLARE_CACHE_VARS();
578 TSRMLS_FETCH();
579
580+#if HARDENED_PHP_MM_PROTECT
581+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
582+ zend_security_log("emalloc() - requested size would result in integer overflow");
583+ exit(1);
584+ }
585+#endif
586 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
587
588 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
589@@ -146,6 +165,10 @@
590 AG(cache_stats)[CACHE_INDEX][1]++;
591 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
592 #endif
593+#if HARDENED_PHP_MM_PROTECT
594+ p->canary = HG(canary_1);
595+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
596+#endif
597 p->cached = 0;
598 p->size = size;
599 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
600@@ -161,7 +184,7 @@
601 AG(allocated_memory_peak) = AG(allocated_memory);
602 }
603 #endif
604- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
605+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
606 }
607
608 HANDLE_BLOCK_INTERRUPTIONS();
609@@ -191,7 +214,10 @@
610 # endif
611 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
612 #endif
613-
614+#if HARDENED_PHP_MM_PROTECT
615+ p->canary = HG(canary_1);
616+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
617+#endif
618 HANDLE_UNBLOCK_INTERRUPTIONS();
619 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
620 }
621@@ -218,17 +244,33 @@
622 return emalloc_rel(lval + offset);
623 }
624 }
625-
626+
627+#if HARDENED_PHP
628+ zend_security_log("Possible integer overflow catched by safe_emalloc()");
629+#endif
630 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
631 return 0;
632 }
633
634 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
635 {
636+#if HARDENED_PHP_MM_PROTECT
637+ unsigned int *canary_2;
638+#endif
639 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
640 DECLARE_CACHE_VARS();
641 TSRMLS_FETCH();
642
643+#if HARDENED_PHP_MM_PROTECT
644+ canary_2 = (unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
645+ if (p->canary != HG(canary_1) || *canary_2 != HG(canary_2)) {
646+ zend_security_log("canary mismatch on efree() - heap overflow or double efree detected");
647+ exit(1);
648+ }
649+ /* to catch double efree()s */
650+ *canary_2 = p->canary = 0;
651+#endif
652+
653 #if defined(ZTS) && TSRM_DEBUG
654 if (p->thread_id != tsrm_thread_id()) {
655 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
656@@ -273,6 +315,9 @@
657 size_t _size = nmemb * size;
658
659 if (nmemb && (_size/nmemb!=size)) {
660+#if HARDENED_PHP
661+ zend_security_log("Possible integer overflow catched by ecalloc()");
662+#endif
663 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
664 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
665 kill(getpid(), SIGSEGV);
666@@ -292,6 +337,9 @@
667
668 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
669 {
670+#if HARDENED_PHP_MM_PROTECT
671+ unsigned int canary_2;
672+#endif
673 zend_mem_header *p;
674 zend_mem_header *orig;
675 DECLARE_CACHE_VARS();
676@@ -303,6 +351,14 @@
677
678 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
679
680+#if HARDENED_PHP_MM_PROTECT
681+ canary_2 = *(unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
682+ if (p->canary != HG(canary_1) || canary_2 != HG(canary_2)) {
683+ zend_security_log("canary mismatch on erealloc() - heap overflow detected");
684+ exit(1);
685+ }
686+#endif
687+
688 #if defined(ZTS) && TSRM_DEBUG
689 if (p->thread_id != tsrm_thread_id()) {
690 void *new_p;
691@@ -326,7 +382,7 @@
692 }
693 #endif
694 REMOVE_POINTER_FROM_LIST(p);
695- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
696+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
697 if (!p) {
698 if (!allow_failure) {
699 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
700@@ -348,6 +404,9 @@
701 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
702 #endif
703
704+#if HARDENED_PHP_MM_PROTECT
705+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
706+#endif
707 p->size = size;
708
709 HANDLE_UNBLOCK_INTERRUPTIONS();
710@@ -423,6 +482,10 @@
711 {
712 AG(head) = NULL;
713
714+#if HARDENED_PHP_MM_PROTECT
715+ HG(canary_1) = zend_canary();
716+ HG(canary_2) = zend_canary();
717+#endif
718 #if MEMORY_LIMIT
719 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
720 AG(allocated_memory) = 0;
721diff -Nur php-4.3.10/Zend/zend_alloc.h hardened-php-4.3.10-0.2.7/Zend/zend_alloc.h
722--- php-4.3.10/Zend/zend_alloc.h 2004-08-11 08:10:46.000000000 +0200
723+++ hardened-php-4.3.10-0.2.7/Zend/zend_alloc.h 2005-04-07 01:51:16.000000000 +0200
724@@ -32,6 +32,9 @@
725 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
726
727 typedef struct _zend_mem_header {
728+#if HARDENED_PHP_MM_PROTECT
729+ unsigned int canary;
730+#endif
731 #if ZEND_DEBUG
732 long magic;
733 char *filename;
734diff -Nur php-4.3.10/Zend/zend_builtin_functions.c hardened-php-4.3.10-0.2.7/Zend/zend_builtin_functions.c
735--- php-4.3.10/Zend/zend_builtin_functions.c 2004-04-01 21:05:01.000000000 +0200
736+++ hardened-php-4.3.10-0.2.7/Zend/zend_builtin_functions.c 2005-04-07 01:51:16.000000000 +0200
737@@ -49,6 +49,9 @@
738 static ZEND_FUNCTION(crash);
739 #endif
740 #endif
741+#if HARDENED_PHP_MM_PROTECT_DEBUG
742+static ZEND_FUNCTION(heap_overflow);
743+#endif
744 static ZEND_FUNCTION(get_included_files);
745 static ZEND_FUNCTION(is_subclass_of);
746 static ZEND_FUNCTION(is_a);
747@@ -101,6 +104,9 @@
748 ZEND_FE(crash, NULL)
749 #endif
750 #endif
751+#if HARDENED_PHP_MM_PROTECT_DEBUG
752+ ZEND_FE(heap_overflow, NULL)
753+#endif
754 ZEND_FE(get_included_files, NULL)
755 ZEND_FALIAS(get_required_files, get_included_files, NULL)
756 ZEND_FE(is_subclass_of, NULL)
757@@ -805,6 +811,19 @@
758
759 #endif /* ZEND_DEBUG */
760
761+
762+#if HARDENED_PHP_MM_PROTECT_DEBUG
763+ZEND_FUNCTION(heap_overflow)
764+{
765+ char *nowhere = emalloc(10);
766+
767+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
768+
769+ efree(nowhere);
770+}
771+#endif
772+
773+
774 /* {{{ proto array get_included_files(void)
775 Returns an array with the file names that were include_once()'d */
776 ZEND_FUNCTION(get_included_files)
777diff -Nur php-4.3.10/Zend/zend_canary.c hardened-php-4.3.10-0.2.7/Zend/zend_canary.c
778--- php-4.3.10/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
779+++ hardened-php-4.3.10-0.2.7/Zend/zend_canary.c 2005-04-07 01:51:16.000000000 +0200
780@@ -0,0 +1,58 @@
781+/*
782+ +----------------------------------------------------------------------+
783+ | Hardened-PHP |
784+ +----------------------------------------------------------------------+
785+ | Copyright (c) 2004 Stefan Esser |
786+ +----------------------------------------------------------------------+
787+ | This source file is subject to version 2.02 of the PHP license, |
788+ | that is bundled with this package in the file LICENSE, and is |
789+ | available at through the world-wide-web at |
790+ | http://www.php.net/license/2_02.txt. |
791+ | If you did not receive a copy of the PHP license and are unable to |
792+ | obtain it through the world-wide-web, please send a note to |
793+ | license@php.net so we can mail you a copy immediately. |
794+ +----------------------------------------------------------------------+
795+ | Author: Stefan Esser <sesser@php.net> |
796+ +----------------------------------------------------------------------+
797+ */
798+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
799+
800+#include "zend.h"
801+
802+#include <stdio.h>
803+#include <stdlib.h>
804+
805+
806+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT
807+
808+/* will be replaced later with more compatible method */
809+ZEND_API unsigned int zend_canary()
810+{
811+ time_t t;
812+ unsigned int canary;
813+ int fd;
814+
815+ fd = open("/dev/urandom", 0);
816+ if (fd != -1) {
817+ int r = read(fd, &canary, sizeof(canary));
818+ close(fd);
819+ if (r == sizeof(canary)) {
820+ return (canary);
821+ }
822+ }
823+ /* not good but we never want to do this */
824+ time(&t);
825+ canary = *(unsigned int *)&t + getpid() << 16;
826+ return (canary);
827+}
828+#endif
829+
830+
831+/*
832+ * Local variables:
833+ * tab-width: 4
834+ * c-basic-offset: 4
835+ * End:
836+ * vim600: sw=4 ts=4 fdm=marker
837+ * vim<600: sw=4 ts=4
838+ */
839diff -Nur php-4.3.10/Zend/zend_execute.c hardened-php-4.3.10-0.2.7/Zend/zend_execute.c
840--- php-4.3.10/Zend/zend_execute.c 2004-11-03 12:23:59.000000000 +0100
841+++ hardened-php-4.3.10-0.2.7/Zend/zend_execute.c 2005-04-07 01:51:16.000000000 +0200
842@@ -2149,7 +2149,12 @@
843 int dummy = 1;
844 zend_file_handle file_handle = {0};
845
846+#if HARDENED_PHP_INC_PROTECT
847+ if (zend_is_valid_include(inc_filename)
848+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
849+#else
850 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
851+#endif
852 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
853
854 file_handle.filename = inc_filename->value.str.val;
855@@ -2178,6 +2183,11 @@
856 break;
857 case ZEND_INCLUDE:
858 case ZEND_REQUIRE:
859+#if HARDENED_PHP_INC_PROTECT
860+ if (!zend_is_valid_include(inc_filename)) {
861+ break;
862+ }
863+#endif
864 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
865 break;
866 case ZEND_EVAL: {
867diff -Nur php-4.3.10/Zend/zend_extensions.h hardened-php-4.3.10-0.2.7/Zend/zend_extensions.h
868--- php-4.3.10/Zend/zend_extensions.h 2002-12-31 17:23:02.000000000 +0100
869+++ hardened-php-4.3.10-0.2.7/Zend/zend_extensions.h 2005-04-07 01:51:16.000000000 +0200
870@@ -23,7 +23,9 @@
871
872 #include "zend_compile.h"
873
874-#define ZEND_EXTENSION_API_NO 20021010
875+/* Create own API version number for Hardened-PHP */
876+
877+#define ZEND_EXTENSION_API_NO 1020041222
878
879 typedef struct _zend_extension_version_info {
880 int zend_extension_api_no;
881diff -Nur php-4.3.10/Zend/zend_hash.c hardened-php-4.3.10-0.2.7/Zend/zend_hash.c
882--- php-4.3.10/Zend/zend_hash.c 2004-07-12 23:26:46.000000000 +0200
883+++ hardened-php-4.3.10-0.2.7/Zend/zend_hash.c 2005-04-07 01:51:16.000000000 +0200
884@@ -26,6 +26,17 @@
885 # include <stdlib.h>
886 #endif
887
888+#if HARDENED_PHP_HASH_PROTECT
889+ unsigned int zend_hash_canary = 0x1234567;
890+ zend_bool zend_hash_canary_inited = 0;
891+#endif
892+
893+#define CHECK_HASH_CANARY(hash) \
894+ if (zend_hash_canary != (hash)->canary) { \
895+ zend_security_log("Zend HashTable canary was overwritten"); \
896+ exit(1); \
897+ }
898+
899 #define HANDLE_NUMERIC(key, length, func) { \
900 register char *tmp=key; \
901 \
902@@ -175,6 +186,9 @@
903 {
904 uint i = 3;
905 Bucket **tmp;
906+#if HARDENED_PHP_HASH_PROTECT
907+ TSRMLS_FETCH();
908+#endif
909
910 SET_INCONSISTENT(HT_OK);
911
912@@ -184,6 +198,13 @@
913
914 ht->nTableSize = 1 << i;
915 ht->nTableMask = ht->nTableSize - 1;
916+#if HARDENED_PHP_HASH_PROTECT
917+ if (zend_hash_canary_inited==0) {
918+ zend_hash_canary = zend_canary();
919+ zend_hash_canary_inited = 1;
920+ }
921+ ht->canary = zend_hash_canary;
922+#endif
923 ht->pDestructor = pDestructor;
924 ht->pListHead = NULL;
925 ht->pListTail = NULL;
926@@ -259,6 +280,9 @@
927 }
928 #endif
929 if (ht->pDestructor) {
930+#if HARDENED_PHP_HASH_PROTECT
931+ CHECK_HASH_CANARY(ht);
932+#endif
933 ht->pDestructor(p->pData);
934 }
935 UPDATE_DATA(ht, p, pData, nDataSize);
936@@ -327,6 +351,9 @@
937 }
938 #endif
939 if (ht->pDestructor) {
940+#if HARDENED_PHP_HASH_PROTECT
941+ CHECK_HASH_CANARY(ht);
942+#endif
943 ht->pDestructor(p->pData);
944 }
945 UPDATE_DATA(ht, p, pData, nDataSize);
946@@ -402,6 +429,9 @@
947 }
948 #endif
949 if (ht->pDestructor) {
950+#if HARDENED_PHP_HASH_PROTECT
951+ CHECK_HASH_CANARY(ht);
952+#endif
953 ht->pDestructor(p->pData);
954 }
955 UPDATE_DATA(ht, p, pData, nDataSize);
956@@ -450,7 +480,7 @@
957 IS_CONSISTENT(ht);
958
959 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
960- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
961+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
962 if (t) {
963 HANDLE_BLOCK_INTERRUPTIONS();
964 ht->arBuckets = t;
965@@ -460,6 +490,7 @@
966 HANDLE_UNBLOCK_INTERRUPTIONS();
967 return SUCCESS;
968 }
969+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
970 return FAILURE;
971 }
972 return SUCCESS;
973@@ -524,6 +555,9 @@
974 ht->pInternalPointer = p->pListNext;
975 }
976 if (ht->pDestructor) {
977+#if HARDENED_PHP_HASH_PROTECT
978+ CHECK_HASH_CANARY(ht);
979+#endif
980 ht->pDestructor(p->pData);
981 }
982 if (!p->pDataPtr) {
983@@ -553,6 +587,9 @@
984 q = p;
985 p = p->pListNext;
986 if (ht->pDestructor) {
987+#if HARDENED_PHP_HASH_PROTECT
988+ CHECK_HASH_CANARY(ht);
989+#endif
990 ht->pDestructor(q->pData);
991 }
992 if (!q->pDataPtr && q->pData) {
993@@ -579,6 +616,9 @@
994 q = p;
995 p = p->pListNext;
996 if (ht->pDestructor) {
997+#if HARDENED_PHP_HASH_PROTECT
998+ CHECK_HASH_CANARY(ht);
999+#endif
1000 ht->pDestructor(q->pData);
1001 }
1002 if (!q->pDataPtr && q->pData) {
1003@@ -608,6 +648,9 @@
1004 HANDLE_BLOCK_INTERRUPTIONS();
1005
1006 if (ht->pDestructor) {
1007+#if HARDENED_PHP_HASH_PROTECT
1008+ CHECK_HASH_CANARY(ht);
1009+#endif
1010 ht->pDestructor(p->pData);
1011 }
1012 if (!p->pDataPtr) {
1013diff -Nur php-4.3.10/Zend/zend_hash.h hardened-php-4.3.10-0.2.7/Zend/zend_hash.h
1014--- php-4.3.10/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
1015+++ hardened-php-4.3.10-0.2.7/Zend/zend_hash.h 2005-04-07 01:51:16.000000000 +0200
1016@@ -54,6 +54,9 @@
1017 } Bucket;
1018
1019 typedef struct _hashtable {
1020+#if HARDENED_PHP_HASH_PROTECT
1021+ unsigned int canary;
1022+#endif
1023 uint nTableSize;
1024 uint nTableMask;
1025 uint nNumOfElements;
1026diff -Nur php-4.3.10/Zend/zend_llist.c hardened-php-4.3.10-0.2.7/Zend/zend_llist.c
1027--- php-4.3.10/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
1028+++ hardened-php-4.3.10-0.2.7/Zend/zend_llist.c 2005-04-07 01:51:16.000000000 +0200
1029@@ -21,9 +21,34 @@
1030 #include "zend.h"
1031 #include "zend_llist.h"
1032 #include "zend_qsort.h"
1033+#include "zend_globals.h"
1034+
1035+#define CHECK_LIST_CANARY(list) \
1036+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
1037+ zend_security_log("linked list canary was overwritten"); \
1038+ exit(1); \
1039+ }
1040+
1041+#define CHECK_LISTELEMENT_CANARY(elem) \
1042+ if (HG(canary_3) != (elem)->canary) { \
1043+ zend_security_log("linked list element canary was overwritten"); \
1044+ exit(1); \
1045+ }
1046+
1047
1048 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
1049 {
1050+#if HARDENED_PHP_LL_PROTECT
1051+ TSRMLS_FETCH();
1052+
1053+ if (!HG(ll_canary_inited)) {
1054+ HG(canary_3) = zend_canary();
1055+ HG(canary_4) = zend_canary();
1056+ HG(ll_canary_inited) = 1;
1057+ }
1058+ l->canary_h = HG(canary_3);
1059+ l->canary_t = HG(canary_4);
1060+#endif
1061 l->head = NULL;
1062 l->tail = NULL;
1063 l->count = 0;
1064@@ -37,6 +62,11 @@
1065 {
1066 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1067
1068+#if HARDENED_PHP_LL_PROTECT
1069+ TSRMLS_FETCH();
1070+ CHECK_LIST_CANARY(l)
1071+ tmp->canary = HG(canary_3);
1072+#endif
1073 tmp->prev = l->tail;
1074 tmp->next = NULL;
1075 if (l->tail) {
1076@@ -55,6 +85,11 @@
1077 {
1078 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1079
1080+#if HARDENED_PHP_LL_PROTECT
1081+ TSRMLS_FETCH();
1082+ CHECK_LIST_CANARY(l)
1083+ tmp->canary = HG(canary_3);
1084+#endif
1085 tmp->next = l->head;
1086 tmp->prev = NULL;
1087 if (l->head) {
1088@@ -91,10 +126,20 @@
1089 zend_llist_element *current=l->head;
1090 zend_llist_element *next;
1091
1092+#if HARDENED_PHP_LL_PROTECT
1093+ TSRMLS_FETCH();
1094+ CHECK_LIST_CANARY(l)
1095+#endif
1096 while (current) {
1097+#if HARDENED_PHP_LL_PROTECT
1098+ CHECK_LISTELEMENT_CANARY(current)
1099+#endif
1100 next = current->next;
1101 if (compare(current->data, element)) {
1102 DEL_LLIST_ELEMENT(current, l);
1103+#if HARDENED_PHP_LL_PROTECT
1104+ current->canary = 0;
1105+#endif
1106 break;
1107 }
1108 current = next;
1109@@ -106,7 +151,14 @@
1110 {
1111 zend_llist_element *current=l->head, *next;
1112
1113+#if HARDENED_PHP_LL_PROTECT
1114+ TSRMLS_FETCH();
1115+ CHECK_LIST_CANARY(l)
1116+#endif
1117 while (current) {
1118+#if HARDENED_PHP_LL_PROTECT
1119+ CHECK_LISTELEMENT_CANARY(current)
1120+#endif
1121 next = current->next;
1122 if (l->dtor) {
1123 l->dtor(current->data);
1124@@ -131,7 +183,14 @@
1125 zend_llist_element *old_tail;
1126 void *data;
1127
1128+#if HARDENED_PHP_LL_PROTECT
1129+ TSRMLS_FETCH();
1130+ CHECK_LIST_CANARY(l)
1131+#endif
1132 if ((old_tail = l->tail)) {
1133+#if HARDENED_PHP_LL_PROTECT
1134+ CHECK_LISTELEMENT_CANARY(old_tail)
1135+#endif
1136 if (l->tail->prev) {
1137 l->tail->prev->next = NULL;
1138 }
1139@@ -157,9 +216,16 @@
1140 {
1141 zend_llist_element *ptr;
1142
1143+#if HARDENED_PHP_LL_PROTECT
1144+ TSRMLS_FETCH();
1145+ CHECK_LIST_CANARY(src)
1146+#endif
1147 zend_llist_init(dst, src->size, src->dtor, src->persistent);
1148 ptr = src->head;
1149 while (ptr) {
1150+#if HARDENED_PHP_LL_PROTECT
1151+ CHECK_LISTELEMENT_CANARY(ptr)
1152+#endif
1153 zend_llist_add_element(dst, ptr->data);
1154 ptr = ptr->next;
1155 }
1156@@ -170,11 +236,21 @@
1157 {
1158 zend_llist_element *element, *next;
1159
1160+#if HARDENED_PHP_LL_PROTECT
1161+ TSRMLS_FETCH();
1162+ CHECK_LIST_CANARY(l)
1163+#endif
1164 element=l->head;
1165 while (element) {
1166+#if HARDENED_PHP_LL_PROTECT
1167+ CHECK_LISTELEMENT_CANARY(element)
1168+#endif
1169 next = element->next;
1170 if (func(element->data)) {
1171 DEL_LLIST_ELEMENT(element, l);
1172+#if HARDENED_PHP_LL_PROTECT
1173+ element->canary = 0;
1174+#endif
1175 }
1176 element = next;
1177 }
1178@@ -185,7 +261,13 @@
1179 {
1180 zend_llist_element *element;
1181
1182+#if HARDENED_PHP_LL_PROTECT
1183+ CHECK_LIST_CANARY(l)
1184+#endif
1185 for (element=l->head; element; element=element->next) {
1186+#if HARDENED_PHP_LL_PROTECT
1187+ CHECK_LISTELEMENT_CANARY(element)
1188+#endif
1189 func(element->data TSRMLS_CC);
1190 }
1191 }
1192@@ -197,6 +279,9 @@
1193 zend_llist_element **elements;
1194 zend_llist_element *element, **ptr;
1195
1196+#if HARDENED_PHP_LL_PROTECT
1197+ CHECK_LIST_CANARY(l)
1198+#endif
1199 if (l->count <= 0) {
1200 return;
1201 }
1202@@ -206,6 +291,9 @@
1203 ptr = &elements[0];
1204
1205 for (element=l->head; element; element=element->next) {
1206+#if HARDENED_PHP_LL_PROTECT
1207+ CHECK_LISTELEMENT_CANARY(element)
1208+#endif
1209 *ptr++ = element;
1210 }
1211
1212@@ -228,7 +316,13 @@
1213 {
1214 zend_llist_element *element;
1215
1216+#if HARDENED_PHP_LL_PROTECT
1217+ CHECK_LIST_CANARY(l)
1218+#endif
1219 for (element=l->head; element; element=element->next) {
1220+#if HARDENED_PHP_LL_PROTECT
1221+ CHECK_LISTELEMENT_CANARY(element)
1222+#endif
1223 func(element->data, arg TSRMLS_CC);
1224 }
1225 }
1226@@ -239,8 +333,14 @@
1227 zend_llist_element *element;
1228 va_list args;
1229
1230+#if HARDENED_PHP_LL_PROTECT
1231+ CHECK_LIST_CANARY(l)
1232+#endif
1233 va_start(args, num_args);
1234 for (element=l->head; element; element=element->next) {
1235+#if HARDENED_PHP_LL_PROTECT
1236+ CHECK_LISTELEMENT_CANARY(element)
1237+#endif
1238 func(element->data, num_args, args TSRMLS_CC);
1239 }
1240 va_end(args);
1241@@ -249,6 +349,10 @@
1242
1243 ZEND_API int zend_llist_count(zend_llist *l)
1244 {
1245+#if HARDENED_PHP_LL_PROTECT
1246+ TSRMLS_FETCH();
1247+ CHECK_LIST_CANARY(l)
1248+#endif
1249 return l->count;
1250 }
1251
1252@@ -256,8 +360,15 @@
1253 {
1254 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1255
1256+#if HARDENED_PHP_LL_PROTECT
1257+ TSRMLS_FETCH();
1258+ CHECK_LIST_CANARY(l)
1259+#endif
1260 *current = l->head;
1261 if (*current) {
1262+#if HARDENED_PHP_LL_PROTECT
1263+ CHECK_LISTELEMENT_CANARY(*current)
1264+#endif
1265 return (*current)->data;
1266 } else {
1267 return NULL;
1268@@ -269,8 +380,15 @@
1269 {
1270 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1271
1272+#if HARDENED_PHP_LL_PROTECT
1273+ TSRMLS_FETCH();
1274+ CHECK_LIST_CANARY(l)
1275+#endif
1276 *current = l->tail;
1277 if (*current) {
1278+#if HARDENED_PHP_LL_PROTECT
1279+ CHECK_LISTELEMENT_CANARY(*current)
1280+#endif
1281 return (*current)->data;
1282 } else {
1283 return NULL;
1284@@ -282,9 +400,19 @@
1285 {
1286 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1287
1288+#if HARDENED_PHP_LL_PROTECT
1289+ TSRMLS_FETCH();
1290+ CHECK_LIST_CANARY(l)
1291+#endif
1292 if (*current) {
1293+#if HARDENED_PHP_LL_PROTECT
1294+ CHECK_LISTELEMENT_CANARY(*current)
1295+#endif
1296 *current = (*current)->next;
1297 if (*current) {
1298+#if HARDENED_PHP_LL_PROTECT
1299+ CHECK_LISTELEMENT_CANARY(*current)
1300+#endif
1301 return (*current)->data;
1302 }
1303 }
1304@@ -296,9 +424,19 @@
1305 {
1306 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1307
1308+#if HARDENED_PHP_LL_PROTECT
1309+ TSRMLS_FETCH();
1310+ CHECK_LIST_CANARY(l)
1311+#endif
1312 if (*current) {
1313+#if HARDENED_PHP_LL_PROTECT
1314+ CHECK_LISTELEMENT_CANARY(*current)
1315+#endif
1316 *current = (*current)->prev;
1317 if (*current) {
1318+#if HARDENED_PHP_LL_PROTECT
1319+ CHECK_LISTELEMENT_CANARY(*current)
1320+#endif
1321 return (*current)->data;
1322 }
1323 }
1324diff -Nur php-4.3.10/Zend/zend_llist.h hardened-php-4.3.10-0.2.7/Zend/zend_llist.h
1325--- php-4.3.10/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
1326+++ hardened-php-4.3.10-0.2.7/Zend/zend_llist.h 2005-04-07 01:51:16.000000000 +0200
1327@@ -24,6 +24,9 @@
1328 #include <stdlib.h>
1329
1330 typedef struct _zend_llist_element {
1331+#if HARDENED_PHP_LL_PROTECT
1332+ unsigned int canary;
1333+#endif
1334 struct _zend_llist_element *next;
1335 struct _zend_llist_element *prev;
1336 char data[1]; /* Needs to always be last in the struct */
1337@@ -36,6 +39,9 @@
1338 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
1339
1340 typedef struct _zend_llist {
1341+#if HARDENED_PHP_LL_PROTECT
1342+ unsigned int canary_h; /* head */
1343+#endif
1344 zend_llist_element *head;
1345 zend_llist_element *tail;
1346 size_t size;
1347@@ -43,6 +49,9 @@
1348 llist_dtor_func_t dtor;
1349 unsigned char persistent;
1350 zend_llist_element *traverse_ptr;
1351+#if HARDENED_PHP_LL_PROTECT
1352+ unsigned int canary_t; /* tail */
1353+#endif
1354 } zend_llist;
1355
1356 typedef zend_llist_element* zend_llist_position;
1357diff -Nur php-4.3.10/Zend/zend_modules.h hardened-php-4.3.10-0.2.7/Zend/zend_modules.h
1358--- php-4.3.10/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
1359+++ hardened-php-4.3.10-0.2.7/Zend/zend_modules.h 2005-04-07 01:51:16.000000000 +0200
1360@@ -34,7 +34,7 @@
1361 ZEND_API extern unsigned char second_arg_force_ref[];
1362 ZEND_API extern unsigned char third_arg_force_ref[];
1363
1364-#define ZEND_MODULE_API_NO 20020429
1365+#define ZEND_MODULE_API_NO 1020041222
1366 #ifdef ZTS
1367 #define USING_ZTS 1
1368 #else
1369diff -Nur php-4.3.10/acinclude.m4 hardened-php-4.3.10-0.2.7/acinclude.m4
1370--- php-4.3.10/acinclude.m4 2004-12-11 12:17:21.000000000 +0100
1371+++ hardened-php-4.3.10-0.2.7/acinclude.m4 2005-04-07 01:51:16.000000000 +0200
1372@@ -1153,6 +1153,36 @@
1373 fi
1374 ])
1375
1376+dnl
1377+dnl Check for broken realpath()
1378+dnl
1379+dnl realpath("/etc/hosts/../passwd",XXX) should not return
1380+dnl "/etc/passwd"
1381+dnl
1382+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
1383+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
1384+ AC_TRY_RUN([
1385+main() {
1386+ char buf[4096+1];
1387+ buf[0] = 0;
1388+ realpath("/etc/hosts/../passwd", buf);
1389+ exit(strcmp(buf, "/etc/passwd")==0);
1390+}
1391+ ],[
1392+ ac_cv_broken_realpath=no
1393+ ],[
1394+ ac_cv_broken_realpath=yes
1395+ ],[
1396+ ac_cv_broken_realpath=no
1397+ ])
1398+ ])
1399+ if test "$ac_cv_broken_realpath" = "yes"; then
1400+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
1401+ else
1402+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
1403+ fi
1404+])
1405+
1406 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
1407 dnl
1408 dnl Basically sets up the link-stage for building module-name
1409diff -Nur php-4.3.10/configure hardened-php-4.3.10-0.2.7/configure
1410--- php-4.3.10/configure 2004-12-14 18:55:18.000000000 +0100
1411+++ hardened-php-4.3.10-0.2.7/configure 2005-04-07 01:51:16.000000000 +0200
1412@@ -389,6 +389,16 @@
1413 ac_default_prefix=/usr/local
1414 # Any additions from configure.in:
1415 ac_help="$ac_help
1416+ --disable-hardened-php-mm-protect Disable the Memory Manager protection."
1417+ac_help="$ac_help
1418+ --disable-hardened-php-ll-protect Disable the Linked List protection."
1419+ac_help="$ac_help
1420+ --disable-hardened-php-inc-protect Disable include/require protection."
1421+ac_help="$ac_help
1422+ --disable-hardened-php-fmt-protect Disable format string protection."
1423+ac_help="$ac_help
1424+ --disable-hardened-php-hash-protect Disable Zend HashTable DTOR protection."
1425+ac_help="$ac_help
1426
1427 SAPI modules:
1428 "
1429@@ -831,6 +841,8 @@
1430 ac_help="$ac_help
1431 --disable-tokenizer Disable tokenizer support"
1432 ac_help="$ac_help
1433+ --disable-varfilter Disable Hardened-PHP's variable filter"
1434+ac_help="$ac_help
1435 --enable-wddx Enable WDDX support."
1436 ac_help="$ac_help
1437 --disable-xml Disable XML support using bundled expat lib"
1438@@ -2643,6 +2655,157 @@
1439
1440
1441
1442+# Check whether --enable-hardened-php-mm-protect or --disable-hardened-php-mm-protect was given.
1443+if test "${enable_hardened_php_mm_protect+set}" = set; then
1444+ enableval="$enable_hardened_php_mm_protect"
1445+
1446+ DO_HARDENED_PHP_MM_PROTECT=$enableval
1447+
1448+else
1449+
1450+ DO_HARDENED_PHP_MM_PROTECT=yes
1451+
1452+fi
1453+
1454+
1455+# Check whether --enable-hardened-php-ll-protect or --disable-hardened-php-ll-protect was given.
1456+if test "${enable_hardened_php_ll_protect+set}" = set; then
1457+ enableval="$enable_hardened_php_ll_protect"
1458+
1459+ DO_HARDENED_PHP_LL_PROTECT=$enableval
1460+
1461+else
1462+
1463+ DO_HARDENED_PHP_LL_PROTECT=yes
1464+
1465+fi
1466+
1467+
1468+# Check whether --enable-hardened-php-inc-protect or --disable-hardened-php-inc-protect was given.
1469+if test "${enable_hardened_php_inc_protect+set}" = set; then
1470+ enableval="$enable_hardened_php_inc_protect"
1471+
1472+ DO_HARDENED_PHP_INC_PROTECT=$enableval
1473+
1474+else
1475+
1476+ DO_HARDENED_PHP_INC_PROTECT=yes
1477+
1478+fi
1479+
1480+
1481+# Check whether --enable-hardened-php-fmt-protect or --disable-hardened-php-fmt-protect was given.
1482+if test "${enable_hardened_php_fmt_protect+set}" = set; then
1483+ enableval="$enable_hardened_php_fmt_protect"
1484+
1485+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
1486+
1487+else
1488+
1489+ DO_HARDENED_PHP_FMT_PROTECT=yes
1490+
1491+fi
1492+
1493+
1494+# Check whether --enable-hardened-php-hash-protect or --disable-hardened-php-hash-protect was given.
1495+if test "${enable_hardened_php_hash_protect+set}" = set; then
1496+ enableval="$enable_hardened_php_hash_protect"
1497+
1498+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
1499+
1500+else
1501+
1502+ DO_HARDENED_PHP_HASH_PROTECT=yes
1503+
1504+fi
1505+
1506+
1507+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
1508+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
1509+echo "$ac_t""$DO_HARDENED_PHP_MM_PROTECT" 1>&6
1510+
1511+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
1512+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
1513+echo "$ac_t""$DO_HARDENED_PHP_LL_PROTECT" 1>&6
1514+
1515+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
1516+echo "configure:2733: checking whether to protect include/require statements" >&5
1517+echo "$ac_t""$DO_HARDENED_PHP_INC_PROTECT" 1>&6
1518+
1519+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
1520+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
1521+echo "$ac_t""$DO_HARDENED_PHP_FMT_PROTECT" 1>&6
1522+
1523+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
1524+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
1525+echo "$ac_t""$DO_HARDENED_PHP_HASH_PROTECT" 1>&6
1526+
1527+
1528+cat >> confdefs.h <<\EOF
1529+#define HARDENED_PHP 1
1530+EOF
1531+
1532+
1533+
1534+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
1535+ cat >> confdefs.h <<\EOF
1536+#define HARDENED_PHP_MM_PROTECT 1
1537+EOF
1538+
1539+else
1540+ cat >> confdefs.h <<\EOF
1541+#define HARDENED_PHP_MM_PROTECT 0
1542+EOF
1543+
1544+fi
1545+
1546+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
1547+ cat >> confdefs.h <<\EOF
1548+#define HARDENED_PHP_LL_PROTECT 1
1549+EOF
1550+
1551+else
1552+ cat >> confdefs.h <<\EOF
1553+#define HARDENED_PHP_LL_PROTECT 0
1554+EOF
1555+
1556+fi
1557+
1558+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
1559+ cat >> confdefs.h <<\EOF
1560+#define HARDENED_PHP_INC_PROTECT 1
1561+EOF
1562+
1563+else
1564+ cat >> confdefs.h <<\EOF
1565+#define HARDENED_PHP_INC_PROTECT 0
1566+EOF
1567+
1568+fi
1569+
1570+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
1571+ cat >> confdefs.h <<\EOF
1572+#define HARDENED_PHP_FMT_PROTECT 1
1573+EOF
1574+
1575+else
1576+ cat >> confdefs.h <<\EOF
1577+#define HARDENED_PHP_FMT_PROTECT 0
1578+EOF
1579+
1580+fi
1581+
1582+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
1583+ cat >> confdefs.h <<\EOF
1584+#define HARDENED_PHP_HASH_PROTECT 1
1585+EOF
1586+
1587+else
1588+ cat >> confdefs.h <<\EOF
1589+#define HARDENED_PHP_HASH_PROTECT 0
1590+EOF
1591+
1592+fi
1593
1594
1595
1596@@ -14890,6 +15053,62 @@
1597 fi
1598
1599
1600+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
1601+echo "configure:14928: checking whether realpath is broken" >&5
1602+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
1603+ echo $ac_n "(cached) $ac_c" 1>&6
1604+else
1605+
1606+ if test "$cross_compiling" = yes; then
1607+
1608+ ac_cv_broken_realpath=no
1609+
1610+else
1611+ cat > conftest.$ac_ext <<EOF
1612+#line 14939 "configure"
1613+#include "confdefs.h"
1614+
1615+main() {
1616+ char buf[4096+1];
1617+ buf[0] = 0;
1618+ realpath("/etc/hosts/../passwd", buf);
1619+ exit(strcmp(buf, "/etc/passwd")==0);
1620+}
1621+
1622+EOF
1623+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
1624+then
1625+
1626+ ac_cv_broken_realpath=no
1627+
1628+else
1629+ echo "configure: failed program was:" >&5
1630+ cat conftest.$ac_ext >&5
1631+ rm -fr conftest*
1632+
1633+ ac_cv_broken_realpath=yes
1634+
1635+fi
1636+rm -fr conftest*
1637+fi
1638+
1639+
1640+fi
1641+
1642+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
1643+ if test "$ac_cv_broken_realpath" = "yes"; then
1644+ cat >> confdefs.h <<\EOF
1645+#define PHP_BROKEN_REALPATH 1
1646+EOF
1647+
1648+ else
1649+ cat >> confdefs.h <<\EOF
1650+#define PHP_BROKEN_REALPATH 0
1651+EOF
1652+
1653+ fi
1654+
1655+
1656 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
1657 echo "configure:14895: checking for declared timezone" >&5
1658 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
1659@@ -82014,6 +82233,265 @@
1660 fi
1661
1662
1663+echo $ac_n "checking whether to enable Hardened-PHP's variable filter""... $ac_c" 1>&6
1664+echo "configure:82041: checking whether to enable Hardened-PHP's variable filter" >&5
1665+# Check whether --enable-varfilter or --disable-varfilter was given.
1666+if test "${enable_varfilter+set}" = set; then
1667+ enableval="$enable_varfilter"
1668+ PHP_VARFILTER=$enableval
1669+else
1670+
1671+ PHP_VARFILTER=yes
1672+
1673+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
1674+ PHP_VARFILTER=$PHP_ENABLE_ALL
1675+ fi
1676+
1677+fi
1678+
1679+
1680+
1681+ext_output="yes, shared"
1682+ext_shared=yes
1683+case $PHP_VARFILTER in
1684+shared,*)
1685+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
1686+ ;;
1687+shared)
1688+ PHP_VARFILTER=yes
1689+ ;;
1690+no)
1691+ ext_output=no
1692+ ext_shared=no
1693+ ;;
1694+*)
1695+ ext_output=yes
1696+ ext_shared=no
1697+ ;;
1698+esac
1699+
1700+
1701+
1702+echo "$ac_t""$ext_output" 1>&6
1703+
1704+
1705+
1706+
1707+if test "$PHP_VARFILTER" != "no"; then
1708+ cat >> confdefs.h <<\EOF
1709+#define HAVE_VARFILTER 1
1710+EOF
1711+
1712+
1713+ ext_builddir=ext/varfilter
1714+ ext_srcdir=$abs_srcdir/ext/varfilter
1715+
1716+ ac_extra=
1717+
1718+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
1719+
1720+
1721+
1722+ case ext/varfilter in
1723+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1724+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1725+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1726+ esac
1727+
1728+
1729+
1730+ b_c_pre=$php_c_pre
1731+ b_cxx_pre=$php_cxx_pre
1732+ b_c_meta=$php_c_meta
1733+ b_cxx_meta=$php_cxx_meta
1734+ b_c_post=$php_c_post
1735+ b_cxx_post=$php_cxx_post
1736+ b_lo=$php_lo
1737+
1738+
1739+ old_IFS=$IFS
1740+ for ac_src in varfilter.c; do
1741+
1742+ IFS=.
1743+ set $ac_src
1744+ ac_obj=$1
1745+ IFS=$old_IFS
1746+
1747+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1748+
1749+ case $ac_src in
1750+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1751+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1752+ esac
1753+
1754+ cat >>Makefile.objects<<EOF
1755+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1756+ $ac_comp
1757+EOF
1758+ done
1759+
1760+
1761+ EXT_STATIC="$EXT_STATIC varfilter"
1762+ if test "$ext_shared" != "nocli"; then
1763+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1764+ fi
1765+ else
1766+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
1767+
1768+ case ext/varfilter in
1769+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1770+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1771+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1772+ esac
1773+
1774+
1775+
1776+ b_c_pre=$shared_c_pre
1777+ b_cxx_pre=$shared_cxx_pre
1778+ b_c_meta=$shared_c_meta
1779+ b_cxx_meta=$shared_cxx_meta
1780+ b_c_post=$shared_c_post
1781+ b_cxx_post=$shared_cxx_post
1782+ b_lo=$shared_lo
1783+
1784+
1785+ old_IFS=$IFS
1786+ for ac_src in varfilter.c; do
1787+
1788+ IFS=.
1789+ set $ac_src
1790+ ac_obj=$1
1791+ IFS=$old_IFS
1792+
1793+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
1794+
1795+ case $ac_src in
1796+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1797+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1798+ esac
1799+
1800+ cat >>Makefile.objects<<EOF
1801+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1802+ $ac_comp
1803+EOF
1804+ done
1805+
1806+
1807+ install_modules="install-modules"
1808+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
1809+
1810+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
1811+
1812+ cat >>Makefile.objects<<EOF
1813+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
1814+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
1815+
1816+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
1817+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
1818+
1819+EOF
1820+
1821+ cat >> confdefs.h <<EOF
1822+#define COMPILE_DL_VARFILTER 1
1823+EOF
1824+
1825+ fi
1826+ fi
1827+
1828+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
1829+ if test "$PHP_SAPI" = "cgi"; then
1830+
1831+
1832+ case ext/varfilter in
1833+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1834+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1835+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1836+ esac
1837+
1838+
1839+
1840+ b_c_pre=$php_c_pre
1841+ b_cxx_pre=$php_cxx_pre
1842+ b_c_meta=$php_c_meta
1843+ b_cxx_meta=$php_cxx_meta
1844+ b_c_post=$php_c_post
1845+ b_cxx_post=$php_cxx_post
1846+ b_lo=$php_lo
1847+
1848+
1849+ old_IFS=$IFS
1850+ for ac_src in varfilter.c; do
1851+
1852+ IFS=.
1853+ set $ac_src
1854+ ac_obj=$1
1855+ IFS=$old_IFS
1856+
1857+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1858+
1859+ case $ac_src in
1860+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1861+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1862+ esac
1863+
1864+ cat >>Makefile.objects<<EOF
1865+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1866+ $ac_comp
1867+EOF
1868+ done
1869+
1870+
1871+ EXT_STATIC="$EXT_STATIC varfilter"
1872+ else
1873+
1874+
1875+ case ext/varfilter in
1876+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1877+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1878+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1879+ esac
1880+
1881+
1882+
1883+ b_c_pre=$php_c_pre
1884+ b_cxx_pre=$php_cxx_pre
1885+ b_c_meta=$php_c_meta
1886+ b_cxx_meta=$php_cxx_meta
1887+ b_c_post=$php_c_post
1888+ b_cxx_post=$php_cxx_post
1889+ b_lo=$php_lo
1890+
1891+
1892+ old_IFS=$IFS
1893+ for ac_src in varfilter.c; do
1894+
1895+ IFS=.
1896+ set $ac_src
1897+ ac_obj=$1
1898+ IFS=$old_IFS
1899+
1900+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
1901+
1902+ case $ac_src in
1903+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1904+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1905+ esac
1906+
1907+ cat >>Makefile.objects<<EOF
1908+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1909+ $ac_comp
1910+EOF
1911+ done
1912+
1913+
1914+ fi
1915+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1916+ fi
1917+
1918+ BUILD_DIR="$BUILD_DIR $ext_builddir"
1919+
1920+
1921+fi
1922
1923
1924 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
1925@@ -94503,7 +94981,7 @@
1926 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1927 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1928 streams.c network.c php_open_temporary_file.c php_logos.c \
1929- output.c memory_streams.c user_streams.c; do
1930+ output.c memory_streams.c user_streams.c hardened_php.c; do
1931
1932 IFS=.
1933 set $ac_src
1934@@ -94676,7 +95154,7 @@
1935 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1936 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1937 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1938- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
1939+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
1940
1941 IFS=.
1942 set $ac_src
1943diff -Nur php-4.3.10/configure.in hardened-php-4.3.10-0.2.7/configure.in
1944--- php-4.3.10/configure.in 2004-12-14 17:07:49.000000000 +0100
1945+++ hardened-php-4.3.10-0.2.7/configure.in 2005-04-07 01:51:16.000000000 +0200
1946@@ -205,7 +205,7 @@
1947 sinclude(Zend/acinclude.m4)
1948 sinclude(Zend/Zend.m4)
1949 sinclude(TSRM/tsrm.m4)
1950-
1951+sinclude(main/hardened_php.m4)
1952
1953
1954 divert(2)
1955@@ -573,6 +573,7 @@
1956 AC_FUNC_ALLOCA
1957 dnl PHP_AC_BROKEN_SPRINTF
1958 dnl PHP_AC_BROKEN_SNPRINTF
1959+PHP_AC_BROKEN_REALPATH
1960 PHP_DECLARED_TIMEZONE
1961 PHP_TIME_R_TYPE
1962 PHP_READDIR_R_TYPE
1963@@ -1201,7 +1202,7 @@
1964 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1965 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1966 streams.c network.c php_open_temporary_file.c php_logos.c \
1967- output.c memory_streams.c user_streams.c)
1968+ output.c memory_streams.c user_streams.c hardened_php.c)
1969 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
1970 PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
1971
1972@@ -1214,7 +1215,7 @@
1973 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1974 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1975 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1976- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
1977+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
1978
1979 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1980 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
1981diff -Nur php-4.3.10/ext/curl/curl.c hardened-php-4.3.10-0.2.7/ext/curl/curl.c
1982--- php-4.3.10/ext/curl/curl.c 2004-11-01 05:56:10.000000000 +0100
1983+++ hardened-php-4.3.10-0.2.7/ext/curl/curl.c 2005-04-07 01:51:16.000000000 +0200
1984@@ -16,7 +16,7 @@
1985 +----------------------------------------------------------------------+
1986 */
1987
1988-/* $Id: curl.c,v 1.124.2.27 2004/11/01 04:56:10 iliaa Exp $ */
1989+/* $Id: curl.c,v 1.124.2.29 2005/03/14 09:03:09 sniper Exp $ */
1990
1991 #ifdef HAVE_CONFIG_H
1992 #include "config.h"
1993@@ -50,6 +50,7 @@
1994 #include "ext/standard/php_smart_str.h"
1995 #include "ext/standard/info.h"
1996 #include "ext/standard/file.h"
1997+#include "ext/standard/url.h"
1998 #include "php_curl.h"
1999
2000 static int le_curl;
2001@@ -64,6 +65,26 @@
2002 #define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s), (char *) v, 1);
2003 #define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s), (zval *) v);
2004
2005+#define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
2006+ if (PG(open_basedir) && *PG(open_basedir) && \
2007+ strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
2008+ { \
2009+ php_url *tmp_url; \
2010+ \
2011+ if (!(tmp_url = php_url_parse_ex(str, len))) { \
2012+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid url '%s'", str); \
2013+ RETURN_FALSE; \
2014+ } \
2015+ \
2016+ if (php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
2017+ (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
2018+ ) { \
2019+ php_url_free(tmp_url); \
2020+ RETURN_FALSE; \
2021+ } \
2022+ php_url_free(tmp_url); \
2023+ }
2024+
2025 /* {{{ curl_functions[]
2026 */
2027 function_entry curl_functions[] = {
2028@@ -682,6 +703,11 @@
2029 WRONG_PARAM_COUNT;
2030 }
2031
2032+ if (argc > 0) {
2033+ convert_to_string_ex(url);
2034+ PHP_CURL_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(url), Z_STRLEN_PP(url));
2035+ }
2036+
2037 alloc_curl_handle(&ch);
2038
2039 ch->cp = curl_easy_init();
2040@@ -712,7 +738,6 @@
2041
2042 if (argc > 0) {
2043 char *urlcopy;
2044- convert_to_string_ex(url);
2045
2046 urlcopy = estrndup(Z_STRVAL_PP(url), Z_STRLEN_PP(url));
2047 curl_easy_setopt(ch->cp, CURLOPT_URL, urlcopy);
2048@@ -724,7 +749,7 @@
2049 }
2050 /* }}} */
2051
2052-/* {{{ proto bool curl_setopt(resource ch, string option, mixed value)
2053+/* {{{ proto bool curl_setopt(resource ch, int option, mixed value)
2054 Set an option for a CURL transfer */
2055 PHP_FUNCTION(curl_setopt)
2056 {
2057@@ -819,8 +844,12 @@
2058 char *copystr = NULL;
2059
2060 convert_to_string_ex(zvalue);
2061- copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
2062
2063+ if (option == CURLOPT_URL) {
2064+ PHP_CURL_CHECK_OPEN_BASEDIR(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
2065+ }
2066+
2067+ copystr = estrndup(Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue));
2068 error = curl_easy_setopt(ch->cp, option, copystr);
2069 zend_llist_add_element(&ch->to_free.str, &copystr);
2070
2071@@ -955,16 +984,16 @@
2072 if (*postval == '@') {
2073 error = curl_formadd(&first, &last,
2074 CURLFORM_COPYNAME, string_key,
2075- CURLFORM_NAMELENGTH, string_key_len - 1,
2076+ CURLFORM_NAMELENGTH, (long)string_key_len - 1,
2077 CURLFORM_FILE, ++postval,
2078 CURLFORM_END);
2079 }
2080 else {
2081 error = curl_formadd(&first, &last,
2082 CURLFORM_COPYNAME, string_key,
2083- CURLFORM_NAMELENGTH, string_key_len - 1,
2084+ CURLFORM_NAMELENGTH, (long)string_key_len - 1,
2085 CURLFORM_COPYCONTENTS, postval,
2086- CURLFORM_CONTENTSLENGTH, Z_STRLEN_PP(current),
2087+ CURLFORM_CONTENTSLENGTH, (long)Z_STRLEN_PP(current),
2088 CURLFORM_END);
2089 }
2090 }
2091diff -Nur php-4.3.10/ext/exif/exif.c hardened-php-4.3.10-0.2.7/ext/exif/exif.c
2092--- php-4.3.10/ext/exif/exif.c 2004-11-10 02:44:58.000000000 +0100
2093+++ hardened-php-4.3.10-0.2.7/ext/exif/exif.c 2005-04-07 01:51:16.000000000 +0200
2094@@ -17,7 +17,7 @@
2095 +----------------------------------------------------------------------+
2096 */
2097
2098-/* $Id: exif.c,v 1.118.2.29 2004/11/10 01:44:58 iliaa Exp $ */
2099+/* $Id: exif.c,v 1.118.2.37 2005/03/22 22:07:03 edink Exp $ */
2100
2101 /* ToDos
2102 *
2103@@ -58,7 +58,7 @@
2104 #include "ext/standard/php_image.h"
2105 #include "ext/standard/info.h"
2106
2107-#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
2108+#if defined(PHP_WIN32) || (HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING))
2109 #define EXIF_USE_MBSTRING 1
2110 #else
2111 #define EXIF_USE_MBSTRING 0
2112@@ -68,6 +68,12 @@
2113 #include "ext/mbstring/mbstring.h"
2114 #endif
2115
2116+/* needed for ssize_t definition */
2117+#include <sys/types.h>
2118+#if defined(PHP_WIN32) && !defined(ssize_t)
2119+typedef SSIZE_T ssize_t;
2120+#endif
2121+
2122 typedef unsigned char uchar;
2123
2124 #ifndef safe_emalloc
2125@@ -85,6 +91,8 @@
2126
2127 #define EFREE_IF(ptr) if (ptr) efree(ptr)
2128
2129+#define MAX_IFD_NESTING_LEVEL 100
2130+
2131 static unsigned char exif_thumbnail_force_ref[] = {2, BYREF_NONE, BYREF_FORCE_REST};
2132
2133 /* {{{ exif_functions[]
2134@@ -99,7 +107,7 @@
2135 };
2136 /* }}} */
2137
2138-#define EXIF_VERSION "1.4 $Id: exif.c,v 1.118.2.29 2004/11/10 01:44:58 iliaa Exp $"
2139+#define EXIF_VERSION "1.4 $Id: exif.c,v 1.118.2.37 2005/03/22 22:07:03 edink Exp $"
2140
2141 /* {{{ PHP_MINFO_FUNCTION
2142 */
2143@@ -1430,6 +1438,7 @@
2144 /* for parsing */
2145 int read_thumbnail;
2146 int read_all;
2147+ int ifd_nesting_level;
2148 /* internal */
2149 file_section_list file;
2150 } image_info_type;
2151@@ -2689,6 +2698,13 @@
2152 size_t byte_count, offset_val, fpos, fgot;
2153 xp_field_type *tmp_xp;
2154
2155+ /* Protect against corrupt headers */
2156+ if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) {
2157+ exif_error_docref("exif_read_data#error_ifd" TSRMLS_CC, ImageInfo, E_WARNING, "corrupt EXIF header: maximum directory nesting level reached");
2158+ return FALSE;
2159+ }
2160+ ImageInfo->ifd_nesting_level++;
2161+
2162 tag = php_ifd_get16u(dir_entry, ImageInfo->motorola_intel);
2163 format = php_ifd_get16u(dir_entry+2, ImageInfo->motorola_intel);
2164 components = php_ifd_get32u(dir_entry+4, ImageInfo->motorola_intel);
2165@@ -2702,6 +2718,11 @@
2166
2167 byte_count = components * php_tiff_bytes_per_format[format];
2168
2169+ if ((ssize_t)byte_count < 0) {
2170+ exif_error_docref("exif_read_data#error_ifd" TSRMLS_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal byte_count(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), byte_count);
2171+ return FALSE;
2172+ }
2173+
2174 if (byte_count > 4) {
2175 offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel);
2176 /* If its bigger than 4 bytes, the dir entry contains an offset. */
2177@@ -3372,7 +3393,7 @@
2178 return FALSE;
2179 }
2180 php_stream_read(ImageInfo->infile, (char*)(ImageInfo->file.list[sn].data+2), dir_size-2);
2181- /*exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Dump: %s", exif_char_dump(ImageInfo->file.list[sn].data, dir_size, 0));*/
2182+ /*exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "Dump: %s", exif_char_dump(ImageInfo->file.list[sn].data, dir_size, 0));*/
2183 next_offset = php_ifd_get32u(ImageInfo->file.list[sn].data + dir_size - 4, ImageInfo->motorola_intel);
2184 #ifdef EXIF_DEBUG
2185 exif_error_docref(NULL TSRMLS_CC, ImageInfo, E_NOTICE, "read from TIFF done, next offset x%04X", next_offset);
2186@@ -3713,6 +3734,8 @@
2187 }
2188 }
2189
2190+ ImageInfo->ifd_nesting_level = 0;
2191+
2192 /* Scan the JPEG headers. */
2193 ret = exif_scan_FILE_header(ImageInfo TSRMLS_CC);
2194
2195diff -Nur php-4.3.10/ext/fbsql/php_fbsql.c hardened-php-4.3.10-0.2.7/ext/fbsql/php_fbsql.c
2196--- php-4.3.10/ext/fbsql/php_fbsql.c 2004-08-24 20:00:05.000000000 +0200
2197+++ hardened-php-4.3.10-0.2.7/ext/fbsql/php_fbsql.c 2005-04-07 01:51:16.000000000 +0200
2198@@ -16,7 +16,7 @@
2199 +----------------------------------------------------------------------+
2200 */
2201
2202-/* $Id: php_fbsql.c,v 1.86.2.9 2004/08/24 18:00:05 fmk Exp $ */
2203+/* $Id: php_fbsql.c,v 1.86.2.14 2005/02/09 19:33:32 fmk Exp $ */
2204
2205 /* TODO:
2206 *
2207@@ -459,11 +459,11 @@
2208
2209 if (FB_SQL_G(allowPersistent))
2210 {
2211- sprintf(buf, "%ld", FB_SQL_G(persistentCount));
2212+ snprintf(buf, sizeof(buf), "%ld", FB_SQL_G(persistentCount));
2213 php_info_print_table_row(2, "Active Persistent Links", buf);
2214 }
2215
2216- sprintf(buf, "%ld", FB_SQL_G(linkCount));
2217+ snprintf(buf, sizeof(buf), "%ld", FB_SQL_G(linkCount));
2218 php_info_print_table_row(2, "Active Links", buf);
2219
2220 /*
2221@@ -507,7 +507,9 @@
2222 if (userName == NULL) userName = FB_SQL_G(userName);
2223 if (userPassword == NULL) userPassword = FB_SQL_G(userPassword);
2224
2225- sprintf(name, "fbsql_%s_%s_%s", hostName, userName, userPassword);
2226+ if (snprintf(name, sizeof(name), "fbsql_%s_%s_%s", hostName, userName, userPassword) < 0) {
2227+ RETURN_FALSE;
2228+ }
2229
2230 if (!FB_SQL_G(allowPersistent)) {
2231 persistent=0;
2232@@ -818,9 +820,21 @@
2233 WRONG_PARAM_COUNT;
2234 break;
2235 }
2236+
2237+ if (Z_LVAL_PP(Locking) < 0 || Z_LVAL_PP(Locking) > 2) {
2238+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid locking type.");
2239+ RETURN_FALSE;
2240+ }
2241+ if (Z_LVAL_PP(Isolation) < 0 || Z_LVAL_PP(Isolation) > 4) {
2242+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid isolation type.");
2243+ RETURN_FALSE;
2244+ }
2245+
2246 ZEND_FETCH_RESOURCE2(phpLink, PHPFBLink *, fbsql_link_index, -1, "FrontBase-Link", le_link, le_plink);
2247
2248- sprintf(strSQL, "SET TRANSACTION LOCKING %s, ISOLATION %s;", strLocking[Z_LVAL_PP(Locking)], strIsolation[Z_LVAL_PP(Isolation)]);
2249+ if (snprintf(strSQL, sizeof(strSQL) , "SET TRANSACTION LOCKING %s, ISOLATION %s;", strLocking[Z_LVAL_PP(Locking)], strIsolation[Z_LVAL_PP(Isolation)]) < 0) {
2250+ RETURN_FALSE;
2251+ }
2252
2253 md = fbcdcExecuteDirectSQL(phpLink->connection, strSQL);
2254 fbcmdRelease(md);
2255@@ -1417,7 +1431,9 @@
2256 convert_to_string_ex(password);
2257 userPassword = Z_STRVAL_PP(password);
2258
2259- sprintf(buffer, "SET AUTHORIZATION %s;", userName);
2260+ if (snprintf(buffer, sizeof(buffer), "SET AUTHORIZATION %s;", userName) < 0) {
2261+ RETURN_FALSE;
2262+ }
2263
2264 phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, buffer, phpLink);
2265 if (Z_LVAL_P(return_value))
2266@@ -1791,11 +1807,28 @@
2267 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message");
2268 }
2269 link->errorText = strdup(emg);
2270- link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);;
2271+ link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);
2272 free(emg);
2273 fbcemdRelease(emd);
2274 result = 0;
2275 }
2276+ else if (fbcmdWarningsFound(md))
2277+ {
2278+ FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
2279+ char* emg = fbcemdAllErrorMessages(emd);
2280+ if (FB_SQL_G(generateWarnings))
2281+ {
2282+ if (emg)
2283+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Warning in statement: '%s' %s", sql, emg);
2284+ else
2285+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No message");
2286+ }
2287+ link->errorText = strdup(emg);
2288+ link->errorNo = fbcemdErrorCodeAtIndex(emd, 0);
2289+ free(emg);
2290+ fbcemdRelease(emd);
2291+ result = 1;
2292+ }
2293 return result;
2294 }
2295 /* }}} */
2296@@ -1824,9 +1857,12 @@
2297 md = meta;
2298
2299 tp = fbcmdStatementType(md);
2300-
2301- if ((tp[0] == 'C') || (tp[0] == 'R'))
2302- {
2303+ if (tp == NULL) {
2304+ fbcmdRelease(meta);
2305+ ZVAL_BOOL(return_value, 1)
2306+ }
2307+ else if ((tp[0] == 'C') || (tp[0] == 'R'))
2308+ {
2309 if (sR == 1 && md) fbcmdRelease(md);
2310 ZVAL_BOOL(return_value, 1)
2311 }
2312@@ -2084,7 +2120,9 @@
2313 RETURN_FALSE;
2314 }
2315
2316- sprintf(sql, "SELECT * FROM %s WHERE 1=0;", tableName);
2317+ if (snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE 1=0;", tableName) < 0) {
2318+ RETURN_FALSE;
2319+ }
2320
2321 phpfbQuery(INTERNAL_FUNCTION_PARAM_PASSTHRU, sql, phpLink);
2322 }
2323@@ -2268,7 +2306,7 @@
2324 {
2325 int v = *((int*)data);
2326 char b[128];
2327- sprintf(b, "%d", v);
2328+ snprintf(b, sizeof(b), "%d", v);
2329 phpfbestrdup(b, length, value);
2330 }
2331 break;
2332@@ -2277,7 +2315,7 @@
2333 {
2334 short int v = *((FBTinyInteger*)data);
2335 char b[128];
2336- sprintf(b, "%d", v);
2337+ snprintf(b, sizeof(b), "%d", v);
2338 phpfbestrdup(b, length, value);
2339 }
2340 break;
2341@@ -2288,9 +2326,9 @@
2342 FBLongInteger v = *((FBLongInteger*)data);
2343 char b[128];
2344 #ifdef PHP_WIN32
2345- sprintf(b, "%I64i", v);
2346+ snprintf(b, sizeof(b), "%I64i", v);
2347 #else
2348- sprintf(b, "%ll", v);
2349+ snprintf(b, sizeof(b), "%ll", v);
2350 #endif
2351 phpfbestrdup(b, length, value);
2352 }
2353@@ -2300,7 +2338,7 @@
2354 {
2355 short v = *((short*)data);
2356 char b[128];
2357- sprintf(b, "%d", v);
2358+ snprintf(b, sizeof(b), "%d", v);
2359 phpfbestrdup(b, length, value);
2360 }
2361 break;
2362@@ -2313,7 +2351,7 @@
2363 {
2364 double v = *((double*)data);
2365 char b[128];
2366- sprintf(b, "%f", v);
2367+ snprintf(b, sizeof(b), "%f", v);
2368 phpfbestrdup(b, length, value);
2369 }
2370 break;
2371@@ -2346,7 +2384,7 @@
2372 *length = l*2+3+1;
2373 if (value)
2374 {
2375- char* r = emalloc(l*2+3+1);
2376+ char* r = safe_emalloc(l, 2, 4);
2377 r[0] = 'X';
2378 r[1] = '\'';
2379 for (i = 0; i < nBits / 8; i++)
2380@@ -2368,7 +2406,7 @@
2381 *length = l*2+3+1;
2382 if (value)
2383 {
2384- char* r = emalloc(l*2+3+1);
2385+ char* r = safe_emalloc(l, 2, 4);
2386 r[0] = 'B';
2387 r[1] = '\'';
2388 for (i = 0; i < nBits; i++)
2389@@ -2400,7 +2438,7 @@
2390 {
2391 char b[128];
2392 int v = *((unsigned int*)data);
2393- sprintf(b, "%d", v);
2394+ snprintf(b, sizeof(b), "%d", v);
2395 phpfbestrdup(b, length, value);
2396 }
2397 break;
2398@@ -2409,7 +2447,7 @@
2399 {
2400 char b[128];
2401 double seconds = *((double*)data);
2402- sprintf(b, "%f", seconds);
2403+ snprintf(b, sizeof(b), "%f", seconds);
2404 phpfbestrdup(b, length, value);
2405 }
2406 break;
2407diff -Nur php-4.3.10/ext/mbstring/mbstring.c hardened-php-4.3.10-0.2.7/ext/mbstring/mbstring.c
2408--- php-4.3.10/ext/mbstring/mbstring.c 2004-06-24 00:07:01.000000000 +0200
2409+++ hardened-php-4.3.10-0.2.7/ext/mbstring/mbstring.c 2005-04-07 01:51:16.000000000 +0200
2410@@ -1467,12 +1467,13 @@
2411
2412 /* {{{ static void php_mbstr_encoding_handler() */
2413 static void
2414-php_mbstr_encoding_handler(zval *arg, char *res, char *separator TSRMLS_DC)
2415+php_mbstr_encoding_handler(zval *arg, int parse_type, char *res, char *separator TSRMLS_DC)
2416 {
2417 char *var, *val, *s1, *s2;
2418 char *strtok_buf = NULL, **val_list;
2419 zval *array_ptr = (zval *) arg;
2420 int n, num, val_len, *len_list, elistsz;
2421+ unsigned int new_val_len;
2422 enum mbfl_no_encoding from_encoding, to_encoding, *elist;
2423 mbfl_string string, resvar, resval;
2424 mbfl_encoding_detector *identd = NULL;
2425@@ -1593,8 +1594,14 @@
2426 val_len = len_list[n];
2427 }
2428 n++;
2429- /* add variable to symbol table */
2430- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
2431+ /* we need val to be emalloc()ed */
2432+ val = estrndup(val, val_len);
2433+ if (sapi_module.input_filter(parse_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
2434+ /* add variable to symbol table */
2435+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
2436+ }
2437+ efree(val);
2438+
2439 if (convd != NULL){
2440 mbfl_string_clear(&resvar);
2441 mbfl_string_clear(&resval);
2442@@ -1620,7 +1627,7 @@
2443 {
2444 MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
2445
2446- php_mbstr_encoding_handler(arg, SG(request_info).post_data, "&" TSRMLS_CC);
2447+ php_mbstr_encoding_handler(arg, PARSE_POST, SG(request_info).post_data, "&" TSRMLS_CC);
2448
2449 if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid) {
2450 MBSTRG(http_input_identify_post) = MBSTRG(http_input_identify);
2451@@ -1720,7 +1727,7 @@
2452 break;
2453 }
2454
2455- php_mbstr_encoding_handler(array_ptr, res, separator TSRMLS_CC);
2456+ php_mbstr_encoding_handler(array_ptr, arg, res, separator TSRMLS_CC);
2457
2458 if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid) {
2459 switch(arg){
2460diff -Nur php-4.3.10/ext/session/session.c hardened-php-4.3.10-0.2.7/ext/session/session.c
2461--- php-4.3.10/ext/session/session.c 2004-12-09 18:16:57.000000000 +0100
2462+++ hardened-php-4.3.10-0.2.7/ext/session/session.c 2005-04-07 01:54:27.000000000 +0200
2463@@ -408,7 +408,7 @@
2464 p += namelen + 1;
2465
2466 if (has_value) {
2467- MAKE_STD_ZVAL(current);
2468+ ALLOC_INIT_ZVAL(current);
2469 if (php_var_unserialize(&current, (const unsigned char **)&p, endptr, &var_hash TSRMLS_CC)) {
2470 php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
2471 }
2472@@ -488,7 +488,7 @@
2473 q++;
2474
2475 if (has_value) {
2476- MAKE_STD_ZVAL(current);
2477+ ALLOC_INIT_ZVAL(current);
2478 if (php_var_unserialize(&current, (const unsigned char **)&q, endptr, &var_hash TSRMLS_CC)) {
2479 php_set_session_var(name, namelen, current, &var_hash TSRMLS_CC);
2480 }
2481diff -Nur php-4.3.10/ext/standard/array.c hardened-php-4.3.10-0.2.7/ext/standard/array.c
2482--- php-4.3.10/ext/standard/array.c 2004-12-02 17:36:41.000000000 +0100
2483+++ hardened-php-4.3.10-0.2.7/ext/standard/array.c 2005-04-07 01:51:16.000000000 +0200
2484@@ -1153,6 +1153,31 @@
2485 }
2486 }
2487 }
2488+
2489+ if (var_name[0] == 'H') {
2490+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
2491+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
2492+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
2493+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
2494+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
2495+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
2496+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)) {
2497+ return 0;
2498+ }
2499+ } else if (var_name[0] == '_') {
2500+ if ((strcmp(var_name, "_COOKIE")==0)||
2501+ (strcmp(var_name, "_ENV")==0)||
2502+ (strcmp(var_name, "_FILES")==0)||
2503+ (strcmp(var_name, "_GET")==0)||
2504+ (strcmp(var_name, "_POST")==0)||
2505+ (strcmp(var_name, "_REQUEST")==0)||
2506+ (strcmp(var_name, "_SESSION")==0)||
2507+ (strcmp(var_name, "_SERVER")==0)) {
2508+ return 0;
2509+ }
2510+ } else if (strcmp(var_name, "GLOBALS")==0) {
2511+ return 0;
2512+ }
2513
2514 return 1;
2515 }
2516diff -Nur php-4.3.10/ext/standard/basic_functions.c hardened-php-4.3.10-0.2.7/ext/standard/basic_functions.c
2517--- php-4.3.10/ext/standard/basic_functions.c 2004-11-16 00:26:40.000000000 +0100
2518+++ hardened-php-4.3.10-0.2.7/ext/standard/basic_functions.c 2005-04-07 01:51:16.000000000 +0200
2519@@ -687,7 +687,7 @@
2520 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
2521
2522 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2523- PHP_FE(realpath, NULL)
2524+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
2525 #endif
2526
2527 #ifdef HAVE_FNMATCH
2528@@ -3008,6 +3008,34 @@
2529 memcpy(new_key, prefix, prefix_len);
2530 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
2531
2532+ if (new_key[0] == 'H') {
2533+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
2534+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
2535+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
2536+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
2537+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
2538+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
2539+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)) {
2540+ efree(new_key);
2541+ return 0;
2542+ }
2543+ } else if (new_key[0] == '_') {
2544+ if ((strcmp(new_key, "_COOKIE")==0)||
2545+ (strcmp(new_key, "_ENV")==0)||
2546+ (strcmp(new_key, "_FILES")==0)||
2547+ (strcmp(new_key, "_GET")==0)||
2548+ (strcmp(new_key, "_POST")==0)||
2549+ (strcmp(new_key, "_REQUEST")==0)||
2550+ (strcmp(new_key, "_SESSION")==0)||
2551+ (strcmp(new_key, "_SERVER")==0)) {
2552+ efree(new_key);
2553+ return 0;
2554+ }
2555+ } else if (strcmp(new_key, "GLOBALS")==0) {
2556+ efree(new_key);
2557+ return 0;
2558+ }
2559+
2560 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
2561 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
2562
2563diff -Nur php-4.3.10/ext/standard/file.c hardened-php-4.3.10-0.2.7/ext/standard/file.c
2564--- php-4.3.10/ext/standard/file.c 2004-12-08 22:15:02.000000000 +0100
2565+++ hardened-php-4.3.10-0.2.7/ext/standard/file.c 2005-04-07 01:51:16.000000000 +0200
2566@@ -2472,7 +2472,7 @@
2567 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2568 /* {{{ proto string realpath(string path)
2569 Return the resolved path */
2570-PHP_FUNCTION(realpath)
2571+PHP_FUNCTION(real_path)
2572 {
2573 zval **path;
2574 char resolved_path_buff[MAXPATHLEN];
2575diff -Nur php-4.3.10/ext/standard/file.h hardened-php-4.3.10-0.2.7/ext/standard/file.h
2576--- php-4.3.10/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
2577+++ hardened-php-4.3.10-0.2.7/ext/standard/file.h 2005-04-07 01:51:16.000000000 +0200
2578@@ -64,7 +64,7 @@
2579 PHP_FUNCTION(fd_set);
2580 PHP_FUNCTION(fd_isset);
2581 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2582-PHP_FUNCTION(realpath);
2583+PHP_FUNCTION(real_path);
2584 #endif
2585 #ifdef HAVE_FNMATCH
2586 PHP_FUNCTION(fnmatch);
2587diff -Nur php-4.3.10/ext/standard/image.c hardened-php-4.3.10-0.2.7/ext/standard/image.c
2588--- php-4.3.10/ext/standard/image.c 2004-10-04 22:44:07.000000000 +0200
2589+++ hardened-php-4.3.10-0.2.7/ext/standard/image.c 2005-04-07 01:51:16.000000000 +0200
2590@@ -17,7 +17,7 @@
2591 +----------------------------------------------------------------------+
2592 */
2593
2594-/* $Id: image.c,v 1.72.2.15 2004/10/04 20:44:07 iliaa Exp $ */
2595+/* $Id: image.c,v 1.72.2.18 2005/03/06 17:05:41 iliaa Exp $ */
2596
2597 #include "php.h"
2598 #include <stdio.h>
2599@@ -363,7 +363,7 @@
2600 /* just return 0 if we hit the end-of-file */
2601 if((php_stream_read(stream, a, sizeof(a))) <= 0) return 0;
2602
2603- return (((unsigned short) a[ 0 ]) << 8) + ((unsigned short) a[ 1 ]);
2604+ return (((unsigned short)a[0]) << 8) + ((unsigned short)a[1]);
2605 }
2606 /* }}} */
2607
2608@@ -374,7 +374,7 @@
2609 int a=0, marker;
2610
2611 /* get marker byte, swallowing possible padding */
2612- if ( last_marker==M_COM && comment_correction) {
2613+ if (last_marker==M_COM && comment_correction) {
2614 /* some software does not count the length bytes of COM section */
2615 /* one company doing so is very much envolved in JPEG... so we accept too */
2616 /* by the way: some of those companies changed their code now... */
2617@@ -383,7 +383,7 @@
2618 last_marker = 0;
2619 comment_correction = 0;
2620 }
2621- if ( ff_read) {
2622+ if (ff_read) {
2623 a = 1; /* already read 0xff in filetype detection */
2624 }
2625 do {
2626@@ -391,9 +391,9 @@
2627 {
2628 return M_EOI;/* we hit EOF */
2629 }
2630- if ( last_marker==M_COM && comment_correction>0)
2631+ if (last_marker==M_COM && comment_correction>0)
2632 {
2633- if ( marker != 0xFF)
2634+ if (marker != 0xFF)
2635 {
2636 marker = 0xff;
2637 comment_correction--;
2638@@ -401,14 +401,14 @@
2639 last_marker = M_PSEUDO; /* stop skipping non 0xff for M_COM */
2640 }
2641 }
2642- if ( ++a > 10)
2643+ if (++a > 10)
2644 {
2645 /* who knows the maxim amount of 0xff? though 7 */
2646 /* but found other implementations */
2647 return M_EOI;
2648 }
2649- } while ( marker == 0xff);
2650- if ( a < 2)
2651+ } while (marker == 0xff);
2652+ if (a < 2)
2653 {
2654 return M_EOI; /* at least one 0xff is needed before marker code */
2655 }
2656@@ -422,35 +422,39 @@
2657
2658 /* {{{ php_skip_variable
2659 * skip over a variable-length block; assumes proper length marker */
2660-static void php_skip_variable(php_stream * stream TSRMLS_DC)
2661+static int php_skip_variable(php_stream * stream TSRMLS_DC)
2662 {
2663 off_t length = ((unsigned int)php_read2(stream TSRMLS_CC));
2664
2665- length = length-2;
2666- if (length)
2667- {
2668- php_stream_seek(stream, (long)length, SEEK_CUR);
2669+ if (length < 2) {
2670+ return 0;
2671 }
2672+ length = length - 2;
2673+ php_stream_seek(stream, (long)length, SEEK_CUR);
2674+ return 1;
2675 }
2676 /* }}} */
2677
2678 /* {{{ php_read_APP
2679 */
2680-static void php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC)
2681+static int php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC)
2682 {
2683 unsigned short length;
2684 unsigned char *buffer;
2685- unsigned char markername[ 16 ];
2686+ unsigned char markername[16];
2687 zval *tmp;
2688
2689 length = php_read2(stream TSRMLS_CC);
2690+ if (length < 2) {
2691+ return 0;
2692+ }
2693 length -= 2; /* length includes itself */
2694
2695 buffer = emalloc(length);
2696
2697 if (php_stream_read(stream, buffer, (long) length) <= 0) {
2698 efree(buffer);
2699- return;
2700+ return 0;
2701 }
2702
2703 sprintf(markername, "APP%d", marker - M_APP0);
2704@@ -461,6 +465,7 @@
2705 }
2706
2707 efree(buffer);
2708+ return 1;
2709 }
2710 /* }}} */
2711
2712@@ -497,12 +502,16 @@
2713 result->height = php_read2(stream TSRMLS_CC);
2714 result->width = php_read2(stream TSRMLS_CC);
2715 result->channels = php_stream_getc(stream);
2716- if (!info || length<8) /* if we don't want an extanded info -> return */
2717+ if (!info || length < 8) { /* if we don't want an extanded info -> return */
2718 return result;
2719- if (php_stream_seek(stream, length-8, SEEK_CUR)) /* file error after info */
2720+ }
2721+ if (php_stream_seek(stream, length - 8, SEEK_CUR)) { /* file error after info */
2722 return result;
2723+ }
2724 } else {
2725- php_skip_variable(stream TSRMLS_CC);
2726+ if (!php_skip_variable(stream TSRMLS_CC)) {
2727+ return result;
2728+ }
2729 }
2730 break;
2731
2732@@ -523,9 +532,13 @@
2733 case M_APP14:
2734 case M_APP15:
2735 if (info) {
2736- php_read_APP(stream, marker, info TSRMLS_CC); /* read all the app markes... */
2737+ if (!php_read_APP(stream, marker, info TSRMLS_CC)) { /* read all the app markes... */
2738+ return result;
2739+ }
2740 } else {
2741- php_skip_variable(stream TSRMLS_CC);
2742+ if (!php_skip_variable(stream TSRMLS_CC)) {
2743+ return result;
2744+ }
2745 }
2746 break;
2747
2748@@ -534,7 +547,9 @@
2749 return result; /* we're about to hit image data, or are at EOF. stop processing. */
2750
2751 default:
2752- php_skip_variable(stream TSRMLS_CC); /* anything else isn't interesting */
2753+ if (!php_skip_variable(stream TSRMLS_CC)) { /* anything else isn't interesting */
2754+ return result;
2755+ }
2756 break;
2757 }
2758 }
2759@@ -613,17 +628,28 @@
2760
2761 dummy_short = php_read2(stream TSRMLS_CC); /* Lsiz */
2762 dummy_short = php_read2(stream TSRMLS_CC); /* Rsiz */
2763- result->height = php_read4(stream TSRMLS_CC); /* Xsiz */
2764 result->width = php_read4(stream TSRMLS_CC); /* Ysiz */
2765+ result->height = php_read4(stream TSRMLS_CC); /* Xsiz */
2766
2767+#if MBO_0
2768 dummy_int = php_read4(stream TSRMLS_CC); /* XOsiz */
2769 dummy_int = php_read4(stream TSRMLS_CC); /* YOsiz */
2770 dummy_int = php_read4(stream TSRMLS_CC); /* XTsiz */
2771 dummy_int = php_read4(stream TSRMLS_CC); /* YTsiz */
2772 dummy_int = php_read4(stream TSRMLS_CC); /* XTOsiz */
2773 dummy_int = php_read4(stream TSRMLS_CC); /* YTOsiz */
2774+#else
2775+ if (php_stream_seek(stream, 24, SEEK_CUR)) {
2776+ efree(result);
2777+ return NULL;
2778+ }
2779+#endif
2780
2781 result->channels = php_read2(stream TSRMLS_CC); /* Csiz */
2782+ if (result->channels < 0 || result->channels > 256) {
2783+ efree(result);
2784+ return NULL;
2785+ }
2786
2787 /* Collect bit depth info */
2788 highest_bit_depth = bit_depth = 0;
2789@@ -685,8 +711,15 @@
2790 break;
2791 }
2792
2793+ /* Stop if this was the last box */
2794+ if ((int)box_length <= 0) {
2795+ break;
2796+ }
2797+
2798 /* Skip over LBox (Which includes both TBox and LBox itself */
2799- php_stream_seek(stream, box_length - 8, SEEK_CUR);
2800+ if (php_stream_seek(stream, box_length - 8, SEEK_CUR)) {
2801+ break;
2802+ }
2803 }
2804
2805 if (result == NULL) {
2806@@ -849,43 +882,49 @@
2807 */
2808 static struct gfxinfo *php_handle_iff(php_stream * stream TSRMLS_DC)
2809 {
2810- struct gfxinfo *result = NULL;
2811+ struct gfxinfo * result;
2812 unsigned char a[10];
2813 int chunkId;
2814 int size;
2815+ short width, height, bits;
2816
2817- if (php_stream_read(stream, a, 8) != 8)
2818+ if (php_stream_read(stream, a, 8) != 8) {
2819 return NULL;
2820- if (strncmp(a+4, "ILBM", 4) && strncmp(a+4, "PBM ", 4))
2821+ }
2822+ if (strncmp(a+4, "ILBM", 4) && strncmp(a+4, "PBM ", 4)) {
2823 return NULL;
2824-
2825- result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
2826+ }
2827
2828 /* loop chunks to find BMHD chunk */
2829 do {
2830 if (php_stream_read(stream, a, 8) != 8) {
2831- efree(result);
2832 return NULL;
2833 }
2834 chunkId = php_ifd_get32s(a+0, 1);
2835 size = php_ifd_get32s(a+4, 1);
2836+ if (size < 0) {
2837+ return NULL;
2838+ }
2839 if ((size & 1) == 1) {
2840 size++;
2841 }
2842 if (chunkId == 0x424d4844) { /* BMHD chunk */
2843- if (php_stream_read(stream, a, 9) != 9) {
2844- efree(result);
2845+ if (size < 9 || php_stream_read(stream, a, 9) != 9) {
2846 return NULL;
2847 }
2848- result->width = php_ifd_get16s(a+0, 1);
2849- result->height = php_ifd_get16s(a+2, 1);
2850- result->bits = a[8] & 0xff;
2851+ width = php_ifd_get16s(a+0, 1);
2852+ height = php_ifd_get16s(a+2, 1);
2853+ bits = a[8] & 0xff;
2854+ if (width > 0 && height > 0 && bits > 0 && bits < 33) {
2855+ result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
2856+ result->width = width;
2857+ result->height = height;
2858+ result->bits = bits;
2859 result->channels = 0;
2860- if (result->width > 0 && result->height > 0 && result->bits > 0 && result->bits < 33)
2861 return result;
2862+ }
2863 } else {
2864 if (php_stream_seek(stream, size, SEEK_CUR)) {
2865- efree(result);
2866 return NULL;
2867 }
2868 }
2869@@ -1230,11 +1269,14 @@
2870 case IMAGE_FILETYPE_SWF:
2871 result = php_handle_swf(stream TSRMLS_CC);
2872 break;
2873-#if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
2874 case IMAGE_FILETYPE_SWC:
2875+#if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
2876 result = php_handle_swc(stream TSRMLS_CC);
2877- break;
2878+#else
2879+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The image is a compressed SWF file, but you do not have a static version of the zlib extension enabled.");
2880+
2881 #endif
2882+ break;
2883 case IMAGE_FILETYPE_PSD:
2884 result = php_handle_psd(stream TSRMLS_CC);
2885 break;
2886diff -Nur php-4.3.10/ext/standard/info.c hardened-php-4.3.10-0.2.7/ext/standard/info.c
2887--- php-4.3.10/ext/standard/info.c 2004-06-09 17:10:19.000000000 +0200
2888+++ hardened-php-4.3.10-0.2.7/ext/standard/info.c 2005-04-07 01:51:16.000000000 +0200
2889@@ -397,7 +397,7 @@
2890
2891 if (flag & PHP_INFO_GENERAL) {
2892 char *zend_version = get_zend_version();
2893- char temp_api[9];
2894+ char temp_api[11];
2895
2896 php_uname = php_get_uname('a');
2897
2898@@ -417,11 +417,22 @@
2899 }
2900 }
2901
2902+#if HARDENED_PHP
2903+ if (!sapi_module.phpinfo_as_text) {
2904+ php_printf("<h1 class=\"p\">Hardened-PHP Version %s/%s</h1>\n", PHP_VERSION, HARDENED_PHP_VERSION);
2905+ } else {
2906+ char temp_ver[40];
2907+
2908+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENED_PHP_VERSION);
2909+ php_info_print_table_row(2, "Hardened-PHP Version", temp_ver);
2910+ }
2911+#else
2912 if (!sapi_module.phpinfo_as_text) {
2913 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2914 } else {
2915 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2916 }
2917+#endif
2918 php_info_print_box_end();
2919 php_info_print_table_start();
2920 php_info_print_table_row(2, "System", php_uname );
2921diff -Nur php-4.3.10/ext/standard/pack.c hardened-php-4.3.10-0.2.7/ext/standard/pack.c
2922--- php-4.3.10/ext/standard/pack.c 2004-11-28 13:44:56.000000000 +0100
2923+++ hardened-php-4.3.10-0.2.7/ext/standard/pack.c 2005-04-07 01:51:16.000000000 +0200
2924@@ -15,7 +15,7 @@
2925 | Author: Chris Schneider <cschneid@relog.ch> |
2926 +----------------------------------------------------------------------+
2927 */
2928-/* $Id: pack.c,v 1.40.2.6 2004/11/28 12:44:56 sesser Exp $ */
2929+/* $Id: pack.c,v 1.40.2.7 2005/01/25 22:52:19 iliaa Exp $ */
2930
2931 #include "php.h"
2932
2933@@ -833,7 +833,9 @@
2934
2935 inputpos += size;
2936 if (inputpos < 0) {
2937- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: outside of string", type);
2938+ if (size != -1) { /* only print warning if not working with * */
2939+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type %c: outside of string", type);
2940+ }
2941 inputpos = 0;
2942 }
2943 } else if (arg < 0) {
2944diff -Nur php-4.3.10/ext/standard/php_var.h hardened-php-4.3.10-0.2.7/ext/standard/php_var.h
2945--- php-4.3.10/ext/standard/php_var.h 2004-09-24 23:57:18.000000000 +0200
2946+++ hardened-php-4.3.10-0.2.7/ext/standard/php_var.h 2005-04-07 01:51:16.000000000 +0200
2947@@ -16,7 +16,7 @@
2948 +----------------------------------------------------------------------+
2949 */
2950
2951-/* $Id: php_var.h,v 1.21.4.4 2004/09/24 21:57:18 helly Exp $ */
2952+/* $Id: php_var.h,v 1.21.4.5 2005/01/15 18:44:29 sesser Exp $ */
2953
2954 #ifndef PHP_VAR_H
2955 #define PHP_VAR_H
2956@@ -41,6 +41,7 @@
2957
2958 struct php_unserialize_data {
2959 void *first;
2960+ void *first_dtor;
2961 };
2962
2963 typedef struct php_unserialize_data php_unserialize_data_t;
2964@@ -54,7 +55,8 @@
2965 zend_hash_destroy(&(var_hash))
2966
2967 #define PHP_VAR_UNSERIALIZE_INIT(var_hash) \
2968- (var_hash).first = 0
2969+ (var_hash).first = 0; \
2970+ (var_hash).first_dtor = 0
2971 #define PHP_VAR_UNSERIALIZE_DESTROY(var_hash) \
2972 var_destroy(&(var_hash))
2973
2974diff -Nur php-4.3.10/ext/standard/var_unserializer.c hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.c
2975--- php-4.3.10/ext/standard/var_unserializer.c 2004-12-14 18:55:22.000000000 +0100
2976+++ hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.c 2005-04-07 01:51:16.000000000 +0200
2977@@ -1,4 +1,4 @@
2978-/* Generated by re2c 0.5 on Thu Nov 18 17:11:01 2004 */
2979+/* Generated by re2c 0.9.4 on Thu Mar 10 02:59:20 2005 */
2980 /*
2981 +----------------------------------------------------------------------+
2982 | PHP Version 4 |
2983@@ -17,7 +17,7 @@
2984 +----------------------------------------------------------------------+
2985 */
2986
2987-/* $Id: var_unserializer.c,v 1.18.4.14 2004/12/03 16:09:19 sesser Exp $ */
2988+/* $Id: var_unserializer.c,v 1.18.4.23 2005/03/10 02:01:40 helly Exp $ */
2989
2990 #include "php.h"
2991 #include "ext/standard/php_var.h"
2992@@ -28,7 +28,7 @@
2993
2994 typedef struct {
2995 zval *data[VAR_ENTRIES_MAX];
2996- int used_slots;
2997+ long used_slots;
2998 void *next;
2999 } var_entries;
3000
3001@@ -55,9 +55,33 @@
3002 var_hash->data[var_hash->used_slots++] = *rval;
3003 }
3004
3005+static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
3006+{
3007+ var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
3008+
3009+ while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
3010+ prev = var_hash;
3011+ var_hash = var_hash->next;
3012+ }
3013+
3014+ if (!var_hash) {
3015+ var_hash = emalloc(sizeof(var_entries));
3016+ var_hash->used_slots = 0;
3017+ var_hash->next = 0;
3018+
3019+ if (!var_hashx->first_dtor)
3020+ var_hashx->first_dtor = var_hash;
3021+ else
3022+ prev->next = var_hash;
3023+ }
3024+
3025+ (*rval)->refcount++;
3026+ var_hash->data[var_hash->used_slots++] = *rval;
3027+}
3028+
3029 PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
3030 {
3031- int i;
3032+ long i;
3033 var_entries *var_hash = var_hashx->first;
3034
3035 while (var_hash) {
3036@@ -71,7 +95,7 @@
3037 }
3038 }
3039
3040-static int var_access(php_unserialize_data_t *var_hashx, int id, zval ***store)
3041+static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
3042 {
3043 var_entries *var_hash = var_hashx->first;
3044
3045@@ -92,6 +116,7 @@
3046 PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
3047 {
3048 void *next;
3049+ long i;
3050 var_entries *var_hash = var_hashx->first;
3051
3052 while (var_hash) {
3053@@ -99,6 +124,17 @@
3054 efree(var_hash);
3055 var_hash = next;
3056 }
3057+
3058+ var_hash = var_hashx->first_dtor;
3059+
3060+ while (var_hash) {
3061+ for (i = 0; i < var_hash->used_slots; i++) {
3062+ zval_ptr_dtor(&var_hash->data[i]);
3063+ }
3064+ next = var_hash->next;
3065+ efree(var_hash);
3066+ var_hash = next;
3067+ }
3068 }
3069
3070 /* }}} */
3071@@ -114,10 +150,10 @@
3072
3073
3074
3075-static inline int parse_iv2(const unsigned char *p, const unsigned char **q)
3076+static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
3077 {
3078 char cursor;
3079- int result = 0;
3080+ long result = 0;
3081 int neg = 0;
3082
3083 switch (*p) {
3084@@ -142,7 +178,7 @@
3085 return result;
3086 }
3087
3088-static inline int parse_iv(const unsigned char *p)
3089+static inline long parse_iv(const unsigned char *p)
3090 {
3091 return parse_iv2(p, NULL);
3092 }
3093@@ -172,10 +208,10 @@
3094 #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
3095 #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
3096
3097-static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int elements)
3098+static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
3099 {
3100 while (elements-- > 0) {
3101- zval *key, *data, *old_data;
3102+ zval *key, *data, **old_data;
3103
3104 ALLOC_INIT_ZVAL(key);
3105
3106@@ -203,14 +239,14 @@
3107
3108 switch (Z_TYPE_P(key)) {
3109 case IS_LONG:
3110- if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)) {
3111- var_replace(var_hash, old_data, rval);
3112+ if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
3113+ var_push_dtor(var_hash, old_data);
3114 }
3115 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
3116 break;
3117 case IS_STRING:
3118- if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)) {
3119- var_replace(var_hash, old_data, rval);
3120+ if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
3121+ var_push_dtor(var_hash, old_data);
3122 }
3123 zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
3124 break;
3125@@ -241,7 +277,7 @@
3126
3127 static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
3128 {
3129- int elements;
3130+ long elements;
3131
3132 elements = parse_iv2((*p) + 2, p);
3133
3134@@ -251,7 +287,7 @@
3135 return elements;
3136 }
3137
3138-static inline int object_common2(UNSERIALIZE_PARAMETER, int elements)
3139+static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
3140 {
3141 zval *retval_ptr = NULL;
3142 zval fname;
3143@@ -300,6 +336,7 @@
3144
3145
3146
3147+
3148 {
3149 YYCTYPE yych;
3150 unsigned int yyaccept;
3151@@ -378,7 +415,8 @@
3152 goto yy16;
3153 } else {
3154 if(yych <= '}') goto yy14;
3155- if(yych <= '\277') goto yy16;
3156+ if(yych <= 0xBF) goto yy16;
3157+ goto yy2;
3158 }
3159 }
3160 }
3161@@ -389,8 +427,9 @@
3162 yy3: yyaccept = 0;
3163 yych = *(YYMARKER = ++YYCURSOR);
3164 if(yych == ':') goto yy87;
3165+ goto yy4;
3166 yy4:
3167- { return 0; }
3168+{ return 0; }
3169 yy5: yyaccept = 0;
3170 yych = *(YYMARKER = ++YYCURSOR);
3171 if(yych == ':') goto yy81;
3172@@ -426,9 +465,10 @@
3173 yych = *(YYMARKER = ++YYCURSOR);
3174 if(yych == ':') goto yy17;
3175 goto yy4;
3176-yy14: yych = *++YYCURSOR;
3177+yy14: ++YYCURSOR;
3178+ goto yy15;
3179 yy15:
3180- {
3181+{
3182 /* this is the case where we have less data than planned */
3183 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
3184 return 0; /* not sure if it should be 0 or 1 here? */
3185@@ -438,21 +478,26 @@
3186 yy17: yych = *++YYCURSOR;
3187 if(yybm[0+yych] & 128) goto yy19;
3188 if(yych != '+') goto yy2;
3189+ goto yy18;
3190 yy18: yych = *++YYCURSOR;
3191 if(yybm[0+yych] & 128) goto yy19;
3192 goto yy2;
3193 yy19: ++YYCURSOR;
3194 if(YYLIMIT == YYCURSOR) YYFILL(1);
3195 yych = *YYCURSOR;
3196+ goto yy20;
3197 yy20: if(yybm[0+yych] & 128) goto yy19;
3198 if(yych != ':') goto yy2;
3199+ goto yy21;
3200 yy21: yych = *++YYCURSOR;
3201 if(yych != '"') goto yy2;
3202-yy22: yych = *++YYCURSOR;
3203+ goto yy22;
3204+yy22: ++YYCURSOR;
3205+ goto yy23;
3206 yy23:
3207- {
3208- size_t len, len2, maxlen;
3209- int elements;
3210+{
3211+ size_t len, len2, len3, maxlen;
3212+ long elements;
3213 char *class_name;
3214 zend_class_entry *ce;
3215 int incomplete_class = 0;
3216@@ -486,6 +531,14 @@
3217 class_name = str_tolower_copy((char *)emalloc(len+1), class_name, len);
3218 class_name[len] = '\0';
3219
3220+ len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyz");
3221+ if (len3 != len)
3222+ {
3223+ *p = YYCURSOR + len3 - len;
3224+ efree(class_name);
3225+ return 0;
3226+ }
3227+
3228 if (zend_hash_find(CG(class_table), class_name, len + 1, (void **) &ce) != SUCCESS) {
3229 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
3230 incomplete_class = 1;
3231@@ -533,6 +586,7 @@
3232 yy24: yych = *++YYCURSOR;
3233 if(yych <= ','){
3234 if(yych != '+') goto yy2;
3235+ goto yy25;
3236 } else {
3237 if(yych <= '-') goto yy25;
3238 if(yych <= '/') goto yy2;
3239@@ -542,17 +596,22 @@
3240 yy25: yych = *++YYCURSOR;
3241 if(yych <= '/') goto yy2;
3242 if(yych >= ':') goto yy2;
3243+ goto yy26;
3244 yy26: ++YYCURSOR;
3245 if(YYLIMIT == YYCURSOR) YYFILL(1);
3246 yych = *YYCURSOR;
3247+ goto yy27;
3248 yy27: if(yych <= '/') goto yy2;
3249 if(yych <= '9') goto yy26;
3250 if(yych >= ';') goto yy2;
3251+ goto yy28;
3252 yy28: yych = *++YYCURSOR;
3253 if(yych != '"') goto yy2;
3254-yy29: yych = *++YYCURSOR;
3255+ goto yy29;
3256+yy29: ++YYCURSOR;
3257+ goto yy30;
3258 yy30:
3259- {
3260+{
3261
3262 INIT_PZVAL(*rval);
3263
3264@@ -567,21 +626,34 @@
3265 yy32: yych = *++YYCURSOR;
3266 if(yych <= '/') goto yy2;
3267 if(yych >= ':') goto yy2;
3268+ goto yy33;
3269 yy33: ++YYCURSOR;
3270 if(YYLIMIT == YYCURSOR) YYFILL(1);
3271 yych = *YYCURSOR;
3272+ goto yy34;
3273 yy34: if(yych <= '/') goto yy2;
3274 if(yych <= '9') goto yy33;
3275 if(yych >= ';') goto yy2;
3276+ goto yy35;
3277 yy35: yych = *++YYCURSOR;
3278 if(yych != '{') goto yy2;
3279-yy36: yych = *++YYCURSOR;
3280+ goto yy36;
3281+yy36: ++YYCURSOR;
3282+ goto yy37;
3283 yy37:
3284- {
3285- int elements = parse_iv(start + 2);
3286-
3287+{
3288+ long elements = parse_iv(start + 2);
3289+ /* use iv() not uiv() in order to check data range */
3290 *p = YYCURSOR;
3291
3292+ if (elements < 0) {
3293+ return 0;
3294+ }
3295+
3296+ if (elements < 0) {
3297+ return 0;
3298+ }
3299+
3300 INIT_PZVAL(*rval);
3301 Z_TYPE_PP(rval) = IS_ARRAY;
3302 ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
3303@@ -602,17 +674,22 @@
3304 yy39: yych = *++YYCURSOR;
3305 if(yych <= '/') goto yy2;
3306 if(yych >= ':') goto yy2;
3307+ goto yy40;
3308 yy40: ++YYCURSOR;
3309 if(YYLIMIT == YYCURSOR) YYFILL(1);
3310 yych = *YYCURSOR;
3311+ goto yy41;
3312 yy41: if(yych <= '/') goto yy2;
3313 if(yych <= '9') goto yy40;
3314 if(yych >= ';') goto yy2;
3315+ goto yy42;
3316 yy42: yych = *++YYCURSOR;
3317 if(yych != '"') goto yy2;
3318-yy43: yych = *++YYCURSOR;
3319+ goto yy43;
3320+yy43: ++YYCURSOR;
3321+ goto yy44;
3322 yy44:
3323- {
3324+{
3325 size_t len, maxlen;
3326 char *str;
3327
3328@@ -656,6 +733,7 @@
3329 goto yy48;
3330 } else {
3331 if(yych != 'N') goto yy2;
3332+ goto yy46;
3333 }
3334 }
3335 yy46: yych = *++YYCURSOR;
3336@@ -668,6 +746,7 @@
3337 } else {
3338 if(yych <= '9') goto yy50;
3339 if(yych != 'I') goto yy2;
3340+ goto yy48;
3341 }
3342 yy48: yych = *++YYCURSOR;
3343 if(yych == 'N') goto yy64;
3344@@ -676,9 +755,11 @@
3345 if(yych == '.') goto yy52;
3346 if(yych <= '/') goto yy2;
3347 if(yych >= ':') goto yy2;
3348+ goto yy50;
3349 yy50: ++YYCURSOR;
3350 if(YYLIMIT == YYCURSOR) YYFILL(1);
3351 yych = *YYCURSOR;
3352+ goto yy51;
3353 yy51: if(yych <= ':'){
3354 if(yych <= '.'){
3355 if(yych <= '-') goto yy2;
3356@@ -701,13 +782,16 @@
3357 yy52: yych = *++YYCURSOR;
3358 if(yych <= '/') goto yy2;
3359 if(yych >= ':') goto yy2;
3360+ goto yy53;
3361 yy53: ++YYCURSOR;
3362 if(YYLIMIT == YYCURSOR) YYFILL(1);
3363 yych = *YYCURSOR;
3364+ goto yy54;
3365 yy54: if(yych <= ';'){
3366 if(yych <= '/') goto yy2;
3367 if(yych <= '9') goto yy53;
3368 if(yych <= ':') goto yy2;
3369+ goto yy55;
3370 } else {
3371 if(yych <= 'E'){
3372 if(yych <= 'D') goto yy2;
3373@@ -717,17 +801,19 @@
3374 goto yy2;
3375 }
3376 }
3377-yy55: yych = *++YYCURSOR;
3378+yy55: ++YYCURSOR;
3379+ goto yy56;
3380 yy56:
3381- {
3382+{
3383 *p = YYCURSOR;
3384 INIT_PZVAL(*rval);
3385- ZVAL_DOUBLE(*rval, atof(start + 2));
3386+ ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
3387 return 1;
3388 }
3389 yy57: yych = *++YYCURSOR;
3390 if(yych <= ','){
3391 if(yych != '+') goto yy2;
3392+ goto yy58;
3393 } else {
3394 if(yych <= '-') goto yy58;
3395 if(yych <= '/') goto yy2;
3396@@ -742,10 +828,12 @@
3397 if(yych <= '-') goto yy61;
3398 if(yych <= '/') goto yy2;
3399 if(yych >= ':') goto yy2;
3400+ goto yy59;
3401 }
3402 yy59: ++YYCURSOR;
3403 if(YYLIMIT == YYCURSOR) YYFILL(1);
3404 yych = *YYCURSOR;
3405+ goto yy60;
3406 yy60: if(yych <= '/') goto yy2;
3407 if(yych <= '9') goto yy59;
3408 if(yych == ';') goto yy55;
3409@@ -757,6 +845,7 @@
3410 yy62: ++YYCURSOR;
3411 if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
3412 yych = *YYCURSOR;
3413+ goto yy63;
3414 yy63: if(yych <= ';'){
3415 if(yych <= '/') goto yy2;
3416 if(yych <= '9') goto yy62;
3417@@ -773,16 +862,17 @@
3418 }
3419 yy64: yych = *++YYCURSOR;
3420 if(yych != 'F') goto yy2;
3421+ goto yy65;
3422 yy65: yych = *++YYCURSOR;
3423 if(yych != ';') goto yy2;
3424-yy66: yych = *++YYCURSOR;
3425+ goto yy66;
3426+yy66: ++YYCURSOR;
3427+ goto yy67;
3428 yy67:
3429- {
3430+{
3431 *p = YYCURSOR;
3432 INIT_PZVAL(*rval);
3433-#if defined(HAVE_ATOF_ACCEPTS_NAN) && defined(HAVE_ATOF_ACCEPTS_INF)
3434- ZVAL_DOUBLE(*rval, atof(start + 2));
3435-#else
3436+
3437 if (!strncmp(start + 2, "NAN", 3)) {
3438 ZVAL_DOUBLE(*rval, php_get_nan());
3439 } else if (!strncmp(start + 2, "INF", 3)) {
3440@@ -790,7 +880,7 @@
3441 } else if (!strncmp(start + 2, "-INF", 4)) {
3442 ZVAL_DOUBLE(*rval, -php_get_inf());
3443 }
3444-#endif
3445+
3446 return 1;
3447 }
3448 yy68: yych = *++YYCURSOR;
3449@@ -799,6 +889,7 @@
3450 yy69: yych = *++YYCURSOR;
3451 if(yych <= ','){
3452 if(yych != '+') goto yy2;
3453+ goto yy70;
3454 } else {
3455 if(yych <= '-') goto yy70;
3456 if(yych <= '/') goto yy2;
3457@@ -808,15 +899,19 @@
3458 yy70: yych = *++YYCURSOR;
3459 if(yych <= '/') goto yy2;
3460 if(yych >= ':') goto yy2;
3461+ goto yy71;
3462 yy71: ++YYCURSOR;
3463 if(YYLIMIT == YYCURSOR) YYFILL(1);
3464 yych = *YYCURSOR;
3465+ goto yy72;
3466 yy72: if(yych <= '/') goto yy2;
3467 if(yych <= '9') goto yy71;
3468 if(yych != ';') goto yy2;
3469-yy73: yych = *++YYCURSOR;
3470+ goto yy73;
3471+yy73: ++YYCURSOR;
3472+ goto yy74;
3473 yy74:
3474- {
3475+{
3476 *p = YYCURSOR;
3477 INIT_PZVAL(*rval);
3478 ZVAL_LONG(*rval, parse_iv(start + 2));
3479@@ -825,19 +920,23 @@
3480 yy75: yych = *++YYCURSOR;
3481 if(yych <= '/') goto yy2;
3482 if(yych >= '2') goto yy2;
3483+ goto yy76;
3484 yy76: yych = *++YYCURSOR;
3485 if(yych != ';') goto yy2;
3486-yy77: yych = *++YYCURSOR;
3487+ goto yy77;
3488+yy77: ++YYCURSOR;
3489+ goto yy78;
3490 yy78:
3491- {
3492+{
3493 *p = YYCURSOR;
3494 INIT_PZVAL(*rval);
3495 ZVAL_BOOL(*rval, parse_iv(start + 2));
3496 return 1;
3497 }
3498-yy79: yych = *++YYCURSOR;
3499+yy79: ++YYCURSOR;
3500+ goto yy80;
3501 yy80:
3502- {
3503+{
3504 *p = YYCURSOR;
3505 INIT_PZVAL(*rval);
3506 ZVAL_NULL(*rval);
3507@@ -846,6 +945,7 @@
3508 yy81: yych = *++YYCURSOR;
3509 if(yych <= ','){
3510 if(yych != '+') goto yy2;
3511+ goto yy82;
3512 } else {
3513 if(yych <= '-') goto yy82;
3514 if(yych <= '/') goto yy2;
3515@@ -855,16 +955,20 @@
3516 yy82: yych = *++YYCURSOR;
3517 if(yych <= '/') goto yy2;
3518 if(yych >= ':') goto yy2;
3519+ goto yy83;
3520 yy83: ++YYCURSOR;
3521 if(YYLIMIT == YYCURSOR) YYFILL(1);
3522 yych = *YYCURSOR;
3523+ goto yy84;
3524 yy84: if(yych <= '/') goto yy2;
3525 if(yych <= '9') goto yy83;
3526 if(yych != ';') goto yy2;
3527-yy85: yych = *++YYCURSOR;
3528+ goto yy85;
3529+yy85: ++YYCURSOR;
3530+ goto yy86;
3531 yy86:
3532- {
3533- int id;
3534+{
3535+ long id;
3536
3537 *p = YYCURSOR;
3538 if (!var_hash) return 0;
3539@@ -873,7 +977,7 @@
3540 if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
3541 return 0;
3542 }
3543-
3544+
3545 if (*rval == *rval_ref) return 0;
3546
3547 if (*rval != NULL) {
3548@@ -888,6 +992,7 @@
3549 yy87: yych = *++YYCURSOR;
3550 if(yych <= ','){
3551 if(yych != '+') goto yy2;
3552+ goto yy88;
3553 } else {
3554 if(yych <= '-') goto yy88;
3555 if(yych <= '/') goto yy2;
3556@@ -897,16 +1002,20 @@
3557 yy88: yych = *++YYCURSOR;
3558 if(yych <= '/') goto yy2;
3559 if(yych >= ':') goto yy2;
3560+ goto yy89;
3561 yy89: ++YYCURSOR;
3562 if(YYLIMIT == YYCURSOR) YYFILL(1);
3563 yych = *YYCURSOR;
3564+ goto yy90;
3565 yy90: if(yych <= '/') goto yy2;
3566 if(yych <= '9') goto yy89;
3567 if(yych != ';') goto yy2;
3568-yy91: yych = *++YYCURSOR;
3569+ goto yy91;
3570+yy91: ++YYCURSOR;
3571+ goto yy92;
3572 yy92:
3573- {
3574- int id;
3575+{
3576+ long id;
3577
3578 *p = YYCURSOR;
3579 if (!var_hash) return 0;
3580diff -Nur php-4.3.10/ext/standard/var_unserializer.c.orig hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.c.orig
3581--- php-4.3.10/ext/standard/var_unserializer.c.orig 2004-12-14 18:55:22.000000000 +0100
3582+++ hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.c.orig 2005-04-07 01:51:16.000000000 +0200
3583@@ -1,5 +1,5 @@
3584-/* Generated by re2c 0.5 on Thu Nov 18 17:11:01 2004 */
3585-#line 1 "/home/rei/php4/ext/standard/var_unserializer.re"
3586+/* Generated by re2c 0.9.4 on Thu Mar 10 02:59:20 2005 */
3587+#line 1 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3588 /*
3589 +----------------------------------------------------------------------+
3590 | PHP Version 4 |
3591@@ -18,7 +18,7 @@
3592 +----------------------------------------------------------------------+
3593 */
3594
3595-/* $Id: var_unserializer.c,v 1.18.4.14 2004/12/03 16:09:19 sesser Exp $ */
3596+/* $Id: var_unserializer.c,v 1.18.4.23 2005/03/10 02:01:40 helly Exp $ */
3597
3598 #include "php.h"
3599 #include "ext/standard/php_var.h"
3600@@ -29,7 +29,7 @@
3601
3602 typedef struct {
3603 zval *data[VAR_ENTRIES_MAX];
3604- int used_slots;
3605+ long used_slots;
3606 void *next;
3607 } var_entries;
3608
3609@@ -56,9 +56,33 @@
3610 var_hash->data[var_hash->used_slots++] = *rval;
3611 }
3612
3613+static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
3614+{
3615+ var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
3616+
3617+ while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
3618+ prev = var_hash;
3619+ var_hash = var_hash->next;
3620+ }
3621+
3622+ if (!var_hash) {
3623+ var_hash = emalloc(sizeof(var_entries));
3624+ var_hash->used_slots = 0;
3625+ var_hash->next = 0;
3626+
3627+ if (!var_hashx->first_dtor)
3628+ var_hashx->first_dtor = var_hash;
3629+ else
3630+ prev->next = var_hash;
3631+ }
3632+
3633+ (*rval)->refcount++;
3634+ var_hash->data[var_hash->used_slots++] = *rval;
3635+}
3636+
3637 PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
3638 {
3639- int i;
3640+ long i;
3641 var_entries *var_hash = var_hashx->first;
3642
3643 while (var_hash) {
3644@@ -72,7 +96,7 @@
3645 }
3646 }
3647
3648-static int var_access(php_unserialize_data_t *var_hashx, int id, zval ***store)
3649+static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
3650 {
3651 var_entries *var_hash = var_hashx->first;
3652
3653@@ -93,6 +117,7 @@
3654 PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
3655 {
3656 void *next;
3657+ long i;
3658 var_entries *var_hash = var_hashx->first;
3659
3660 while (var_hash) {
3661@@ -100,6 +125,17 @@
3662 efree(var_hash);
3663 var_hash = next;
3664 }
3665+
3666+ var_hash = var_hashx->first_dtor;
3667+
3668+ while (var_hash) {
3669+ for (i = 0; i < var_hash->used_slots; i++) {
3670+ zval_ptr_dtor(&var_hash->data[i]);
3671+ }
3672+ next = var_hash->next;
3673+ efree(var_hash);
3674+ var_hash = next;
3675+ }
3676 }
3677
3678 /* }}} */
3679@@ -111,15 +147,15 @@
3680 #define YYMARKER marker
3681
3682
3683-#line 118
3684+#line 154 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3685
3686
3687
3688
3689-static inline int parse_iv2(const unsigned char *p, const unsigned char **q)
3690+static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
3691 {
3692 char cursor;
3693- int result = 0;
3694+ long result = 0;
3695 int neg = 0;
3696
3697 switch (*p) {
3698@@ -144,7 +180,7 @@
3699 return result;
3700 }
3701
3702-static inline int parse_iv(const unsigned char *p)
3703+static inline long parse_iv(const unsigned char *p)
3704 {
3705 return parse_iv2(p, NULL);
3706 }
3707@@ -174,10 +210,10 @@
3708 #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
3709 #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
3710
3711-static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int elements)
3712+static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
3713 {
3714 while (elements-- > 0) {
3715- zval *key, *data, *old_data;
3716+ zval *key, *data, **old_data;
3717
3718 ALLOC_INIT_ZVAL(key);
3719
3720@@ -205,14 +241,14 @@
3721
3722 switch (Z_TYPE_P(key)) {
3723 case IS_LONG:
3724- if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)) {
3725- var_replace(var_hash, old_data, rval);
3726+ if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
3727+ var_push_dtor(var_hash, old_data);
3728 }
3729 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
3730 break;
3731 case IS_STRING:
3732- if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)) {
3733- var_replace(var_hash, old_data, rval);
3734+ if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
3735+ var_push_dtor(var_hash, old_data);
3736 }
3737 zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
3738 break;
3739@@ -243,7 +279,7 @@
3740
3741 static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
3742 {
3743- int elements;
3744+ long elements;
3745
3746 elements = parse_iv2((*p) + 2, p);
3747
3748@@ -253,7 +289,7 @@
3749 return elements;
3750 }
3751
3752-static inline int object_common2(UNSERIALIZE_PARAMETER, int elements)
3753+static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
3754 {
3755 zval *retval_ptr = NULL;
3756 zval fname;
3757@@ -302,6 +338,8 @@
3758
3759
3760
3761+
3762+#line 7 "<stdout>"
3763 {
3764 YYCTYPE yych;
3765 unsigned int yyaccept;
3766@@ -380,7 +418,8 @@
3767 goto yy16;
3768 } else {
3769 if(yych <= '}') goto yy14;
3770- if(yych <= '\277') goto yy16;
3771+ if(yych <= 0xBF) goto yy16;
3772+ goto yy2;
3773 }
3774 }
3775 }
3776@@ -391,9 +430,11 @@
3777 yy3: yyaccept = 0;
3778 yych = *(YYMARKER = ++YYCURSOR);
3779 if(yych == ':') goto yy87;
3780+ goto yy4;
3781 yy4:
3782-#line 532
3783- { return 0; }
3784+#line 590 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3785+{ return 0; }
3786+#line 102 "<stdout>"
3787 yy5: yyaccept = 0;
3788 yych = *(YYMARKER = ++YYCURSOR);
3789 if(yych == ':') goto yy81;
3790@@ -429,35 +470,42 @@
3791 yych = *(YYMARKER = ++YYCURSOR);
3792 if(yych == ':') goto yy17;
3793 goto yy4;
3794-yy14: yych = *++YYCURSOR;
3795+yy14: ++YYCURSOR;
3796+ goto yy15;
3797 yy15:
3798-#line 526
3799- {
3800+#line 584 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3801+{
3802 /* this is the case where we have less data than planned */
3803 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
3804 return 0; /* not sure if it should be 0 or 1 here? */
3805 }
3806+#line 147 "<stdout>"
3807 yy16: yych = *++YYCURSOR;
3808 goto yy4;
3809 yy17: yych = *++YYCURSOR;
3810 if(yybm[0+yych] & 128) goto yy19;
3811 if(yych != '+') goto yy2;
3812+ goto yy18;
3813 yy18: yych = *++YYCURSOR;
3814 if(yybm[0+yych] & 128) goto yy19;
3815 goto yy2;
3816 yy19: ++YYCURSOR;
3817 if(YYLIMIT == YYCURSOR) YYFILL(1);
3818 yych = *YYCURSOR;
3819+ goto yy20;
3820 yy20: if(yybm[0+yych] & 128) goto yy19;
3821 if(yych != ':') goto yy2;
3822+ goto yy21;
3823 yy21: yych = *++YYCURSOR;
3824 if(yych != '"') goto yy2;
3825-yy22: yych = *++YYCURSOR;
3826+ goto yy22;
3827+yy22: ++YYCURSOR;
3828+ goto yy23;
3829 yy23:
3830-#line 445
3831- {
3832- size_t len, len2, maxlen;
3833- int elements;
3834+#line 495 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3835+{
3836+ size_t len, len2, len3, maxlen;
3837+ long elements;
3838 char *class_name;
3839 zend_class_entry *ce;
3840 int incomplete_class = 0;
3841@@ -491,6 +539,14 @@
3842 class_name = str_tolower_copy((char *)emalloc(len+1), class_name, len);
3843 class_name[len] = '\0';
3844
3845+ len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyz");
3846+ if (len3 != len)
3847+ {
3848+ *p = YYCURSOR + len3 - len;
3849+ efree(class_name);
3850+ return 0;
3851+ }
3852+
3853 if (zend_hash_find(CG(class_table), class_name, len + 1, (void **) &ce) != SUCCESS) {
3854 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
3855 incomplete_class = 1;
3856@@ -535,9 +591,11 @@
3857
3858 return object_common2(UNSERIALIZE_PASSTHRU, elements);
3859 }
3860+#line 260 "<stdout>"
3861 yy24: yych = *++YYCURSOR;
3862 if(yych <= ','){
3863 if(yych != '+') goto yy2;
3864+ goto yy25;
3865 } else {
3866 if(yych <= '-') goto yy25;
3867 if(yych <= '/') goto yy2;
3868@@ -547,24 +605,30 @@
3869 yy25: yych = *++YYCURSOR;
3870 if(yych <= '/') goto yy2;
3871 if(yych >= ':') goto yy2;
3872+ goto yy26;
3873 yy26: ++YYCURSOR;
3874 if(YYLIMIT == YYCURSOR) YYFILL(1);
3875 yych = *YYCURSOR;
3876+ goto yy27;
3877 yy27: if(yych <= '/') goto yy2;
3878 if(yych <= '9') goto yy26;
3879 if(yych >= ';') goto yy2;
3880+ goto yy28;
3881 yy28: yych = *++YYCURSOR;
3882 if(yych != '"') goto yy2;
3883-yy29: yych = *++YYCURSOR;
3884+ goto yy29;
3885+yy29: ++YYCURSOR;
3886+ goto yy30;
3887 yy30:
3888-#line 437
3889- {
3890+#line 487 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3891+{
3892
3893 INIT_PZVAL(*rval);
3894
3895 return object_common2(UNSERIALIZE_PASSTHRU,
3896 object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
3897 }
3898+#line 298 "<stdout>"
3899 yy31: yych = *++YYCURSOR;
3900 if(yych == '+') goto yy32;
3901 if(yych <= '/') goto yy2;
3902@@ -573,22 +637,35 @@
3903 yy32: yych = *++YYCURSOR;
3904 if(yych <= '/') goto yy2;
3905 if(yych >= ':') goto yy2;
3906+ goto yy33;
3907 yy33: ++YYCURSOR;
3908 if(YYLIMIT == YYCURSOR) YYFILL(1);
3909 yych = *YYCURSOR;
3910+ goto yy34;
3911 yy34: if(yych <= '/') goto yy2;
3912 if(yych <= '9') goto yy33;
3913 if(yych >= ';') goto yy2;
3914+ goto yy35;
3915 yy35: yych = *++YYCURSOR;
3916 if(yych != '{') goto yy2;
3917-yy36: yych = *++YYCURSOR;
3918+ goto yy36;
3919+yy36: ++YYCURSOR;
3920+ goto yy37;
3921 yy37:
3922-#line 419
3923- {
3924- int elements = parse_iv(start + 2);
3925-
3926+#line 461 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3927+{
3928+ long elements = parse_iv(start + 2);
3929+ /* use iv() not uiv() in order to check data range */
3930 *p = YYCURSOR;
3931
3932+ if (elements < 0) {
3933+ return 0;
3934+ }
3935+
3936+ if (elements < 0) {
3937+ return 0;
3938+ }
3939+
3940 INIT_PZVAL(*rval);
3941 Z_TYPE_PP(rval) = IS_ARRAY;
3942 ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
3943@@ -601,6 +678,7 @@
3944
3945 return finish_nested_data(UNSERIALIZE_PASSTHRU);
3946 }
3947+#line 349 "<stdout>"
3948 yy38: yych = *++YYCURSOR;
3949 if(yych == '+') goto yy39;
3950 if(yych <= '/') goto yy2;
3951@@ -609,18 +687,23 @@
3952 yy39: yych = *++YYCURSOR;
3953 if(yych <= '/') goto yy2;
3954 if(yych >= ':') goto yy2;
3955+ goto yy40;
3956 yy40: ++YYCURSOR;
3957 if(YYLIMIT == YYCURSOR) YYFILL(1);
3958 yych = *YYCURSOR;
3959+ goto yy41;
3960 yy41: if(yych <= '/') goto yy2;
3961 if(yych <= '9') goto yy40;
3962 if(yych >= ';') goto yy2;
3963+ goto yy42;
3964 yy42: yych = *++YYCURSOR;
3965 if(yych != '"') goto yy2;
3966-yy43: yych = *++YYCURSOR;
3967+ goto yy43;
3968+yy43: ++YYCURSOR;
3969+ goto yy44;
3970 yy44:
3971-#line 391
3972- {
3973+#line 433 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
3974+{
3975 size_t len, maxlen;
3976 char *str;
3977
3978@@ -647,6 +730,7 @@
3979 ZVAL_STRINGL(*rval, str, len, 1);
3980 return 1;
3981 }
3982+#line 402 "<stdout>"
3983 yy45: yych = *++YYCURSOR;
3984 if(yych <= '/'){
3985 if(yych <= ','){
3986@@ -664,6 +748,7 @@
3987 goto yy48;
3988 } else {
3989 if(yych != 'N') goto yy2;
3990+ goto yy46;
3991 }
3992 }
3993 yy46: yych = *++YYCURSOR;
3994@@ -676,6 +761,7 @@
3995 } else {
3996 if(yych <= '9') goto yy50;
3997 if(yych != 'I') goto yy2;
3998+ goto yy48;
3999 }
4000 yy48: yych = *++YYCURSOR;
4001 if(yych == 'N') goto yy64;
4002@@ -684,9 +770,11 @@
4003 if(yych == '.') goto yy52;
4004 if(yych <= '/') goto yy2;
4005 if(yych >= ':') goto yy2;
4006+ goto yy50;
4007 yy50: ++YYCURSOR;
4008 if(YYLIMIT == YYCURSOR) YYFILL(1);
4009 yych = *YYCURSOR;
4010+ goto yy51;
4011 yy51: if(yych <= ':'){
4012 if(yych <= '.'){
4013 if(yych <= '-') goto yy2;
4014@@ -709,13 +797,16 @@
4015 yy52: yych = *++YYCURSOR;
4016 if(yych <= '/') goto yy2;
4017 if(yych >= ':') goto yy2;
4018+ goto yy53;
4019 yy53: ++YYCURSOR;
4020 if(YYLIMIT == YYCURSOR) YYFILL(1);
4021 yych = *YYCURSOR;
4022+ goto yy54;
4023 yy54: if(yych <= ';'){
4024 if(yych <= '/') goto yy2;
4025 if(yych <= '9') goto yy53;
4026 if(yych <= ':') goto yy2;
4027+ goto yy55;
4028 } else {
4029 if(yych <= 'E'){
4030 if(yych <= 'D') goto yy2;
4031@@ -725,18 +816,21 @@
4032 goto yy2;
4033 }
4034 }
4035-yy55: yych = *++YYCURSOR;
4036+yy55: ++YYCURSOR;
4037+ goto yy56;
4038 yy56:
4039-#line 384
4040- {
4041+#line 426 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4042+{
4043 *p = YYCURSOR;
4044 INIT_PZVAL(*rval);
4045- ZVAL_DOUBLE(*rval, atof(start + 2));
4046+ ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
4047 return 1;
4048 }
4049+#line 500 "<stdout>"
4050 yy57: yych = *++YYCURSOR;
4051 if(yych <= ','){
4052 if(yych != '+') goto yy2;
4053+ goto yy58;
4054 } else {
4055 if(yych <= '-') goto yy58;
4056 if(yych <= '/') goto yy2;
4057@@ -751,10 +845,12 @@
4058 if(yych <= '-') goto yy61;
4059 if(yych <= '/') goto yy2;
4060 if(yych >= ':') goto yy2;
4061+ goto yy59;
4062 }
4063 yy59: ++YYCURSOR;
4064 if(YYLIMIT == YYCURSOR) YYFILL(1);
4065 yych = *YYCURSOR;
4066+ goto yy60;
4067 yy60: if(yych <= '/') goto yy2;
4068 if(yych <= '9') goto yy59;
4069 if(yych == ';') goto yy55;
4070@@ -766,6 +862,7 @@
4071 yy62: ++YYCURSOR;
4072 if((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
4073 yych = *YYCURSOR;
4074+ goto yy63;
4075 yy63: if(yych <= ';'){
4076 if(yych <= '/') goto yy2;
4077 if(yych <= '9') goto yy62;
4078@@ -782,17 +879,18 @@
4079 }
4080 yy64: yych = *++YYCURSOR;
4081 if(yych != 'F') goto yy2;
4082+ goto yy65;
4083 yy65: yych = *++YYCURSOR;
4084 if(yych != ';') goto yy2;
4085-yy66: yych = *++YYCURSOR;
4086+ goto yy66;
4087+yy66: ++YYCURSOR;
4088+ goto yy67;
4089 yy67:
4090-#line 367
4091- {
4092+#line 411 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4093+{
4094 *p = YYCURSOR;
4095 INIT_PZVAL(*rval);
4096-#if defined(HAVE_ATOF_ACCEPTS_NAN) && defined(HAVE_ATOF_ACCEPTS_INF)
4097- ZVAL_DOUBLE(*rval, atof(start + 2));
4098-#else
4099+
4100 if (!strncmp(start + 2, "NAN", 3)) {
4101 ZVAL_DOUBLE(*rval, php_get_nan());
4102 } else if (!strncmp(start + 2, "INF", 3)) {
4103@@ -800,15 +898,17 @@
4104 } else if (!strncmp(start + 2, "-INF", 4)) {
4105 ZVAL_DOUBLE(*rval, -php_get_inf());
4106 }
4107-#endif
4108+
4109 return 1;
4110 }
4111+#line 577 "<stdout>"
4112 yy68: yych = *++YYCURSOR;
4113 if(yych == 'N') goto yy65;
4114 goto yy2;
4115 yy69: yych = *++YYCURSOR;
4116 if(yych <= ','){
4117 if(yych != '+') goto yy2;
4118+ goto yy70;
4119 } else {
4120 if(yych <= '-') goto yy70;
4121 if(yych <= '/') goto yy2;
4122@@ -818,47 +918,59 @@
4123 yy70: yych = *++YYCURSOR;
4124 if(yych <= '/') goto yy2;
4125 if(yych >= ':') goto yy2;
4126+ goto yy71;
4127 yy71: ++YYCURSOR;
4128 if(YYLIMIT == YYCURSOR) YYFILL(1);
4129 yych = *YYCURSOR;
4130+ goto yy72;
4131 yy72: if(yych <= '/') goto yy2;
4132 if(yych <= '9') goto yy71;
4133 if(yych != ';') goto yy2;
4134-yy73: yych = *++YYCURSOR;
4135+ goto yy73;
4136+yy73: ++YYCURSOR;
4137+ goto yy74;
4138 yy74:
4139-#line 360
4140- {
4141+#line 404 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4142+{
4143 *p = YYCURSOR;
4144 INIT_PZVAL(*rval);
4145 ZVAL_LONG(*rval, parse_iv(start + 2));
4146 return 1;
4147 }
4148+#line 614 "<stdout>"
4149 yy75: yych = *++YYCURSOR;
4150 if(yych <= '/') goto yy2;
4151 if(yych >= '2') goto yy2;
4152+ goto yy76;
4153 yy76: yych = *++YYCURSOR;
4154 if(yych != ';') goto yy2;
4155-yy77: yych = *++YYCURSOR;
4156+ goto yy77;
4157+yy77: ++YYCURSOR;
4158+ goto yy78;
4159 yy78:
4160-#line 353
4161- {
4162+#line 397 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4163+{
4164 *p = YYCURSOR;
4165 INIT_PZVAL(*rval);
4166 ZVAL_BOOL(*rval, parse_iv(start + 2));
4167 return 1;
4168 }
4169-yy79: yych = *++YYCURSOR;
4170+#line 632 "<stdout>"
4171+yy79: ++YYCURSOR;
4172+ goto yy80;
4173 yy80:
4174-#line 346
4175- {
4176+#line 390 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4177+{
4178 *p = YYCURSOR;
4179 INIT_PZVAL(*rval);
4180 ZVAL_NULL(*rval);
4181 return 1;
4182 }
4183+#line 643 "<stdout>"
4184 yy81: yych = *++YYCURSOR;
4185 if(yych <= ','){
4186 if(yych != '+') goto yy2;
4187+ goto yy82;
4188 } else {
4189 if(yych <= '-') goto yy82;
4190 if(yych <= '/') goto yy2;
4191@@ -868,17 +980,21 @@
4192 yy82: yych = *++YYCURSOR;
4193 if(yych <= '/') goto yy2;
4194 if(yych >= ':') goto yy2;
4195+ goto yy83;
4196 yy83: ++YYCURSOR;
4197 if(YYLIMIT == YYCURSOR) YYFILL(1);
4198 yych = *YYCURSOR;
4199+ goto yy84;
4200 yy84: if(yych <= '/') goto yy2;
4201 if(yych <= '9') goto yy83;
4202 if(yych != ';') goto yy2;
4203-yy85: yych = *++YYCURSOR;
4204+ goto yy85;
4205+yy85: ++YYCURSOR;
4206+ goto yy86;
4207 yy86:
4208-#line 325
4209- {
4210- int id;
4211+#line 367 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4212+{
4213+ long id;
4214
4215 *p = YYCURSOR;
4216 if (!var_hash) return 0;
4217@@ -887,7 +1003,7 @@
4218 if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
4219 return 0;
4220 }
4221-
4222+
4223 if (*rval == *rval_ref) return 0;
4224
4225 if (*rval != NULL) {
4226@@ -899,9 +1015,11 @@
4227
4228 return 1;
4229 }
4230+#line 693 "<stdout>"
4231 yy87: yych = *++YYCURSOR;
4232 if(yych <= ','){
4233 if(yych != '+') goto yy2;
4234+ goto yy88;
4235 } else {
4236 if(yych <= '-') goto yy88;
4237 if(yych <= '/') goto yy2;
4238@@ -911,17 +1029,21 @@
4239 yy88: yych = *++YYCURSOR;
4240 if(yych <= '/') goto yy2;
4241 if(yych >= ':') goto yy2;
4242+ goto yy89;
4243 yy89: ++YYCURSOR;
4244 if(YYLIMIT == YYCURSOR) YYFILL(1);
4245 yych = *YYCURSOR;
4246+ goto yy90;
4247 yy90: if(yych <= '/') goto yy2;
4248 if(yych <= '9') goto yy89;
4249 if(yych != ';') goto yy2;
4250-yy91: yych = *++YYCURSOR;
4251+ goto yy91;
4252+yy91: ++YYCURSOR;
4253+ goto yy92;
4254 yy92:
4255-#line 304
4256- {
4257- int id;
4258+#line 346 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4259+{
4260+ long id;
4261
4262 *p = YYCURSOR;
4263 if (!var_hash) return 0;
4264@@ -940,8 +1062,9 @@
4265
4266 return 1;
4267 }
4268+#line 741 "<stdout>"
4269 }
4270-#line 534
4271+#line 592 "/usr/src/PHP_4_3_0/ext/standard/var_unserializer.re"
4272
4273
4274 return 0;
4275diff -Nur php-4.3.10/ext/standard/var_unserializer.re hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.re
4276--- php-4.3.10/ext/standard/var_unserializer.re 2004-12-03 17:09:19.000000000 +0100
4277+++ hardened-php-4.3.10-0.2.7/ext/standard/var_unserializer.re 2005-04-07 01:51:16.000000000 +0200
4278@@ -16,7 +16,7 @@
4279 +----------------------------------------------------------------------+
4280 */
4281
4282-/* $Id: var_unserializer.re,v 1.11.4.8 2004/12/03 16:09:19 sesser Exp $ */
4283+/* $Id: var_unserializer.re,v 1.11.4.16 2005/03/10 02:00:17 helly Exp $ */
4284
4285 #include "php.h"
4286 #include "ext/standard/php_var.h"
4287@@ -27,7 +27,7 @@
4288
4289 typedef struct {
4290 zval *data[VAR_ENTRIES_MAX];
4291- int used_slots;
4292+ long used_slots;
4293 void *next;
4294 } var_entries;
4295
4296@@ -54,9 +54,33 @@
4297 var_hash->data[var_hash->used_slots++] = *rval;
4298 }
4299
4300+static inline void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
4301+{
4302+ var_entries *var_hash = var_hashx->first_dtor, *prev = NULL;
4303+
4304+ while (var_hash && var_hash->used_slots == VAR_ENTRIES_MAX) {
4305+ prev = var_hash;
4306+ var_hash = var_hash->next;
4307+ }
4308+
4309+ if (!var_hash) {
4310+ var_hash = emalloc(sizeof(var_entries));
4311+ var_hash->used_slots = 0;
4312+ var_hash->next = 0;
4313+
4314+ if (!var_hashx->first_dtor)
4315+ var_hashx->first_dtor = var_hash;
4316+ else
4317+ prev->next = var_hash;
4318+ }
4319+
4320+ (*rval)->refcount++;
4321+ var_hash->data[var_hash->used_slots++] = *rval;
4322+}
4323+
4324 PHPAPI void var_replace(php_unserialize_data_t *var_hashx, zval *ozval, zval **nzval)
4325 {
4326- int i;
4327+ long i;
4328 var_entries *var_hash = var_hashx->first;
4329
4330 while (var_hash) {
4331@@ -70,7 +94,7 @@
4332 }
4333 }
4334
4335-static int var_access(php_unserialize_data_t *var_hashx, int id, zval ***store)
4336+static int var_access(php_unserialize_data_t *var_hashx, long id, zval ***store)
4337 {
4338 var_entries *var_hash = var_hashx->first;
4339
4340@@ -91,6 +115,7 @@
4341 PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
4342 {
4343 void *next;
4344+ long i;
4345 var_entries *var_hash = var_hashx->first;
4346
4347 while (var_hash) {
4348@@ -98,6 +123,17 @@
4349 efree(var_hash);
4350 var_hash = next;
4351 }
4352+
4353+ var_hash = var_hashx->first_dtor;
4354+
4355+ while (var_hash) {
4356+ for (i = 0; i < var_hash->used_slots; i++) {
4357+ zval_ptr_dtor(&var_hash->data[i]);
4358+ }
4359+ next = var_hash->next;
4360+ efree(var_hash);
4361+ var_hash = next;
4362+ }
4363 }
4364
4365 /* }}} */
4366@@ -119,10 +155,10 @@
4367
4368
4369
4370-static inline int parse_iv2(const unsigned char *p, const unsigned char **q)
4371+static inline long parse_iv2(const unsigned char *p, const unsigned char **q)
4372 {
4373 char cursor;
4374- int result = 0;
4375+ long result = 0;
4376 int neg = 0;
4377
4378 switch (*p) {
4379@@ -147,7 +183,7 @@
4380 return result;
4381 }
4382
4383-static inline int parse_iv(const unsigned char *p)
4384+static inline long parse_iv(const unsigned char *p)
4385 {
4386 return parse_iv2(p, NULL);
4387 }
4388@@ -177,10 +213,10 @@
4389 #define UNSERIALIZE_PARAMETER zval **rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC
4390 #define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC
4391
4392-static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int elements)
4393+static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long elements)
4394 {
4395 while (elements-- > 0) {
4396- zval *key, *data, *old_data;
4397+ zval *key, *data, **old_data;
4398
4399 ALLOC_INIT_ZVAL(key);
4400
4401@@ -208,14 +244,14 @@
4402
4403 switch (Z_TYPE_P(key)) {
4404 case IS_LONG:
4405- if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)) {
4406- var_replace(var_hash, old_data, rval);
4407+ if (zend_hash_index_find(ht, Z_LVAL_P(key), (void **)&old_data)==SUCCESS) {
4408+ var_push_dtor(var_hash, old_data);
4409 }
4410 zend_hash_index_update(ht, Z_LVAL_P(key), &data, sizeof(data), NULL);
4411 break;
4412 case IS_STRING:
4413- if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)) {
4414- var_replace(var_hash, old_data, rval);
4415+ if (zend_hash_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
4416+ var_push_dtor(var_hash, old_data);
4417 }
4418 zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL);
4419 break;
4420@@ -246,7 +282,7 @@
4421
4422 static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
4423 {
4424- int elements;
4425+ long elements;
4426
4427 elements = parse_iv2((*p) + 2, p);
4428
4429@@ -256,7 +292,7 @@
4430 return elements;
4431 }
4432
4433-static inline int object_common2(UNSERIALIZE_PARAMETER, int elements)
4434+static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
4435 {
4436 zval *retval_ptr = NULL;
4437 zval fname;
4438@@ -308,7 +344,7 @@
4439 /*!re2c
4440
4441 "R:" iv ";" {
4442- int id;
4443+ long id;
4444
4445 *p = YYCURSOR;
4446 if (!var_hash) return 0;
4447@@ -329,7 +365,7 @@
4448 }
4449
4450 "r:" iv ";" {
4451- int id;
4452+ long id;
4453
4454 *p = YYCURSOR;
4455 if (!var_hash) return 0;
4456@@ -375,9 +411,7 @@
4457 "d:" ("NAN" | "-"? "INF") ";" {
4458 *p = YYCURSOR;
4459 INIT_PZVAL(*rval);
4460-#if defined(HAVE_ATOF_ACCEPTS_NAN) && defined(HAVE_ATOF_ACCEPTS_INF)
4461- ZVAL_DOUBLE(*rval, atof(start + 2));
4462-#else
4463+
4464 if (!strncmp(start + 2, "NAN", 3)) {
4465 ZVAL_DOUBLE(*rval, php_get_nan());
4466 } else if (!strncmp(start + 2, "INF", 3)) {
4467@@ -385,14 +419,14 @@
4468 } else if (!strncmp(start + 2, "-INF", 4)) {
4469 ZVAL_DOUBLE(*rval, -php_get_inf());
4470 }
4471-#endif
4472+
4473 return 1;
4474 }
4475
4476 "d:" (iv | nv | nvexp) ";" {
4477 *p = YYCURSOR;
4478 INIT_PZVAL(*rval);
4479- ZVAL_DOUBLE(*rval, atof(start + 2));
4480+ ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
4481 return 1;
4482 }
4483
4484@@ -425,10 +459,18 @@
4485 }
4486
4487 "a:" uiv ":" "{" {
4488- int elements = parse_iv(start + 2);
4489-
4490+ long elements = parse_iv(start + 2);
4491+ /* use iv() not uiv() in order to check data range */
4492 *p = YYCURSOR;
4493
4494+ if (elements < 0) {
4495+ return 0;
4496+ }
4497+
4498+ if (elements < 0) {
4499+ return 0;
4500+ }
4501+
4502 INIT_PZVAL(*rval);
4503 Z_TYPE_PP(rval) = IS_ARRAY;
4504 ALLOC_HASHTABLE(Z_ARRVAL_PP(rval));
4505@@ -451,8 +493,8 @@
4506 }
4507
4508 "O:" uiv ":" ["] {
4509- size_t len, len2, maxlen;
4510- int elements;
4511+ size_t len, len2, len3, maxlen;
4512+ long elements;
4513 char *class_name;
4514 zend_class_entry *ce;
4515 int incomplete_class = 0;
4516@@ -486,6 +528,14 @@
4517 class_name = str_tolower_copy((char *)emalloc(len+1), class_name, len);
4518 class_name[len] = '\0';
4519
4520+ len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyz");
4521+ if (len3 != len)
4522+ {
4523+ *p = YYCURSOR + len3 - len;
4524+ efree(class_name);
4525+ return 0;
4526+ }
4527+
4528 if (zend_hash_find(CG(class_table), class_name, len + 1, (void **) &ce) != SUCCESS) {
4529 if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
4530 incomplete_class = 1;
4531diff -Nur php-4.3.10/ext/swf/swf.c hardened-php-4.3.10-0.2.7/ext/swf/swf.c
4532--- php-4.3.10/ext/swf/swf.c 2003-09-12 06:53:39.000000000 +0200
4533+++ hardened-php-4.3.10-0.2.7/ext/swf/swf.c 2005-04-07 01:51:16.000000000 +0200
4534@@ -16,7 +16,7 @@
4535 +----------------------------------------------------------------------+
4536 */
4537
4538-/* $Id: swf.c,v 1.46.2.2 2003/09/12 04:53:39 iliaa Exp $ */
4539+/* $Id: swf.c,v 1.46.2.4 2004/12/23 18:29:36 iliaa Exp $ */
4540
4541
4542 #ifdef HAVE_CONFIG_H
4543@@ -239,12 +239,17 @@
4544 }
4545 na = tmpna;
4546 #endif
4547+ if (php_check_open_basedir(na TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(na, "wb+", CHECKUID_CHECK_MODE_PARAM))) {
4548+ goto err;
4549+ }
4550+
4551 if (!SWFG(use_file))
4552 SWFG(tmpfile_name) = na;
4553
4554 swf_openfile(na,(float)Z_DVAL_PP(sizeX), (float)Z_DVAL_PP(sizeY),
4555 (float)Z_DVAL_PP(frameRate), (float)Z_DVAL_PP(r),
4556 (float)Z_DVAL_PP(g), (float)Z_DVAL_PP(b));
4557+err:
4558 #ifdef VIRTUAL_DIR
4559 free(na);
4560 #endif
4561@@ -606,8 +611,13 @@
4562 convert_to_double_ex(width);
4563
4564 if (Z_TYPE_PP(coordinates) != IS_ARRAY) {
4565- return;
4566 php_error(E_WARNING, "Wrong datatype of second argument to swf_definepoly");
4567+ RETURN_FALSE;
4568+ }
4569+
4570+ if (Z_LVAL_PP(NumPoints) > 256) {
4571+ php_error(E_WARNING, "The npoints value cannot be larger then 256.");
4572+ RETURN_FALSE;
4573 }
4574
4575 npoints = Z_LVAL_PP(NumPoints);
4576diff -Nur php-4.3.10/ext/varfilter/CREDITS hardened-php-4.3.10-0.2.7/ext/varfilter/CREDITS
4577--- php-4.3.10/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
4578+++ hardened-php-4.3.10-0.2.7/ext/varfilter/CREDITS 2005-04-07 01:51:16.000000000 +0200
4579@@ -0,0 +1,2 @@
4580+varfilter
4581+Stefan Esser
4582\ No newline at end of file
4583diff -Nur php-4.3.10/ext/varfilter/config.m4 hardened-php-4.3.10-0.2.7/ext/varfilter/config.m4
4584--- php-4.3.10/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
4585+++ hardened-php-4.3.10-0.2.7/ext/varfilter/config.m4 2005-04-07 01:51:16.000000000 +0200
4586@@ -0,0 +1,11 @@
4587+dnl
4588+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
4589+dnl
4590+
4591+PHP_ARG_ENABLE(varfilter, whether to enable Hardened-PHP's variable filter,
4592+[ --disable-varfilter Disable Hardened-PHP's variable filter], yes)
4593+
4594+if test "$PHP_VARFILTER" != "no"; then
4595+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
4596+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
4597+fi
4598diff -Nur php-4.3.10/ext/varfilter/php_varfilter.h hardened-php-4.3.10-0.2.7/ext/varfilter/php_varfilter.h
4599--- php-4.3.10/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
4600+++ hardened-php-4.3.10-0.2.7/ext/varfilter/php_varfilter.h 2005-04-07 01:51:16.000000000 +0200
4601@@ -0,0 +1,72 @@
4602+/*
4603+ +----------------------------------------------------------------------+
4604+ | PHP Version 4 |
4605+ +----------------------------------------------------------------------+
4606+ | Copyright (c) 1997-2003 The PHP Group |
4607+ +----------------------------------------------------------------------+
4608+ | This source file is subject to version 2.02 of the PHP license, |
4609+ | that is bundled with this package in the file LICENSE, and is |
4610+ | available at through the world-wide-web at |
4611+ | http://www.php.net/license/2_02.txt. |
4612+ | If you did not receive a copy of the PHP license and are unable to |
4613+ | obtain it through the world-wide-web, please send a note to |
4614+ | license@php.net so we can mail you a copy immediately. |
4615+ +----------------------------------------------------------------------+
4616+ | Author: Stefan Esser |
4617+ +----------------------------------------------------------------------+
4618+
4619+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
4620+*/
4621+
4622+#ifndef PHP_VARFILTER_H
4623+#define PHP_VARFILTER_H
4624+
4625+extern zend_module_entry varfilter_module_entry;
4626+#define phpext_varfilter_ptr &varfilter_module_entry
4627+
4628+#ifdef PHP_WIN32
4629+#define PHP_VARFILTER_API __declspec(dllexport)
4630+#else
4631+#define PHP_VARFILTER_API
4632+#endif
4633+
4634+#ifdef ZTS
4635+#include "TSRM.h"
4636+#endif
4637+
4638+#include "SAPI.h"
4639+
4640+PHP_MINIT_FUNCTION(varfilter);
4641+PHP_MSHUTDOWN_FUNCTION(varfilter);
4642+PHP_RINIT_FUNCTION(varfilter);
4643+PHP_RSHUTDOWN_FUNCTION(varfilter);
4644+PHP_MINFO_FUNCTION(varfilter);
4645+
4646+
4647+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
4648+ long max_request_variables;
4649+ long cur_request_variables;
4650+ long max_varname_length;
4651+ long max_value_length;
4652+ long max_array_depth;
4653+ZEND_END_MODULE_GLOBALS(varfilter)
4654+
4655+
4656+#ifdef ZTS
4657+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
4658+#else
4659+#define VARFILTER_G(v) (varfilter_globals.v)
4660+#endif
4661+
4662+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
4663+
4664+#endif /* PHP_VARFILTER_H */
4665+
4666+
4667+/*
4668+ * Local variables:
4669+ * tab-width: 4
4670+ * c-basic-offset: 4
4671+ * indent-tabs-mode: t
4672+ * End:
4673+ */
4674diff -Nur php-4.3.10/ext/varfilter/varfilter.c hardened-php-4.3.10-0.2.7/ext/varfilter/varfilter.c
4675--- php-4.3.10/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
4676+++ hardened-php-4.3.10-0.2.7/ext/varfilter/varfilter.c 2005-04-07 01:51:16.000000000 +0200
4677@@ -0,0 +1,196 @@
4678+/*
4679+ +----------------------------------------------------------------------+
4680+ | PHP Version 4 |
4681+ +----------------------------------------------------------------------+
4682+ | Copyright (c) 1997-2003 The PHP Group |
4683+ +----------------------------------------------------------------------+
4684+ | This source file is subject to version 2.02 of the PHP license, |
4685+ | that is bundled with this package in the file LICENSE, and is |
4686+ | available at through the world-wide-web at |
4687+ | http://www.php.net/license/2_02.txt. |
4688+ | If you did not receive a copy of the PHP license and are unable to |
4689+ | obtain it through the world-wide-web, please send a note to |
4690+ | license@php.net so we can mail you a copy immediately. |
4691+ +----------------------------------------------------------------------+
4692+ | Author: |
4693+ +----------------------------------------------------------------------+
4694+
4695+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
4696+*/
4697+
4698+#ifdef HAVE_CONFIG_H
4699+#include "config.h"
4700+#endif
4701+
4702+#include "php.h"
4703+#include "php_ini.h"
4704+#include "ext/standard/info.h"
4705+#include "php_varfilter.h"
4706+#include "hardened_php.h"
4707+
4708+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
4709+
4710+/* True global resources - no need for thread safety here */
4711+static int le_varfilter;
4712+
4713+/* {{{ varfilter_module_entry
4714+ */
4715+zend_module_entry varfilter_module_entry = {
4716+#if ZEND_MODULE_API_NO >= 20010901
4717+ STANDARD_MODULE_HEADER,
4718+#endif
4719+ "varfilter",
4720+ NULL,
4721+ PHP_MINIT(varfilter),
4722+ PHP_MSHUTDOWN(varfilter),
4723+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
4724+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
4725+ PHP_MINFO(varfilter),
4726+#if ZEND_MODULE_API_NO >= 20010901
4727+ "0.2.0", /* Replace with version number for your extension */
4728+#endif
4729+ STANDARD_MODULE_PROPERTIES
4730+};
4731+/* }}} */
4732+
4733+#ifdef COMPILE_DL_VARFILTER
4734+ZEND_GET_MODULE(varfilter)
4735+#endif
4736+
4737+/* {{{ PHP_INI
4738+ */
4739+PHP_INI_BEGIN()
4740+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_SYSTEM, OnUpdateInt, max_request_variables, zend_varfilter_globals, varfilter_globals)
4741+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_SYSTEM, OnUpdateInt, max_varname_length, zend_varfilter_globals, varfilter_globals)
4742+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "10000", PHP_INI_SYSTEM, OnUpdateInt, max_value_length, zend_varfilter_globals, varfilter_globals)
4743+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_SYSTEM, OnUpdateInt, max_array_depth, zend_varfilter_globals, varfilter_globals)
4744+PHP_INI_END()
4745+/* }}} */
4746+
4747+/* {{{ php_varfilter_init_globals
4748+ */
4749+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
4750+{
4751+ varfilter_globals->max_request_variables = 200;
4752+ varfilter_globals->cur_request_variables = 0;
4753+ varfilter_globals->max_varname_length = 64;
4754+ varfilter_globals->max_value_length = 10000;
4755+ varfilter_globals->max_array_depth = 100;
4756+}
4757+/* }}} */
4758+
4759+/* {{{ PHP_MINIT_FUNCTION
4760+ */
4761+PHP_MINIT_FUNCTION(varfilter)
4762+{
4763+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
4764+ REGISTER_INI_ENTRIES();
4765+
4766+ sapi_register_input_filter(varfilter_input_filter);
4767+ return SUCCESS;
4768+}
4769+/* }}} */
4770+
4771+/* {{{ PHP_MSHUTDOWN_FUNCTION
4772+ */
4773+PHP_MSHUTDOWN_FUNCTION(varfilter)
4774+{
4775+ UNREGISTER_INI_ENTRIES();
4776+
4777+ return SUCCESS;
4778+}
4779+/* }}} */
4780+
4781+/* Remove if there's nothing to do at request start */
4782+/* {{{ PHP_RINIT_FUNCTION
4783+ */
4784+PHP_RINIT_FUNCTION(varfilter)
4785+{
4786+ VARFILTER_G(cur_request_variables) = 0;
4787+
4788+ return SUCCESS;
4789+}
4790+/* }}} */
4791+
4792+/* Remove if there's nothing to do at request end */
4793+/* {{{ PHP_RSHUTDOWN_FUNCTION
4794+ */
4795+PHP_RSHUTDOWN_FUNCTION(varfilter)
4796+{
4797+ return SUCCESS;
4798+}
4799+/* }}} */
4800+
4801+/* {{{ PHP_MINFO_FUNCTION
4802+ */
4803+PHP_MINFO_FUNCTION(varfilter)
4804+{
4805+ php_info_print_table_start();
4806+ php_info_print_table_header(2, "Hardened-PHP's variable filter support", "enabled");
4807+ php_info_print_table_end();
4808+
4809+ DISPLAY_INI_ENTRIES();
4810+}
4811+/* }}} */
4812+
4813+/* {{{ SAPI_INPUT_FILTER_FUNC
4814+ */
4815+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
4816+{
4817+ char *index;
4818+ unsigned int var_len, depth = 0;
4819+
4820+ /* Drop this variable if the limit is reached */
4821+ if (VARFILTER_G(max_request_variables) == VARFILTER_G(cur_request_variables)) {
4822+ php_security_log("tried to register too many variables");
4823+ return 0;
4824+ }
4825+
4826+ /* Drop this variable if it exceeds the value length limit */
4827+ if (VARFILTER_G(max_value_length) < val_len) {
4828+ php_security_log("tried to register a variable with a too long value");
4829+ return 0;
4830+ }
4831+
4832+ /* Find length of variable name */
4833+ index = strchr(var, '[');
4834+ var_len = index ? index-var : strlen(var);
4835+
4836+ /* Drop this variable if it exceeds the varname length limit */
4837+ if (VARFILTER_G(max_varname_length) < var_len) {
4838+ php_security_log("tried to register a variable with a too long variable name");
4839+ return 0;
4840+ }
4841+
4842+ /* Find out array depth */
4843+ while (index) {
4844+ depth++;
4845+ index = strchr(index+1, '[');
4846+ }
4847+
4848+ /* Drop this variable if it exceeds the array depth limit */
4849+ if (VARFILTER_G(max_array_depth) < depth) {
4850+ php_security_log("tried to register a too deep array variable");
4851+ return 0;
4852+ }
4853+
4854+ /* Okay let PHP register this variable */
4855+ VARFILTER_G(cur_request_variables)++;
4856+
4857+ if (new_val_len) {
4858+ *new_val_len = val_len;
4859+ }
4860+
4861+ return 1;
4862+}
4863+/* }}} */
4864+
4865+
4866+/*
4867+ * Local variables:
4868+ * tab-width: 4
4869+ * c-basic-offset: 4
4870+ * End:
4871+ * vim600: noet sw=4 ts=4 fdm=marker
4872+ * vim<600: noet sw=4 ts=4
4873+ */
4874diff -Nur php-4.3.10/main/SAPI.c hardened-php-4.3.10-0.2.7/main/SAPI.c
4875--- php-4.3.10/main/SAPI.c 2004-08-19 22:35:36.000000000 +0200
4876+++ hardened-php-4.3.10-0.2.7/main/SAPI.c 2005-04-07 01:51:16.000000000 +0200
4877@@ -823,6 +823,12 @@
4878 return SUCCESS;
4879 }
4880
4881+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
4882+{
4883+ sapi_module.input_filter = input_filter;
4884+ return SUCCESS;
4885+}
4886+
4887
4888 SAPI_API int sapi_flush(TSRMLS_D)
4889 {
4890diff -Nur php-4.3.10/main/SAPI.h hardened-php-4.3.10-0.2.7/main/SAPI.h
4891--- php-4.3.10/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
4892+++ hardened-php-4.3.10-0.2.7/main/SAPI.h 2005-04-07 01:51:16.000000000 +0200
4893@@ -101,9 +101,14 @@
4894 char *current_user;
4895 int current_user_length;
4896
4897- /* this is necessary for CLI module */
4898- int argc;
4899- char **argv;
4900+ /* this is necessary for CLI module */
4901+ int argc;
4902+ char **argv;
4903+
4904+#if HARDENED_PHP
4905+ /* this is necessary for IP logging */
4906+ char ip_address[64];
4907+#endif
4908 } sapi_request_info;
4909
4910
4911@@ -177,6 +182,7 @@
4912 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
4913 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
4914 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4915+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC));
4916
4917 SAPI_API int sapi_flush(TSRMLS_D);
4918 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4919@@ -238,8 +244,11 @@
4920 int (*get_target_uid)(uid_t * TSRMLS_DC);
4921 int (*get_target_gid)(gid_t * TSRMLS_DC);
4922
4923+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4924+
4925 void (*ini_defaults)(HashTable *configuration_hash);
4926 int phpinfo_as_text;
4927+
4928 };
4929
4930
4931@@ -262,16 +271,23 @@
4932
4933 #define SAPI_DEFAULT_MIMETYPE "text/html"
4934 #define SAPI_DEFAULT_CHARSET ""
4935+
4936+#if HARDENED_PHP
4937+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: Hardened-PHP/" PHP_VERSION
4938+#else
4939 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4940+#endif
4941
4942 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4943 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4944
4945 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4946+#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)
4947
4948 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4949 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4950 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
4951+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
4952
4953 #define STANDARD_SAPI_MODULE_PROPERTIES
4954
4955diff -Nur php-4.3.10/main/fopen_wrappers.c hardened-php-4.3.10-0.2.7/main/fopen_wrappers.c
4956--- php-4.3.10/main/fopen_wrappers.c 2004-03-16 01:32:09.000000000 +0100
4957+++ hardened-php-4.3.10-0.2.7/main/fopen_wrappers.c 2005-04-07 01:51:16.000000000 +0200
4958@@ -16,7 +16,7 @@
4959 | Jim Winstead <jimw@php.net> |
4960 +----------------------------------------------------------------------+
4961 */
4962-/* $Id: fopen_wrappers.c,v 1.153.2.9 2004/03/16 00:32:09 iliaa Exp $ */
4963+/* $Id: fopen_wrappers.c,v 1.153.2.10 2005/02/02 23:44:07 iliaa Exp $ */
4964
4965 /* {{{ includes
4966 */
4967@@ -106,24 +106,11 @@
4968 char resolved_name[MAXPATHLEN];
4969 char resolved_basedir[MAXPATHLEN];
4970 char local_open_basedir[MAXPATHLEN];
4971- int local_open_basedir_pos;
4972 int resolved_basedir_len;
4973 int resolved_name_len;
4974
4975 /* Special case basedir==".": Use script-directory */
4976- if ((strcmp(basedir, ".") == 0) &&
4977- SG(request_info).path_translated &&
4978- *SG(request_info).path_translated
4979- ) {
4980- strlcpy(local_open_basedir, SG(request_info).path_translated, sizeof(local_open_basedir));
4981- local_open_basedir_pos = strlen(local_open_basedir) - 1;
4982-
4983- /* Strip filename */
4984- while (!IS_SLASH(local_open_basedir[local_open_basedir_pos])
4985- && (local_open_basedir_pos >= 0)) {
4986- local_open_basedir[local_open_basedir_pos--] = 0;
4987- }
4988- } else {
4989+ if (strcmp(basedir, ".") || !VCWD_GETCWD(local_open_basedir, MAXPATHLEN)) {
4990 /* Else use the unmodified path */
4991 strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir));
4992 }
4993@@ -179,6 +166,21 @@
4994 char *pathbuf;
4995 char *ptr;
4996 char *end;
4997+ char path_copy[MAXPATHLEN];
4998+ int path_len;
4999+
5000+ /* Special case path ends with a trailing slash */
5001+ path_len = strlen(path);
5002+ if (path_len >= MAXPATHLEN) {
5003+ errno = EPERM; /* we deny permission to open it */
5004+ return -1;
5005+ }
5006+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
5007+ memcpy(path_copy, path, path_len+1);
5008+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
5009+ path_copy[path_len] = '\0';
5010+ path = (const char *)&path_copy;
5011+ }
5012
5013 pathbuf = estrdup(PG(open_basedir));
5014
5015diff -Nur php-4.3.10/main/hardened_globals.h hardened-php-4.3.10-0.2.7/main/hardened_globals.h
5016--- php-4.3.10/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
5017+++ hardened-php-4.3.10-0.2.7/main/hardened_globals.h 2005-04-07 01:51:16.000000000 +0200
5018@@ -0,0 +1,54 @@
5019+/*
5020+ +----------------------------------------------------------------------+
5021+ | Hardened-PHP |
5022+ +----------------------------------------------------------------------+
5023+ | Copyright (c) 2004 Stefan Esser |
5024+ +----------------------------------------------------------------------+
5025+ | This source file is subject to version 2.02 of the PHP license, |
5026+ | that is bundled with this package in the file LICENSE, and is |
5027+ | available at through the world-wide-web at |
5028+ | http://www.php.net/license/2_02.txt. |
5029+ | If you did not receive a copy of the PHP license and are unable to |
5030+ | obtain it through the world-wide-web, please send a note to |
5031+ | license@php.net so we can mail you a copy immediately. |
5032+ +----------------------------------------------------------------------+
5033+ | Author: Stefan Esser <sesser@php.net> |
5034+ +----------------------------------------------------------------------+
5035+ */
5036+
5037+#ifndef HARDENED_GLOBALS_H
5038+#define HARDENED_GLOBALS_H
5039+
5040+typedef struct _hardened_globals hardened_globals_struct;
5041+
5042+#ifdef ZTS
5043+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
5044+extern int hardened_globals_id;
5045+#else
5046+# define HG(v) (hardened_globals.v)
5047+extern struct _hardened_globals hardened_globals;
5048+#endif
5049+
5050+
5051+struct _hardened_globals {
5052+#if HARDENED_PHP_MM_PROTECT
5053+ unsigned int canary_1;
5054+ unsigned int canary_2;
5055+#endif
5056+#if HARDENED_PHP_LL_PROTECT
5057+ unsigned int canary_3;
5058+ unsigned int canary_4;
5059+ unsigned int ll_canary_inited;
5060+#endif
5061+ unsigned int dummy;
5062+};
5063+
5064+
5065+#endif /* HARDENED_GLOBALS_H */
5066+
5067+/*
5068+ * Local variables:
5069+ * tab-width: 4
5070+ * c-basic-offset: 4
5071+ * End:
5072+ */
5073diff -Nur php-4.3.10/main/hardened_php.c hardened-php-4.3.10-0.2.7/main/hardened_php.c
5074--- php-4.3.10/main/hardened_php.c 1970-01-01 01:00:00.000000000 +0100
5075+++ hardened-php-4.3.10-0.2.7/main/hardened_php.c 2005-04-07 01:51:16.000000000 +0200
5076@@ -0,0 +1,205 @@
5077+/*
5078+ +----------------------------------------------------------------------+
5079+ | Hardened-PHP |
5080+ +----------------------------------------------------------------------+
5081+ | Copyright (c) 2004 Stefan Esser |
5082+ +----------------------------------------------------------------------+
5083+ | This source file is subject to version 2.02 of the PHP license, |
5084+ | that is bundled with this package in the file LICENSE, and is |
5085+ | available at through the world-wide-web at |
5086+ | http://www.php.net/license/2_02.txt. |
5087+ | If you did not receive a copy of the PHP license and are unable to |
5088+ | obtain it through the world-wide-web, please send a note to |
5089+ | license@php.net so we can mail you a copy immediately. |
5090+ +----------------------------------------------------------------------+
5091+ | Author: Stefan Esser <sesser@php.net> |
5092+ +----------------------------------------------------------------------+
5093+ */
5094+/* $Id: hardened_php.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
5095+
5096+#include "php.h"
5097+
5098+#include <stdio.h>
5099+#include <stdlib.h>
5100+
5101+#if HAVE_UNISTD_H
5102+#include <unistd.h>
5103+#endif
5104+#include "SAPI.h"
5105+#include "php_globals.h"
5106+
5107+#if HARDENED_PHP
5108+
5109+#ifdef HAVE_SYS_SOCKET_H
5110+#include <sys/socket.h>
5111+#endif
5112+
5113+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
5114+#undef AF_UNIX
5115+#endif
5116+
5117+#if defined(AF_UNIX)
5118+#include <sys/un.h>
5119+#endif
5120+
5121+#define SYSLOG_PATH "/dev/log"
5122+
5123+#include "snprintf.h"
5124+
5125+#ifdef ZTS
5126+#include "hardened_globals.h"
5127+int hardened_globals_id;
5128+#else
5129+struct _hardened_globals hardened_globals;
5130+#endif
5131+
5132+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
5133+{
5134+ memset(hardened_globals, 0, sizeof(*hardened_globals));
5135+}
5136+
5137+PHPAPI void hardened_startup()
5138+{
5139+#ifdef ZTS
5140+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
5141+#else
5142+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
5143+#endif
5144+}
5145+
5146+PHPAPI void php_security_log(char *str)
5147+{
5148+#if defined(AF_UNIX)
5149+ int s, r;
5150+ struct sockaddr_un saun;
5151+ char buf[1024];
5152+ char *ip_address;
5153+ char *fname;
5154+ TSRMLS_FETCH();
5155+
5156+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
5157+ if (ip_address == NULL) {
5158+ ip_address = "REMOTE_ADDR not set";
5159+ }
5160+
5161+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
5162+
5163+ ap_php_snprintf(buf, 1024, "php security-alert: %s (attacker '%s', file '%s')\n", str, ip_address, fname);
5164+
5165+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
5166+ if (s == -1) {
5167+ return;
5168+ }
5169+
5170+ memset(&saun, 0, sizeof(saun));
5171+ saun.sun_family = AF_UNIX;
5172+ strcpy(saun.sun_path, SYSLOG_PATH);
5173+ /*saun.sun_len = sizeof(saun);*/
5174+
5175+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5176+ if (r) {
5177+ close(s);
5178+ s = socket(AF_UNIX, SOCK_STREAM, 0);
5179+ if (s == -1) {
5180+ return;
5181+ }
5182+
5183+ memset(&saun, 0, sizeof(saun));
5184+ saun.sun_family = AF_UNIX;
5185+ strcpy(saun.sun_path, SYSLOG_PATH);
5186+ /*saun.sun_len = sizeof(saun);*/
5187+
5188+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5189+ if (r) {
5190+ close(s);
5191+ return;
5192+ }
5193+ }
5194+ send(s, buf, strlen(buf), 0);
5195+
5196+ close(s);
5197+#endif
5198+}
5199+#endif
5200+
5201+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
5202+
5203+/* will be replaced later with more compatible method */
5204+PHPAPI unsigned int php_canary()
5205+{
5206+ time_t t;
5207+ unsigned int canary;
5208+ int fd;
5209+
5210+ fd = open("/dev/urandom", 0);
5211+ if (fd != -1) {
5212+ int r = read(fd, &canary, sizeof(canary));
5213+ close(fd);
5214+ if (r == sizeof(canary)) {
5215+ return (canary);
5216+ }
5217+ }
5218+ /* not good but we never want to do this */
5219+ time(&t);
5220+ canary = *(unsigned int *)&t + getpid() << 16;
5221+ return (canary);
5222+}
5223+#endif
5224+
5225+#if HARDENED_PHP_INC_PROTECT
5226+
5227+PHPAPI int php_is_valid_include(zval *z)
5228+{
5229+ char *filename;
5230+ int len;
5231+ TSRMLS_FETCH();
5232+
5233+ /* must be of type string */
5234+ if (z->type != IS_STRING || z->value.str.val == NULL) {
5235+ return (0);
5236+ }
5237+
5238+ /* short cut */
5239+ filename = z->value.str.val;
5240+ len = z->value.str.len;
5241+
5242+ /* 1. must be shorter than MAXPATHLEN */
5243+ if (len > MAXPATHLEN) {
5244+ php_security_log("Include filename longer than MAXPATHLEN chars");
5245+ return (0);
5246+ }
5247+
5248+ /* 2. must not be cutted */
5249+ if (len != strlen(filename)) {
5250+ php_security_log("Include filename has a \\0 cut");
5251+ return (0);
5252+ }
5253+
5254+ /* 3. must not be a URL */
5255+ if (strstr(filename, "://")) {
5256+ php_security_log("Include filename is an URL");
5257+ return (0);
5258+ }
5259+
5260+ /* 4. must not be an uploaded file */
5261+ if (SG(rfc1867_uploaded_files)) {
5262+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
5263+ php_security_log("Include filename is an uploaded file");
5264+ return (0);
5265+ }
5266+ }
5267+
5268+ /* passed all tests */
5269+ return (1);
5270+}
5271+
5272+#endif
5273+
5274+/*
5275+ * Local variables:
5276+ * tab-width: 4
5277+ * c-basic-offset: 4
5278+ * End:
5279+ * vim600: sw=4 ts=4 fdm=marker
5280+ * vim<600: sw=4 ts=4
5281+ */
5282diff -Nur php-4.3.10/main/hardened_php.h hardened-php-4.3.10-0.2.7/main/hardened_php.h
5283--- php-4.3.10/main/hardened_php.h 1970-01-01 01:00:00.000000000 +0100
5284+++ hardened-php-4.3.10-0.2.7/main/hardened_php.h 2005-04-07 01:51:16.000000000 +0200
5285@@ -0,0 +1,45 @@
5286+/*
5287+ +----------------------------------------------------------------------+
5288+ | Hardened-PHP |
5289+ +----------------------------------------------------------------------+
5290+ | Copyright (c) 2004 Stefan Esser |
5291+ +----------------------------------------------------------------------+
5292+ | This source file is subject to version 2.02 of the PHP license, |
5293+ | that is bundled with this package in the file LICENSE, and is |
5294+ | available at through the world-wide-web at |
5295+ | http://www.php.net/license/2_02.txt. |
5296+ | If you did not receive a copy of the PHP license and are unable to |
5297+ | obtain it through the world-wide-web, please send a note to |
5298+ | license@php.net so we can mail you a copy immediately. |
5299+ +----------------------------------------------------------------------+
5300+ | Author: Stefan Esser <sesser@php.net> |
5301+ +----------------------------------------------------------------------+
5302+ */
5303+
5304+#ifndef HARDENED_PHP_H
5305+#define HARDENED_PHP_H
5306+
5307+#include "zend.h"
5308+
5309+#if HARDENED_PHP
5310+PHPAPI void php_security_log(char *str);
5311+PHPAPI void hardened_startup();
5312+#define HARDENED_PHP_VERSION "0.2.7"
5313+#endif
5314+
5315+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
5316+PHPAPI unsigned int php_canary();
5317+#endif
5318+
5319+#if HARDENED_PHP_INC_PROTECT
5320+PHPAPI int php_is_valid_include(zval *z);
5321+#endif
5322+
5323+#endif /* HARDENED_PHP_H */
5324+
5325+/*
5326+ * Local variables:
5327+ * tab-width: 4
5328+ * c-basic-offset: 4
5329+ * End:
5330+ */
5331diff -Nur php-4.3.10/main/hardened_php.m4 hardened-php-4.3.10-0.2.7/main/hardened_php.m4
5332--- php-4.3.10/main/hardened_php.m4 1970-01-01 01:00:00.000000000 +0100
5333+++ hardened-php-4.3.10-0.2.7/main/hardened_php.m4 2005-04-07 01:51:16.000000000 +0200
5334@@ -0,0 +1,95 @@
5335+dnl
5336+dnl $Id: hardened_php.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
5337+dnl
5338+dnl This file contains Hardened-PHP specific autoconf functions.
5339+dnl
5340+
5341+AC_ARG_ENABLE(hardened-php-mm-protect,
5342+[ --disable-hardened-php-mm-protect Disable the Memory Manager protection.],[
5343+ DO_HARDENED_PHP_MM_PROTECT=$enableval
5344+],[
5345+ DO_HARDENED_PHP_MM_PROTECT=yes
5346+])
5347+
5348+AC_ARG_ENABLE(hardened-php-ll-protect,
5349+[ --disable-hardened-php-ll-protect Disable the Linked List protection.],[
5350+ DO_HARDENED_PHP_LL_PROTECT=$enableval
5351+],[
5352+ DO_HARDENED_PHP_LL_PROTECT=yes
5353+])
5354+
5355+AC_ARG_ENABLE(hardened-php-inc-protect,
5356+[ --disable-hardened-php-inc-protect Disable include/require protection.],[
5357+ DO_HARDENED_PHP_INC_PROTECT=$enableval
5358+],[
5359+ DO_HARDENED_PHP_INC_PROTECT=yes
5360+])
5361+
5362+AC_ARG_ENABLE(hardened-php-fmt-protect,
5363+[ --disable-hardened-php-fmt-protect Disable format string protection.],[
5364+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
5365+],[
5366+ DO_HARDENED_PHP_FMT_PROTECT=yes
5367+])
5368+
5369+AC_ARG_ENABLE(hardened-php-hash-protect,
5370+[ --disable-hardened-php-hash-protect Disable HashTable destructor protection.],[
5371+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
5372+],[
5373+ DO_HARDENED_PHP_HASH_PROTECT=yes
5374+])
5375+
5376+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
5377+AC_MSG_RESULT($DO_HARDENED_PHP_MM_PROTECT)
5378+
5379+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
5380+AC_MSG_RESULT($DO_HARDENED_PHP_LL_PROTECT)
5381+
5382+AC_MSG_CHECKING(whether to protect include/require statements)
5383+AC_MSG_RESULT($DO_HARDENED_PHP_INC_PROTECT)
5384+
5385+AC_MSG_CHECKING(whether to protect PHP Format String functions)
5386+AC_MSG_RESULT($DO_HARDENED_PHP_FMT_PROTECT)
5387+
5388+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
5389+AC_MSG_RESULT($DO_HARDENED_PHP_HASH_PROTECT)
5390+
5391+
5392+AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5393+
5394+
5395+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
5396+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5397+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 1, [Memory Manager Protection])
5398+else
5399+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 0, [Memory Manager Protection])
5400+fi
5401+
5402+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
5403+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5404+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 1, [Linked List Protection])
5405+else
5406+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 0, [Linked List Protection])
5407+fi
5408+
5409+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
5410+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5411+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 1, [Include/Require Protection])
5412+else
5413+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 0, [Include/Require Protection])
5414+fi
5415+
5416+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
5417+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5418+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 1, [Fmt String Protection])
5419+else
5420+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 0, [Fmt String Protection])
5421+fi
5422+
5423+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
5424+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
5425+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 1, [HashTable DTOR Protection])
5426+else
5427+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 0, [HashTable DTOR Protection])
5428+fi
5429+
5430diff -Nur php-4.3.10/main/main.c hardened-php-4.3.10-0.2.7/main/main.c
5431--- php-4.3.10/main/main.c 2004-10-01 16:27:13.000000000 +0200
5432+++ hardened-php-4.3.10-0.2.7/main/main.c 2005-04-07 01:51:16.000000000 +0200
5433@@ -100,6 +100,10 @@
5434 PHPAPI int core_globals_id;
5435 #endif
5436
5437+#if HARDENED_PHP
5438+#include "hardened_globals.h"
5439+#endif
5440+
5441 #define ERROR_BUF_LEN 1024
5442
5443 typedef struct {
5444@@ -150,10 +154,33 @@
5445 */
5446 static PHP_INI_MH(OnChangeMemoryLimit)
5447 {
5448+#if HARDENED_PHP
5449+ long orig_memory_limit;
5450+
5451+ if (entry->modified) {
5452+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
5453+ } else {
5454+ orig_memory_limit = 1<<30;
5455+ }
5456+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
5457+ orig_memory_limit = 1<<30;
5458+ }
5459+#endif
5460 if (new_value) {
5461 PG(memory_limit) = zend_atoi(new_value, new_value_length);
5462+#if HARDENED_PHP
5463+ if (PG(memory_limit) > orig_memory_limit) {
5464+ PG(memory_limit) = orig_memory_limit;
5465+ php_security_log("script tried to increase memory_limit above allowed value");
5466+ return FAILURE;
5467+ }
5468+#endif
5469 } else {
5470+#if HARDENED_PHP
5471+ PG(memory_limit) = orig_memory_limit;
5472+#else
5473 PG(memory_limit) = 1<<30; /* effectively, no limit */
5474+#endif
5475 }
5476 return zend_set_memory_limit(PG(memory_limit));
5477 }
5478@@ -1091,6 +1118,10 @@
5479 tsrm_ls = ts_resource(0);
5480 #endif
5481
5482+#if HARDENED_PHP
5483+ hardened_startup();
5484+#endif
5485+
5486 sapi_initialize_empty_request(TSRMLS_C);
5487 sapi_activate(TSRMLS_C);
5488
5489@@ -1103,6 +1134,12 @@
5490 php_output_startup();
5491 php_output_activate(TSRMLS_C);
5492
5493+#if HARDENED_PHP_INC_PROTECT
5494+ zuf.is_valid_include = php_is_valid_include;
5495+#endif
5496+#if HARDENED_PHP
5497+ zuf.security_log_function = php_security_log;
5498+#endif
5499 zuf.error_function = php_error_cb;
5500 zuf.printf_function = php_printf;
5501 zuf.write_function = php_body_write_wrapper;
5502@@ -1204,6 +1241,10 @@
5503 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
5504 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);
5505 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
5506+#if HARDENED_PHP
5507+ REGISTER_MAIN_LONG_CONSTANT("HARDENED_PHP", 1, CONST_PERSISTENT | CONST_CS);
5508+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENED_PHP_VERSION", HARDENED_PHP_VERSION, sizeof(HARDENED_PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
5509+#endif
5510 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
5511 php_output_register_constants(TSRMLS_C);
5512 php_rfc1867_register_constants(TSRMLS_C);
5513@@ -1339,6 +1380,7 @@
5514 ulong num_key;
5515 HashPosition pos;
5516 int key_type;
5517+ int globals_check = (PG(register_globals) && (dest == (&EG(symbol_table))));
5518
5519 zend_hash_internal_pointer_reset_ex(src, &pos);
5520 while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) {
5521@@ -1349,7 +1391,12 @@
5522 || Z_TYPE_PP(dest_entry) != IS_ARRAY) {
5523 (*src_entry)->refcount++;
5524 if (key_type == HASH_KEY_IS_STRING) {
5525- zend_hash_update(dest, string_key, strlen(string_key)+1, src_entry, sizeof(zval *), NULL);
5526+ /* if register_globals is on and working with main symbol table, prevent overwriting of GLOBALS */
5527+ if (!globals_check || string_key_len != sizeof("GLOBALS") || memcmp(string_key, "GLOBALS", sizeof("GLOBALS") - 1)) {
5528+ zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
5529+ } else {
5530+ (*src_entry)->refcount--;
5531+ }
5532 } else {
5533 zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL);
5534 }
5535diff -Nur php-4.3.10/main/php.h hardened-php-4.3.10-0.2.7/main/php.h
5536--- php-4.3.10/main/php.h 2004-11-28 13:44:56.000000000 +0100
5537+++ hardened-php-4.3.10-0.2.7/main/php.h 2005-04-07 01:51:16.000000000 +0200
5538@@ -35,11 +35,19 @@
5539 #include "zend_qsort.h"
5540 #include "php_compat.h"
5541
5542+
5543 #include "zend_API.h"
5544
5545 #undef sprintf
5546 #define sprintf php_sprintf
5547
5548+#if HARDENED_PHP
5549+#if HAVE_REALPATH
5550+#undef realpath
5551+#define realpath php_realpath
5552+#endif
5553+#endif
5554+
5555 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
5556 #undef PHP_DEBUG
5557 #define PHP_DEBUG ZEND_DEBUG
5558@@ -436,6 +444,10 @@
5559 #endif
5560 #endif /* !XtOffsetOf */
5561
5562+#if HARDENED_PHP
5563+#include "hardened_php.h"
5564+#endif
5565+
5566 #endif
5567
5568 /*
5569diff -Nur php-4.3.10/main/php_config.h.in hardened-php-4.3.10-0.2.7/main/php_config.h.in
5570--- php-4.3.10/main/php_config.h.in 2004-12-14 18:55:22.000000000 +0100
5571+++ hardened-php-4.3.10-0.2.7/main/php_config.h.in 2005-04-07 01:51:16.000000000 +0200
5572@@ -834,6 +834,39 @@
5573 /* Enabling BIND8 compatibility for Panther */
5574 #undef BIND_8_COMPAT
5575
5576+/* Hardened-PHP */
5577+#undef HARDENED_PHP
5578+
5579+/* Memory Manager Protection */
5580+#undef HARDENED_PHP_MM_PROTECT
5581+
5582+/* Memory Manager Protection */
5583+#undef HARDENED_PHP_MM_PROTECT
5584+
5585+/* Linked List Protection */
5586+#undef HARDENED_PHP_LL_PROTECT
5587+
5588+/* Linked List Protection */
5589+#undef HARDENED_PHP_LL_PROTECT
5590+
5591+/* Include/Require Protection */
5592+#undef HARDENED_PHP_INC_PROTECT
5593+
5594+/* Include/Require Protection */
5595+#undef HARDENED_PHP_INC_PROTECT
5596+
5597+/* Fmt String Protection */
5598+#undef HARDENED_PHP_FMT_PROTECT
5599+
5600+/* Fmt String Protection */
5601+#undef HARDENED_PHP_FMT_PROTECT
5602+
5603+/* HashTable DTOR Protection */
5604+#undef HARDENED_PHP_HASH_PROTECT
5605+
5606+/* HashTable DTOR Protection */
5607+#undef HARDENED_PHP_HASH_PROTECT
5608+
5609 /* Whether you have AOLserver */
5610 #undef HAVE_AOLSERVER
5611
5612@@ -1117,6 +1150,12 @@
5613 /* Define if you have the getaddrinfo function */
5614 #undef HAVE_GETADDRINFO
5615
5616+/* Whether realpath is broken */
5617+#undef PHP_BROKEN_REALPATH
5618+
5619+/* Whether realpath is broken */
5620+#undef PHP_BROKEN_REALPATH
5621+
5622 /* Whether system headers declare timezone */
5623 #undef HAVE_DECLARED_TIMEZONE
5624
5625diff -Nur php-4.3.10/main/php_content_types.c hardened-php-4.3.10-0.2.7/main/php_content_types.c
5626--- php-4.3.10/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
5627+++ hardened-php-4.3.10-0.2.7/main/php_content_types.c 2005-04-07 01:51:16.000000000 +0200
5628@@ -77,6 +77,7 @@
5629 sapi_register_post_entries(php_post_entries);
5630 sapi_register_default_post_reader(php_default_post_reader);
5631 sapi_register_treat_data(php_default_treat_data);
5632+ sapi_register_input_filter(php_default_input_filter);
5633 return SUCCESS;
5634 }
5635 /* }}} */
5636diff -Nur php-4.3.10/main/php_variables.c hardened-php-4.3.10-0.2.7/main/php_variables.c
5637--- php-4.3.10/main/php_variables.c 2004-10-18 17:08:46.000000000 +0200
5638+++ hardened-php-4.3.10-0.2.7/main/php_variables.c 2005-04-07 01:51:16.000000000 +0200
5639@@ -211,17 +211,28 @@
5640 while (var) {
5641 val = strchr(var, '=');
5642 if (val) { /* have a value */
5643- int val_len;
5644+ unsigned int val_len, new_val_len;
5645
5646 *val++ = '\0';
5647 php_url_decode(var, strlen(var));
5648 val_len = php_url_decode(val, strlen(val));
5649- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5650+ val = estrndup(val, val_len);
5651+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5652+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5653+ }
5654+ efree(val);
5655 }
5656 var = php_strtok_r(NULL, "&", &strtok_buf);
5657 }
5658 }
5659
5660+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
5661+{
5662+ /* TODO: check .ini setting here and apply user-defined input filter */
5663+ *new_val_len = val_len;
5664+ return 1;
5665+}
5666+
5667 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
5668 {
5669 char *res = NULL, *var, *val, *separator=NULL;
5670@@ -299,15 +310,26 @@
5671 while (var) {
5672 val = strchr(var, '=');
5673 if (val) { /* have a value */
5674- int val_len;
5675+ unsigned int val_len, new_val_len;
5676
5677 *val++ = '\0';
5678 php_url_decode(var, strlen(var));
5679 val_len = php_url_decode(val, strlen(val));
5680- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5681+ val = estrndup(val, val_len);
5682+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5683+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5684+ }
5685+ efree(val);
5686 } else {
5687+ unsigned int val_len, new_val_len;
5688+
5689 php_url_decode(var, strlen(var));
5690- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
5691+ val_len = 0;
5692+ val = estrndup("", 0);
5693+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5694+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5695+ }
5696+ efree(val);
5697 }
5698 var = php_strtok_r(NULL, separator, &strtok_buf);
5699 }
5700diff -Nur php-4.3.10/main/rfc1867.c hardened-php-4.3.10-0.2.7/main/rfc1867.c
5701--- php-4.3.10/main/rfc1867.c 2004-11-20 21:16:44.000000000 +0100
5702+++ hardened-php-4.3.10-0.2.7/main/rfc1867.c 2005-04-07 01:51:16.000000000 +0200
5703@@ -891,21 +891,24 @@
5704 if (!filename && param) {
5705
5706 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
5707+ unsigned int new_val_len; /* Dummy variable */
5708
5709 if (!value) {
5710 value = estrdup("");
5711 }
5712
5713+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
5714 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
5715- if (php_mb_encoding_translation(TSRMLS_C)) {
5716- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5717- &num_vars, &num_vars_max TSRMLS_CC);
5718- } else {
5719- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5720- }
5721+ if (php_mb_encoding_translation(TSRMLS_C)) {
5722+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5723+ &num_vars, &num_vars_max TSRMLS_CC);
5724+ } else {
5725+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5726+ }
5727 #else
5728- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5729+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5730 #endif
5731+ }
5732 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
5733 max_file_size = atol(value);
5734 }
5735diff -Nur php-4.3.10/main/snprintf.c hardened-php-4.3.10-0.2.7/main/snprintf.c
5736--- php-4.3.10/main/snprintf.c 2004-11-16 00:27:26.000000000 +0100
5737+++ hardened-php-4.3.10-0.2.7/main/snprintf.c 2005-04-07 01:51:16.000000000 +0200
5738@@ -850,7 +850,11 @@
5739
5740
5741 case 'n':
5742+#if HARDENED_PHP_FMT_PROTECT
5743+ php_security_log("'n' specifier within format string");
5744+#else
5745 *(va_arg(ap, int *)) = cc;
5746+#endif
5747 break;
5748
5749 /*
5750diff -Nur php-4.3.10/main/spprintf.c hardened-php-4.3.10-0.2.7/main/spprintf.c
5751--- php-4.3.10/main/spprintf.c 2003-09-29 03:09:36.000000000 +0200
5752+++ hardened-php-4.3.10-0.2.7/main/spprintf.c 2005-04-07 01:51:16.000000000 +0200
5753@@ -531,7 +531,11 @@
5754
5755
5756 case 'n':
5757+#if HARDENED_PHP_FMT_PROTECT
5758+ php_security_log("'n' specifier within format string");
5759+#else
5760 *(va_arg(ap, int *)) = cc;
5761+#endif
5762 break;
5763
5764 /*
5765diff -Nur php-4.3.10/php.ini-dist hardened-php-4.3.10-0.2.7/php.ini-dist
5766--- php-4.3.10/php.ini-dist 2004-08-18 07:05:23.000000000 +0200
5767+++ hardened-php-4.3.10-0.2.7/php.ini-dist 2005-04-07 01:51:16.000000000 +0200
5768@@ -1113,6 +1113,23 @@
5769 ;exif.decode_jis_motorola = JIS
5770 ;exif.decode_jis_intel = JIS
5771
5772+[varfilter]
5773+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5774+; Hardened-PHP's variable filter
5775+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5776+
5777+; Maximum number of input variables per request
5778+varfilter.max_request_variables = 200
5779+
5780+; Maximum characters in input variable names
5781+varfilter.max_varname_length = 64
5782+
5783+; Maximum length of input variable values
5784+varfilter.max_value_length = 10000
5785+
5786+; Maximum depth of input variable arrays
5787+varfilter.max_array_depth = 100
5788+
5789 ; Local Variables:
5790 ; tab-width: 4
5791 ; End:
5792diff -Nur php-4.3.10/php.ini-recommended hardened-php-4.3.10-0.2.7/php.ini-recommended
5793--- php-4.3.10/php.ini-recommended 2004-08-18 07:05:23.000000000 +0200
5794+++ hardened-php-4.3.10-0.2.7/php.ini-recommended 2005-04-07 01:51:16.000000000 +0200
5795@@ -1111,6 +1111,23 @@
5796 ;exif.decode_jis_motorola = JIS
5797 ;exif.decode_jis_intel = JIS
5798
5799+[varfilter]
5800+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5801+; Hardened-PHP's variable filter
5802+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5803+
5804+; Maximum number of input variables per request
5805+varfilter.max_request_variables = 200
5806+
5807+; Maximum characters in input variable names
5808+varfilter.max_varname_length = 64
5809+
5810+; Maximum length of input variable values
5811+varfilter.max_value_length = 10000
5812+
5813+; Maximum depth of input variable arrays
5814+varfilter.max_array_depth = 100
5815+
5816 ; Local Variables:
5817 ; tab-width: 4
5818 ; End:
5819diff -Nur php-4.3.10/sapi/apache/mod_php4.c hardened-php-4.3.10-0.2.7/sapi/apache/mod_php4.c
5820--- php-4.3.10/sapi/apache/mod_php4.c 2004-07-21 18:25:28.000000000 +0200
5821+++ hardened-php-4.3.10-0.2.7/sapi/apache/mod_php4.c 2005-04-07 01:51:16.000000000 +0200
5822@@ -446,7 +446,7 @@
5823 sapi_apache_get_fd,
5824 sapi_apache_force_http_10,
5825 sapi_apache_get_target_uid,
5826- sapi_apache_get_target_gid
5827+ sapi_apache_get_target_gid,
5828 };
5829 /* }}} */
5830
5831@@ -892,7 +892,11 @@
5832 {
5833 TSRMLS_FETCH();
5834 if (PG(expose_php)) {
5835+#if HARDENED_PHP
5836+ ap_add_version_component("Hardened-PHP/" PHP_VERSION);
5837+#else
5838 ap_add_version_component("PHP/" PHP_VERSION);
5839+#endif
5840 }
5841 }
5842 #endif
5843diff -Nur php-4.3.10/sapi/apache2filter/sapi_apache2.c hardened-php-4.3.10-0.2.7/sapi/apache2filter/sapi_apache2.c
5844--- php-4.3.10/sapi/apache2filter/sapi_apache2.c 2004-06-18 02:37:02.000000000 +0200
5845+++ hardened-php-4.3.10-0.2.7/sapi/apache2filter/sapi_apache2.c 2005-04-07 01:51:16.000000000 +0200
5846@@ -560,7 +560,11 @@
5847 {
5848 TSRMLS_FETCH();
5849 if (PG(expose_php)) {
5850+#if HARDENED_PHP
5851+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
5852+#else
5853 ap_add_version_component(p, "PHP/" PHP_VERSION);
5854+#endif
5855 }
5856 }
5857
5858diff -Nur php-4.3.10/sapi/apache2handler/sapi_apache2.c hardened-php-4.3.10-0.2.7/sapi/apache2handler/sapi_apache2.c
5859--- php-4.3.10/sapi/apache2handler/sapi_apache2.c 2004-12-06 19:55:16.000000000 +0100
5860+++ hardened-php-4.3.10-0.2.7/sapi/apache2handler/sapi_apache2.c 2005-04-07 01:51:16.000000000 +0200
5861@@ -337,7 +337,11 @@
5862 {
5863 TSRMLS_FETCH();
5864 if (PG(expose_php)) {
5865+#if HARDENED_PHP
5866+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
5867+#else
5868 ap_add_version_component(p, "PHP/" PHP_VERSION);
5869+#endif
5870 }
5871 }
5872
5873diff -Nur php-4.3.10/sapi/cgi/cgi_main.c hardened-php-4.3.10-0.2.7/sapi/cgi/cgi_main.c
5874--- php-4.3.10/sapi/cgi/cgi_main.c 2004-07-15 00:38:18.000000000 +0200
5875+++ hardened-php-4.3.10-0.2.7/sapi/cgi/cgi_main.c 2005-04-07 01:51:16.000000000 +0200
5876@@ -1426,11 +1426,19 @@
5877 SG(headers_sent) = 1;
5878 SG(request_info).no_headers = 1;
5879 }
5880+#if HARDENED_PHP
5881+#if ZEND_DEBUG
5882+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5883+#else
5884+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5885+#endif
5886+#else
5887 #if ZEND_DEBUG
5888 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());
5889 #else
5890 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());
5891 #endif
5892+#endif
5893 php_end_ob_buffers(1 TSRMLS_CC);
5894 exit(1);
5895 break;
5896diff -Nur php-4.3.10/sapi/cli/php_cli.c hardened-php-4.3.10-0.2.7/sapi/cli/php_cli.c
5897--- php-4.3.10/sapi/cli/php_cli.c 2004-07-15 00:38:18.000000000 +0200
5898+++ hardened-php-4.3.10-0.2.7/sapi/cli/php_cli.c 2005-04-07 01:51:16.000000000 +0200
5899@@ -646,11 +646,19 @@
5900 if (php_request_startup(TSRMLS_C)==FAILURE) {
5901 goto err;
5902 }
5903+#if HARDENED_PHP
5904+#if ZEND_DEBUG
5905+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5906+#else
5907+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5908+#endif
5909+#else
5910 #if ZEND_DEBUG
5911 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());
5912 #else
5913 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());
5914 #endif
5915+#endif
5916 php_end_ob_buffers(1 TSRMLS_CC);
5917 exit_status=1;
5918 goto out;
diff --git a/0.2.7/hardened-php-4.3.11-0.2.7.patch b/0.2.7/hardened-php-4.3.11-0.2.7.patch
new file mode 100644
index 0000000..d91abe4
--- /dev/null
+++ b/0.2.7/hardened-php-4.3.11-0.2.7.patch
@@ -0,0 +1,3417 @@
1diff -Nur php-4.3.11/README.input_filter hardened-php-4.3.11-0.2.7/README.input_filter
2--- php-4.3.11/README.input_filter 1970-01-01 01:00:00.000000000 +0100
3+++ hardened-php-4.3.11-0.2.7/README.input_filter 2005-04-07 02:08:26.000000000 +0200
4@@ -0,0 +1,193 @@
5+Input Filter Support ported from PHP 5
6+--------------------------------------
7+
8+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
9+and can be quite difficult to prevent. Whenever you accept user data
10+and somehow display this data back to users, you are likely vulnerable
11+to XSS hacks.
12+
13+The Input Filter support in PHP 5 is aimed at providing the framework
14+through which a company-wide or site-wide security policy can be
15+enforced. It is implemented as a SAPI hook and is called from the
16+treat_data and post handler functions. To implement your own security
17+policy you will need to write a standard PHP extension.
18+
19+A simple implementation might look like the following. This stores the
20+original raw user data and adds a my_get_raw() function while the normal
21+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
22+data. In this simple example all I am doing is calling strip_tags() on
23+the data. If register_globals is turned on, the default globals that
24+are created will be stripped ($foo) while a $RAW_foo is created with the
25+original user input.
26+
27+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
28+ zval *post_array;
29+ zval *get_array;
30+ zval *cookie_array;
31+ZEND_END_MODULE_GLOBALS(my_input_filter)
32+
33+#ifdef ZTS
34+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
35+#else
36+#define IF_G(v) (my_input_filter_globals.v)
37+#endif
38+
39+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
40+
41+function_entry my_input_filter_functions[] = {
42+ PHP_FE(my_get_raw, NULL)
43+ {NULL, NULL, NULL}
44+};
45+
46+zend_module_entry my_input_filter_module_entry = {
47+ STANDARD_MODULE_HEADER,
48+ "my_input_filter",
49+ my_input_filter_functions,
50+ PHP_MINIT(my_input_filter),
51+ PHP_MSHUTDOWN(my_input_filter),
52+ NULL,
53+ PHP_RSHUTDOWN(my_input_filter),
54+ PHP_MINFO(my_input_filter),
55+ "0.1",
56+ STANDARD_MODULE_PROPERTIES
57+};
58+
59+PHP_MINIT_FUNCTION(my_input_filter)
60+{
61+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
62+
63+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
64+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
65+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
66+
67+ sapi_register_input_filter(my_sapi_input_filter);
68+ return SUCCESS;
69+}
70+
71+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
72+{
73+ if(IF_G(get_array)) {
74+ zval_ptr_dtor(&IF_G(get_array));
75+ IF_G(get_array) = NULL;
76+ }
77+ if(IF_G(post_array)) {
78+ zval_ptr_dtor(&IF_G(post_array));
79+ IF_G(post_array) = NULL;
80+ }
81+ if(IF_G(cookie_array)) {
82+ zval_ptr_dtor(&IF_G(cookie_array));
83+ IF_G(cookie_array) = NULL;
84+ }
85+ return SUCCESS;
86+}
87+
88+PHP_MINFO_FUNCTION(my_input_filter)
89+{
90+ php_info_print_table_start();
91+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
92+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
93+ php_info_print_table_end();
94+}
95+
96+/* The filter handler. If you return 1 from it, then PHP also registers the
97+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
98+ * you can use this if your filter already registers the variable under a
99+ * different name, or if you just don't want the variable registered at all. */
100+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
101+{
102+ zval new_var;
103+ zval *array_ptr = NULL;
104+ char *raw_var;
105+ int var_len;
106+
107+ assert(*val != NULL);
108+
109+ switch(arg) {
110+ case PARSE_GET:
111+ if(!IF_G(get_array)) {
112+ ALLOC_ZVAL(array_ptr);
113+ array_init(array_ptr);
114+ INIT_PZVAL(array_ptr);
115+ }
116+ IF_G(get_array) = array_ptr;
117+ break;
118+ case PARSE_POST:
119+ if(!IF_G(post_array)) {
120+ ALLOC_ZVAL(array_ptr);
121+ array_init(array_ptr);
122+ INIT_PZVAL(array_ptr);
123+ }
124+ IF_G(post_array) = array_ptr;
125+ break;
126+ case PARSE_COOKIE:
127+ if(!IF_G(cookie_array)) {
128+ ALLOC_ZVAL(array_ptr);
129+ array_init(array_ptr);
130+ INIT_PZVAL(array_ptr);
131+ }
132+ IF_G(cookie_array) = array_ptr;
133+ break;
134+ }
135+ Z_STRLEN(new_var) = val_len;
136+ Z_STRVAL(new_var) = estrndup(*val, val_len);
137+ Z_TYPE(new_var) = IS_STRING;
138+
139+ var_len = strlen(var);
140+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
141+ strcpy(raw_var, "RAW_");
142+ strlcat(raw_var,var,var_len+5);
143+
144+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
145+
146+ php_strip_tags(*val, val_len, NULL, NULL, 0);
147+
148+ *new_val_len = strlen(*val);
149+ return 1;
150+}
151+
152+PHP_FUNCTION(my_get_raw)
153+{
154+ long arg;
155+ char *var;
156+ int var_len;
157+ zval **tmp;
158+ zval *array_ptr = NULL;
159+ HashTable *hash_ptr;
160+ char *raw_var;
161+
162+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
163+ return;
164+ }
165+
166+ switch(arg) {
167+ case PARSE_GET:
168+ array_ptr = IF_G(get_array);
169+ break;
170+ case PARSE_POST:
171+ array_ptr = IF_G(post_array);
172+ break;
173+ case PARSE_COOKIE:
174+ array_ptr = IF_G(post_array);
175+ break;
176+ }
177+
178+ if(!array_ptr) RETURN_FALSE;
179+
180+ /*
181+ * I'm changing the variable name here because when running with register_globals on,
182+ * the variable will end up in the global symbol table
183+ */
184+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
185+ strcpy(raw_var, "RAW_");
186+ strlcat(raw_var,var,var_len+5);
187+ hash_ptr = HASH_OF(array_ptr);
188+
189+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
190+ *return_value = **tmp;
191+ zval_copy_ctor(return_value);
192+ } else {
193+ RETVAL_FALSE;
194+ }
195+ efree(raw_var);
196+}
197+
198diff -Nur php-4.3.11/TSRM/TSRM.h hardened-php-4.3.11-0.2.7/TSRM/TSRM.h
199--- php-4.3.11/TSRM/TSRM.h 2005-02-11 04:34:04.000000000 +0100
200+++ hardened-php-4.3.11-0.2.7/TSRM/TSRM.h 2005-04-07 02:08:26.000000000 +0200
201@@ -33,6 +33,13 @@
202 # define TSRM_API
203 #endif
204
205+#if HARDENED_PHP
206+# if HAVE_REALPATH
207+# undef realpath
208+# define realpath php_realpath
209+# endif
210+#endif
211+
212 /* Only compile multi-threading functions if we're in ZTS mode */
213 #ifdef ZTS
214
215@@ -90,6 +97,7 @@
216
217 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
218
219+
220 #ifdef __cplusplus
221 extern "C" {
222 #endif
223diff -Nur php-4.3.11/TSRM/tsrm_virtual_cwd.c hardened-php-4.3.11-0.2.7/TSRM/tsrm_virtual_cwd.c
224--- php-4.3.11/TSRM/tsrm_virtual_cwd.c 2005-02-11 04:34:04.000000000 +0100
225+++ hardened-php-4.3.11-0.2.7/TSRM/tsrm_virtual_cwd.c 2005-04-07 02:08:26.000000000 +0200
226@@ -192,6 +192,165 @@
227 return p;
228 }
229
230+#if HARDENED_PHP
231+CWD_API char *php_realpath(const char *path, char *resolved)
232+{
233+ struct stat sb;
234+ char *p, *q, *s;
235+ size_t left_len, resolved_len;
236+ unsigned symlinks;
237+ int serrno, slen;
238+ int is_dir = 1;
239+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
240+
241+ serrno = errno;
242+ symlinks = 0;
243+ if (path[0] == '/') {
244+ resolved[0] = '/';
245+ resolved[1] = '\0';
246+ if (path[1] == '\0')
247+ return (resolved);
248+ resolved_len = 1;
249+ left_len = strlcpy(left, path + 1, sizeof(left));
250+ } else {
251+ if (getcwd(resolved, PATH_MAX) == NULL) {
252+ strlcpy(resolved, ".", PATH_MAX);
253+ return (NULL);
254+ }
255+ resolved_len = strlen(resolved);
256+ left_len = strlcpy(left, path, sizeof(left));
257+ }
258+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
259+ errno = ENAMETOOLONG;
260+ return (NULL);
261+ }
262+
263+ /*
264+ * Iterate over path components in `left'.
265+ */
266+ while (left_len != 0) {
267+ /*
268+ * Extract the next path component and adjust `left'
269+ * and its length.
270+ */
271+ p = strchr(left, '/');
272+ s = p ? p : left + left_len;
273+ if (s - left >= sizeof(next_token)) {
274+ errno = ENAMETOOLONG;
275+ return (NULL);
276+ }
277+ memcpy(next_token, left, s - left);
278+ next_token[s - left] = '\0';
279+ left_len -= s - left;
280+ if (p != NULL)
281+ memmove(left, s + 1, left_len + 1);
282+ if (resolved[resolved_len - 1] != '/') {
283+ if (resolved_len + 1 >= PATH_MAX) {
284+ errno = ENAMETOOLONG;
285+ return (NULL);
286+ }
287+ resolved[resolved_len++] = '/';
288+ resolved[resolved_len] = '\0';
289+ }
290+ if (next_token[0] == '\0')
291+ continue;
292+ else if (strcmp(next_token, ".") == 0)
293+ continue;
294+ else if (strcmp(next_token, "..") == 0) {
295+ /*
296+ * Strip the last path component except when we have
297+ * single "/"
298+ */
299+ if (!is_dir) {
300+ errno = ENOENT;
301+ return (NULL);
302+ }
303+ if (resolved_len > 1) {
304+ resolved[resolved_len - 1] = '\0';
305+ q = strrchr(resolved, '/');
306+ *q = '\0';
307+ resolved_len = q - resolved;
308+ }
309+ continue;
310+ }
311+
312+ /*
313+ * Append the next path component and lstat() it. If
314+ * lstat() fails we still can return successfully if
315+ * there are no more path components left.
316+ */
317+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
318+ if (resolved_len >= PATH_MAX) {
319+ errno = ENAMETOOLONG;
320+ return (NULL);
321+ }
322+ if (lstat(resolved, &sb) != 0) {
323+ if (errno == ENOENT && p == NULL) {
324+ errno = serrno;
325+ return (resolved);
326+ }
327+ return (NULL);
328+ }
329+ if (S_ISLNK(sb.st_mode)) {
330+ if (symlinks++ > MAXSYMLINKS) {
331+ errno = ELOOP;
332+ return (NULL);
333+ }
334+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
335+ if (slen < 0)
336+ return (NULL);
337+ symlink[slen] = '\0';
338+ if (symlink[0] == '/') {
339+ resolved[1] = 0;
340+ resolved_len = 1;
341+ } else if (resolved_len > 1) {
342+ /* Strip the last path component. */
343+ resolved[resolved_len - 1] = '\0';
344+ q = strrchr(resolved, '/');
345+ *q = '\0';
346+ resolved_len = q - resolved;
347+ }
348+
349+ /*
350+ * If there are any path components left, then
351+ * append them to symlink. The result is placed
352+ * in `left'.
353+ */
354+ if (p != NULL) {
355+ if (symlink[slen - 1] != '/') {
356+ if (slen + 1 >= sizeof(symlink)) {
357+ errno = ENAMETOOLONG;
358+ return (NULL);
359+ }
360+ symlink[slen] = '/';
361+ symlink[slen + 1] = 0;
362+ }
363+ left_len = strlcat(symlink, left, sizeof(left));
364+ if (left_len >= sizeof(left)) {
365+ errno = ENAMETOOLONG;
366+ return (NULL);
367+ }
368+ }
369+ left_len = strlcpy(left, symlink, sizeof(left));
370+ } else {
371+ if (S_ISDIR(sb.st_mode)) {
372+ is_dir = 1;
373+ } else {
374+ is_dir = 0;
375+ }
376+ }
377+ }
378+
379+ /*
380+ * Remove trailing slash except when the resolved pathname
381+ * is a single "/".
382+ */
383+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
384+ resolved[resolved_len - 1] = '\0';
385+ return (resolved);
386+}
387+#endif
388+
389 CWD_API void virtual_cwd_startup(void)
390 {
391 char cwd[MAXPATHLEN];
392@@ -314,8 +473,7 @@
393 path = resolved_path;
394 path_length = strlen(path);
395 } else {
396- /* disable for now
397- return 1; */
398+ return 1;
399 }
400 }
401 } else { /* Concat current directory with relative path and then run realpath() on it */
402@@ -341,9 +499,8 @@
403 path = resolved_path;
404 path_length = strlen(path);
405 } else {
406- /* disable for now
407 free(tmp);
408- return 1; */
409+ return 1;
410 }
411 }
412 free(tmp);
413diff -Nur php-4.3.11/TSRM/tsrm_virtual_cwd.h hardened-php-4.3.11-0.2.7/TSRM/tsrm_virtual_cwd.h
414--- php-4.3.11/TSRM/tsrm_virtual_cwd.h 2005-02-11 04:34:04.000000000 +0100
415+++ hardened-php-4.3.11-0.2.7/TSRM/tsrm_virtual_cwd.h 2005-04-07 02:08:26.000000000 +0200
416@@ -128,6 +128,22 @@
417
418 typedef int (*verify_path_func)(const cwd_state *);
419
420+#ifndef HAVE_STRLCPY
421+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
422+#undef strlcpy
423+#define strlcpy php_strlcpy
424+#endif
425+
426+#ifndef HAVE_STRLCAT
427+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
428+#undef strlcat
429+#define strlcat php_strlcat
430+#endif
431+
432+
433+#if HARDENED_PHP
434+CWD_API char *php_realpath(const char *path, char *resolved);
435+#endif
436 CWD_API void virtual_cwd_startup(void);
437 CWD_API void virtual_cwd_shutdown(void);
438 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
439diff -Nur php-4.3.11/Zend/zend.c hardened-php-4.3.11-0.2.7/Zend/zend.c
440--- php-4.3.11/Zend/zend.c 2005-01-22 21:36:34.000000000 +0100
441+++ hardened-php-4.3.11-0.2.7/Zend/zend.c 2005-04-07 02:08:26.000000000 +0200
442@@ -53,6 +53,12 @@
443 ZEND_API void (*zend_unblock_interruptions)(void);
444 ZEND_API void (*zend_ticks_function)(int ticks);
445 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
446+#if HARDENED_PHP
447+ZEND_API void (*zend_security_log)(char *str);
448+#endif
449+#if HARDENED_PHP_INC_PROTECT
450+ZEND_API int (*zend_is_valid_include)(zval *z);
451+#endif
452
453 void (*zend_on_timeout)(int seconds TSRMLS_DC);
454
455@@ -420,6 +426,14 @@
456 extern zend_scanner_globals language_scanner_globals;
457 #endif
458
459+ /* Set up Hardened-PHP utility functions first */
460+#if HARDENED_PHP
461+ zend_security_log = utility_functions->security_log_function;
462+#endif
463+#if HARDENED_PHP_INC_PROTECT
464+ zend_is_valid_include = utility_functions->is_valid_include;
465+#endif
466+
467 #ifdef ZTS
468 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
469 #else
470diff -Nur php-4.3.11/Zend/zend.h hardened-php-4.3.11-0.2.7/Zend/zend.h
471--- php-4.3.11/Zend/zend.h 2005-01-25 14:08:41.000000000 +0100
472+++ hardened-php-4.3.11-0.2.7/Zend/zend.h 2005-04-07 02:08:26.000000000 +0200
473@@ -275,9 +275,9 @@
474 struct _zval_struct {
475 /* Variable information */
476 zvalue_value value; /* value */
477+ zend_uint refcount;
478 zend_uchar type; /* active type */
479 zend_uchar is_ref;
480- zend_ushort refcount;
481 };
482
483
484@@ -338,6 +338,12 @@
485 void (*ticks_function)(int ticks);
486 void (*on_timeout)(int seconds TSRMLS_DC);
487 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
488+#if HARDENED_PHP
489+ void (*security_log_function)(char *str);
490+#endif
491+#if HARDENED_PHP_INC_PROTECT
492+ int (*is_valid_include)(zval *z);
493+#endif
494 } zend_utility_functions;
495
496
497@@ -469,7 +475,16 @@
498 extern ZEND_API void (*zend_ticks_function)(int ticks);
499 extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
500 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
501+#if HARDENED_PHP
502+extern ZEND_API void (*zend_security_log)(char *str);
503+#endif
504+#if HARDENED_PHP_INC_PROTECT
505+extern ZEND_API int (*zend_is_valid_include)(zval *z);
506+#endif
507
508+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
509+ZEND_API unsigned int zend_canary(void);
510+#endif
511
512 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
513
514@@ -576,6 +591,10 @@
515
516 #define ZEND_MAX_RESERVED_RESOURCES 4
517
518+#if HARDENED_PHP
519+#include "hardened_globals.h"
520+#endif
521+
522 #endif /* ZEND_H */
523
524 /*
525diff -Nur php-4.3.11/Zend/zend_alloc.c hardened-php-4.3.11-0.2.7/Zend/zend_alloc.c
526--- php-4.3.11/Zend/zend_alloc.c 2004-08-27 18:51:25.000000000 +0200
527+++ hardened-php-4.3.11-0.2.7/Zend/zend_alloc.c 2005-04-07 02:11:04.000000000 +0200
528@@ -56,6 +56,11 @@
529 # define END_MAGIC_SIZE 0
530 #endif
531
532+#if HARDENED_PHP_MM_PROTECT
533+# define CANARY_SIZE sizeof(unsigned int)
534+#else
535+# define CANARY_SIZE 0
536+#endif
537
538 # if MEMORY_LIMIT
539 # if ZEND_DEBUG
540@@ -95,9 +100,17 @@
541 if (p==AG(head)) { \
542 AG(head) = p->pNext; \
543 } else { \
544+ if (p != p->pLast->pNext) { \
545+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
546+ exit(1); \
547+ } \
548 p->pLast->pNext = p->pNext; \
549 } \
550 if (p->pNext) { \
551+ if (p != p->pNext->pLast) { \
552+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
553+ exit(1); \
554+ } \
555 p->pNext->pLast = p->pLast; \
556 }
557
558@@ -129,6 +142,12 @@
559 DECLARE_CACHE_VARS();
560 TSRMLS_FETCH();
561
562+#if HARDENED_PHP_MM_PROTECT
563+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
564+ zend_security_log("emalloc() - requested size would result in integer overflow");
565+ exit(1);
566+ }
567+#endif
568 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
569
570 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
571@@ -146,6 +165,10 @@
572 AG(cache_stats)[CACHE_INDEX][1]++;
573 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
574 #endif
575+#if HARDENED_PHP_MM_PROTECT
576+ p->canary = HG(canary_1);
577+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
578+#endif
579 p->cached = 0;
580 p->size = size;
581 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
582@@ -161,7 +184,7 @@
583 AG(allocated_memory_peak) = AG(allocated_memory);
584 }
585 #endif
586- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
587+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
588 }
589
590 HANDLE_BLOCK_INTERRUPTIONS();
591@@ -191,7 +214,10 @@
592 # endif
593 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
594 #endif
595-
596+#if HARDENED_PHP_MM_PROTECT
597+ p->canary = HG(canary_1);
598+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
599+#endif
600 HANDLE_UNBLOCK_INTERRUPTIONS();
601 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
602 }
603@@ -218,17 +244,33 @@
604 return emalloc_rel(lval + offset);
605 }
606 }
607-
608+
609+#if HARDENED_PHP
610+ zend_security_log("Possible integer overflow catched by safe_emalloc()");
611+#endif
612 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
613 return 0;
614 }
615
616 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
617 {
618+#if HARDENED_PHP_MM_PROTECT
619+ unsigned int *canary_2;
620+#endif
621 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
622 DECLARE_CACHE_VARS();
623 TSRMLS_FETCH();
624
625+#if HARDENED_PHP_MM_PROTECT
626+ canary_2 = (unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
627+ if (p->canary != HG(canary_1) || *canary_2 != HG(canary_2)) {
628+ zend_security_log("canary mismatch on efree() - heap overflow or double efree detected");
629+ exit(1);
630+ }
631+ /* to catch double efree()s */
632+ *canary_2 = p->canary = 0;
633+#endif
634+
635 #if defined(ZTS) && TSRM_DEBUG
636 if (p->thread_id != tsrm_thread_id()) {
637 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
638@@ -273,6 +315,9 @@
639 size_t _size = nmemb * size;
640
641 if (nmemb && (_size/nmemb!=size)) {
642+#if HARDENED_PHP
643+ zend_security_log("Possible integer overflow catched by ecalloc()");
644+#endif
645 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
646 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
647 kill(getpid(), SIGSEGV);
648@@ -292,6 +337,9 @@
649
650 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
651 {
652+#if HARDENED_PHP_MM_PROTECT
653+ unsigned int canary_2;
654+#endif
655 zend_mem_header *p;
656 zend_mem_header *orig;
657 DECLARE_CACHE_VARS();
658@@ -303,6 +351,14 @@
659
660 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
661
662+#if HARDENED_PHP_MM_PROTECT
663+ canary_2 = *(unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
664+ if (p->canary != HG(canary_1) || canary_2 != HG(canary_2)) {
665+ zend_security_log("canary mismatch on erealloc() - heap overflow detected");
666+ exit(1);
667+ }
668+#endif
669+
670 #if defined(ZTS) && TSRM_DEBUG
671 if (p->thread_id != tsrm_thread_id()) {
672 void *new_p;
673@@ -326,7 +382,7 @@
674 }
675 #endif
676 REMOVE_POINTER_FROM_LIST(p);
677- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
678+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
679 if (!p) {
680 if (!allow_failure) {
681 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
682@@ -348,6 +404,9 @@
683 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
684 #endif
685
686+#if HARDENED_PHP_MM_PROTECT
687+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
688+#endif
689 p->size = size;
690
691 HANDLE_UNBLOCK_INTERRUPTIONS();
692@@ -423,6 +482,10 @@
693 {
694 AG(head) = NULL;
695
696+#if HARDENED_PHP_MM_PROTECT
697+ HG(canary_1) = zend_canary();
698+ HG(canary_2) = zend_canary();
699+#endif
700 #if MEMORY_LIMIT
701 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
702 AG(allocated_memory) = 0;
703diff -Nur php-4.3.11/Zend/zend_alloc.h hardened-php-4.3.11-0.2.7/Zend/zend_alloc.h
704--- php-4.3.11/Zend/zend_alloc.h 2004-08-11 08:10:46.000000000 +0200
705+++ hardened-php-4.3.11-0.2.7/Zend/zend_alloc.h 2005-04-07 02:08:26.000000000 +0200
706@@ -32,6 +32,9 @@
707 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
708
709 typedef struct _zend_mem_header {
710+#if HARDENED_PHP_MM_PROTECT
711+ unsigned int canary;
712+#endif
713 #if ZEND_DEBUG
714 long magic;
715 char *filename;
716diff -Nur php-4.3.11/Zend/zend_builtin_functions.c hardened-php-4.3.11-0.2.7/Zend/zend_builtin_functions.c
717--- php-4.3.11/Zend/zend_builtin_functions.c 2004-12-27 20:28:35.000000000 +0100
718+++ hardened-php-4.3.11-0.2.7/Zend/zend_builtin_functions.c 2005-04-07 02:08:26.000000000 +0200
719@@ -49,6 +49,9 @@
720 static ZEND_FUNCTION(crash);
721 #endif
722 #endif
723+#if HARDENED_PHP_MM_PROTECT_DEBUG
724+static ZEND_FUNCTION(heap_overflow);
725+#endif
726 static ZEND_FUNCTION(get_included_files);
727 static ZEND_FUNCTION(is_subclass_of);
728 static ZEND_FUNCTION(is_a);
729@@ -101,6 +104,9 @@
730 ZEND_FE(crash, NULL)
731 #endif
732 #endif
733+#if HARDENED_PHP_MM_PROTECT_DEBUG
734+ ZEND_FE(heap_overflow, NULL)
735+#endif
736 ZEND_FE(get_included_files, NULL)
737 ZEND_FALIAS(get_required_files, get_included_files, NULL)
738 ZEND_FE(is_subclass_of, NULL)
739@@ -805,6 +811,19 @@
740
741 #endif /* ZEND_DEBUG */
742
743+
744+#if HARDENED_PHP_MM_PROTECT_DEBUG
745+ZEND_FUNCTION(heap_overflow)
746+{
747+ char *nowhere = emalloc(10);
748+
749+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
750+
751+ efree(nowhere);
752+}
753+#endif
754+
755+
756 /* {{{ proto array get_included_files(void)
757 Returns an array with the file names that were include_once()'d */
758 ZEND_FUNCTION(get_included_files)
759diff -Nur php-4.3.11/Zend/zend_canary.c hardened-php-4.3.11-0.2.7/Zend/zend_canary.c
760--- php-4.3.11/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
761+++ hardened-php-4.3.11-0.2.7/Zend/zend_canary.c 2005-04-07 02:08:26.000000000 +0200
762@@ -0,0 +1,58 @@
763+/*
764+ +----------------------------------------------------------------------+
765+ | Hardened-PHP |
766+ +----------------------------------------------------------------------+
767+ | Copyright (c) 2004 Stefan Esser |
768+ +----------------------------------------------------------------------+
769+ | This source file is subject to version 2.02 of the PHP license, |
770+ | that is bundled with this package in the file LICENSE, and is |
771+ | available at through the world-wide-web at |
772+ | http://www.php.net/license/2_02.txt. |
773+ | If you did not receive a copy of the PHP license and are unable to |
774+ | obtain it through the world-wide-web, please send a note to |
775+ | license@php.net so we can mail you a copy immediately. |
776+ +----------------------------------------------------------------------+
777+ | Author: Stefan Esser <sesser@php.net> |
778+ +----------------------------------------------------------------------+
779+ */
780+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
781+
782+#include "zend.h"
783+
784+#include <stdio.h>
785+#include <stdlib.h>
786+
787+
788+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT
789+
790+/* will be replaced later with more compatible method */
791+ZEND_API unsigned int zend_canary()
792+{
793+ time_t t;
794+ unsigned int canary;
795+ int fd;
796+
797+ fd = open("/dev/urandom", 0);
798+ if (fd != -1) {
799+ int r = read(fd, &canary, sizeof(canary));
800+ close(fd);
801+ if (r == sizeof(canary)) {
802+ return (canary);
803+ }
804+ }
805+ /* not good but we never want to do this */
806+ time(&t);
807+ canary = *(unsigned int *)&t + getpid() << 16;
808+ return (canary);
809+}
810+#endif
811+
812+
813+/*
814+ * Local variables:
815+ * tab-width: 4
816+ * c-basic-offset: 4
817+ * End:
818+ * vim600: sw=4 ts=4 fdm=marker
819+ * vim<600: sw=4 ts=4
820+ */
821diff -Nur php-4.3.11/Zend/zend_execute.c hardened-php-4.3.11-0.2.7/Zend/zend_execute.c
822--- php-4.3.11/Zend/zend_execute.c 2005-02-21 13:38:54.000000000 +0100
823+++ hardened-php-4.3.11-0.2.7/Zend/zend_execute.c 2005-04-07 02:08:26.000000000 +0200
824@@ -2161,7 +2161,12 @@
825 int dummy = 1;
826 zend_file_handle file_handle = {0};
827
828+#if HARDENED_PHP_INC_PROTECT
829+ if (zend_is_valid_include(inc_filename)
830+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
831+#else
832 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
833+#endif
834 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
835
836 file_handle.filename = inc_filename->value.str.val;
837@@ -2190,6 +2195,11 @@
838 break;
839 case ZEND_INCLUDE:
840 case ZEND_REQUIRE:
841+#if HARDENED_PHP_INC_PROTECT
842+ if (!zend_is_valid_include(inc_filename)) {
843+ break;
844+ }
845+#endif
846 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
847 break;
848 case ZEND_EVAL: {
849diff -Nur php-4.3.11/Zend/zend_extensions.h hardened-php-4.3.11-0.2.7/Zend/zend_extensions.h
850--- php-4.3.11/Zend/zend_extensions.h 2002-12-31 17:23:02.000000000 +0100
851+++ hardened-php-4.3.11-0.2.7/Zend/zend_extensions.h 2005-04-07 02:08:26.000000000 +0200
852@@ -23,7 +23,9 @@
853
854 #include "zend_compile.h"
855
856-#define ZEND_EXTENSION_API_NO 20021010
857+/* Create own API version number for Hardened-PHP */
858+
859+#define ZEND_EXTENSION_API_NO 1020041222
860
861 typedef struct _zend_extension_version_info {
862 int zend_extension_api_no;
863diff -Nur php-4.3.11/Zend/zend_hash.c hardened-php-4.3.11-0.2.7/Zend/zend_hash.c
864--- php-4.3.11/Zend/zend_hash.c 2004-07-12 23:26:46.000000000 +0200
865+++ hardened-php-4.3.11-0.2.7/Zend/zend_hash.c 2005-04-07 02:09:31.000000000 +0200
866@@ -26,6 +26,17 @@
867 # include <stdlib.h>
868 #endif
869
870+#if HARDENED_PHP_HASH_PROTECT
871+ unsigned int zend_hash_canary = 0x1234567;
872+ zend_bool zend_hash_canary_inited = 0;
873+#endif
874+
875+#define CHECK_HASH_CANARY(hash) \
876+ if (zend_hash_canary != (hash)->canary) { \
877+ zend_security_log("Zend HashTable canary was overwritten"); \
878+ exit(1); \
879+ }
880+
881 #define HANDLE_NUMERIC(key, length, func) { \
882 register char *tmp=key; \
883 \
884@@ -175,6 +186,9 @@
885 {
886 uint i = 3;
887 Bucket **tmp;
888+#if HARDENED_PHP_HASH_PROTECT
889+ TSRMLS_FETCH();
890+#endif
891
892 SET_INCONSISTENT(HT_OK);
893
894@@ -184,6 +198,13 @@
895
896 ht->nTableSize = 1 << i;
897 ht->nTableMask = ht->nTableSize - 1;
898+#if HARDENED_PHP_HASH_PROTECT
899+ if (zend_hash_canary_inited==0) {
900+ zend_hash_canary = zend_canary();
901+ zend_hash_canary_inited = 1;
902+ }
903+ ht->canary = zend_hash_canary;
904+#endif
905 ht->pDestructor = pDestructor;
906 ht->pListHead = NULL;
907 ht->pListTail = NULL;
908@@ -259,6 +280,9 @@
909 }
910 #endif
911 if (ht->pDestructor) {
912+#if HARDENED_PHP_HASH_PROTECT
913+ CHECK_HASH_CANARY(ht);
914+#endif
915 ht->pDestructor(p->pData);
916 }
917 UPDATE_DATA(ht, p, pData, nDataSize);
918@@ -327,6 +351,9 @@
919 }
920 #endif
921 if (ht->pDestructor) {
922+#if HARDENED_PHP_HASH_PROTECT
923+ CHECK_HASH_CANARY(ht);
924+#endif
925 ht->pDestructor(p->pData);
926 }
927 UPDATE_DATA(ht, p, pData, nDataSize);
928@@ -402,6 +429,9 @@
929 }
930 #endif
931 if (ht->pDestructor) {
932+#if HARDENED_PHP_HASH_PROTECT
933+ CHECK_HASH_CANARY(ht);
934+#endif
935 ht->pDestructor(p->pData);
936 }
937 UPDATE_DATA(ht, p, pData, nDataSize);
938@@ -450,7 +480,7 @@
939 IS_CONSISTENT(ht);
940
941 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
942- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
943+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
944 if (t) {
945 HANDLE_BLOCK_INTERRUPTIONS();
946 ht->arBuckets = t;
947@@ -460,6 +490,7 @@
948 HANDLE_UNBLOCK_INTERRUPTIONS();
949 return SUCCESS;
950 }
951+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
952 return FAILURE;
953 }
954 return SUCCESS;
955@@ -524,6 +555,9 @@
956 ht->pInternalPointer = p->pListNext;
957 }
958 if (ht->pDestructor) {
959+#if HARDENED_PHP_HASH_PROTECT
960+ CHECK_HASH_CANARY(ht);
961+#endif
962 ht->pDestructor(p->pData);
963 }
964 if (!p->pDataPtr) {
965@@ -553,6 +587,9 @@
966 q = p;
967 p = p->pListNext;
968 if (ht->pDestructor) {
969+#if HARDENED_PHP_HASH_PROTECT
970+ CHECK_HASH_CANARY(ht);
971+#endif
972 ht->pDestructor(q->pData);
973 }
974 if (!q->pDataPtr && q->pData) {
975@@ -579,6 +616,9 @@
976 q = p;
977 p = p->pListNext;
978 if (ht->pDestructor) {
979+#if HARDENED_PHP_HASH_PROTECT
980+ CHECK_HASH_CANARY(ht);
981+#endif
982 ht->pDestructor(q->pData);
983 }
984 if (!q->pDataPtr && q->pData) {
985@@ -608,6 +648,9 @@
986 HANDLE_BLOCK_INTERRUPTIONS();
987
988 if (ht->pDestructor) {
989+#if HARDENED_PHP_HASH_PROTECT
990+ CHECK_HASH_CANARY(ht);
991+#endif
992 ht->pDestructor(p->pData);
993 }
994 if (!p->pDataPtr) {
995diff -Nur php-4.3.11/Zend/zend_hash.h hardened-php-4.3.11-0.2.7/Zend/zend_hash.h
996--- php-4.3.11/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
997+++ hardened-php-4.3.11-0.2.7/Zend/zend_hash.h 2005-04-07 02:08:26.000000000 +0200
998@@ -54,6 +54,9 @@
999 } Bucket;
1000
1001 typedef struct _hashtable {
1002+#if HARDENED_PHP_HASH_PROTECT
1003+ unsigned int canary;
1004+#endif
1005 uint nTableSize;
1006 uint nTableMask;
1007 uint nNumOfElements;
1008diff -Nur php-4.3.11/Zend/zend_llist.c hardened-php-4.3.11-0.2.7/Zend/zend_llist.c
1009--- php-4.3.11/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
1010+++ hardened-php-4.3.11-0.2.7/Zend/zend_llist.c 2005-04-07 02:08:26.000000000 +0200
1011@@ -21,9 +21,34 @@
1012 #include "zend.h"
1013 #include "zend_llist.h"
1014 #include "zend_qsort.h"
1015+#include "zend_globals.h"
1016+
1017+#define CHECK_LIST_CANARY(list) \
1018+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
1019+ zend_security_log("linked list canary was overwritten"); \
1020+ exit(1); \
1021+ }
1022+
1023+#define CHECK_LISTELEMENT_CANARY(elem) \
1024+ if (HG(canary_3) != (elem)->canary) { \
1025+ zend_security_log("linked list element canary was overwritten"); \
1026+ exit(1); \
1027+ }
1028+
1029
1030 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
1031 {
1032+#if HARDENED_PHP_LL_PROTECT
1033+ TSRMLS_FETCH();
1034+
1035+ if (!HG(ll_canary_inited)) {
1036+ HG(canary_3) = zend_canary();
1037+ HG(canary_4) = zend_canary();
1038+ HG(ll_canary_inited) = 1;
1039+ }
1040+ l->canary_h = HG(canary_3);
1041+ l->canary_t = HG(canary_4);
1042+#endif
1043 l->head = NULL;
1044 l->tail = NULL;
1045 l->count = 0;
1046@@ -37,6 +62,11 @@
1047 {
1048 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1049
1050+#if HARDENED_PHP_LL_PROTECT
1051+ TSRMLS_FETCH();
1052+ CHECK_LIST_CANARY(l)
1053+ tmp->canary = HG(canary_3);
1054+#endif
1055 tmp->prev = l->tail;
1056 tmp->next = NULL;
1057 if (l->tail) {
1058@@ -55,6 +85,11 @@
1059 {
1060 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1061
1062+#if HARDENED_PHP_LL_PROTECT
1063+ TSRMLS_FETCH();
1064+ CHECK_LIST_CANARY(l)
1065+ tmp->canary = HG(canary_3);
1066+#endif
1067 tmp->next = l->head;
1068 tmp->prev = NULL;
1069 if (l->head) {
1070@@ -91,10 +126,20 @@
1071 zend_llist_element *current=l->head;
1072 zend_llist_element *next;
1073
1074+#if HARDENED_PHP_LL_PROTECT
1075+ TSRMLS_FETCH();
1076+ CHECK_LIST_CANARY(l)
1077+#endif
1078 while (current) {
1079+#if HARDENED_PHP_LL_PROTECT
1080+ CHECK_LISTELEMENT_CANARY(current)
1081+#endif
1082 next = current->next;
1083 if (compare(current->data, element)) {
1084 DEL_LLIST_ELEMENT(current, l);
1085+#if HARDENED_PHP_LL_PROTECT
1086+ current->canary = 0;
1087+#endif
1088 break;
1089 }
1090 current = next;
1091@@ -106,7 +151,14 @@
1092 {
1093 zend_llist_element *current=l->head, *next;
1094
1095+#if HARDENED_PHP_LL_PROTECT
1096+ TSRMLS_FETCH();
1097+ CHECK_LIST_CANARY(l)
1098+#endif
1099 while (current) {
1100+#if HARDENED_PHP_LL_PROTECT
1101+ CHECK_LISTELEMENT_CANARY(current)
1102+#endif
1103 next = current->next;
1104 if (l->dtor) {
1105 l->dtor(current->data);
1106@@ -131,7 +183,14 @@
1107 zend_llist_element *old_tail;
1108 void *data;
1109
1110+#if HARDENED_PHP_LL_PROTECT
1111+ TSRMLS_FETCH();
1112+ CHECK_LIST_CANARY(l)
1113+#endif
1114 if ((old_tail = l->tail)) {
1115+#if HARDENED_PHP_LL_PROTECT
1116+ CHECK_LISTELEMENT_CANARY(old_tail)
1117+#endif
1118 if (l->tail->prev) {
1119 l->tail->prev->next = NULL;
1120 }
1121@@ -157,9 +216,16 @@
1122 {
1123 zend_llist_element *ptr;
1124
1125+#if HARDENED_PHP_LL_PROTECT
1126+ TSRMLS_FETCH();
1127+ CHECK_LIST_CANARY(src)
1128+#endif
1129 zend_llist_init(dst, src->size, src->dtor, src->persistent);
1130 ptr = src->head;
1131 while (ptr) {
1132+#if HARDENED_PHP_LL_PROTECT
1133+ CHECK_LISTELEMENT_CANARY(ptr)
1134+#endif
1135 zend_llist_add_element(dst, ptr->data);
1136 ptr = ptr->next;
1137 }
1138@@ -170,11 +236,21 @@
1139 {
1140 zend_llist_element *element, *next;
1141
1142+#if HARDENED_PHP_LL_PROTECT
1143+ TSRMLS_FETCH();
1144+ CHECK_LIST_CANARY(l)
1145+#endif
1146 element=l->head;
1147 while (element) {
1148+#if HARDENED_PHP_LL_PROTECT
1149+ CHECK_LISTELEMENT_CANARY(element)
1150+#endif
1151 next = element->next;
1152 if (func(element->data)) {
1153 DEL_LLIST_ELEMENT(element, l);
1154+#if HARDENED_PHP_LL_PROTECT
1155+ element->canary = 0;
1156+#endif
1157 }
1158 element = next;
1159 }
1160@@ -185,7 +261,13 @@
1161 {
1162 zend_llist_element *element;
1163
1164+#if HARDENED_PHP_LL_PROTECT
1165+ CHECK_LIST_CANARY(l)
1166+#endif
1167 for (element=l->head; element; element=element->next) {
1168+#if HARDENED_PHP_LL_PROTECT
1169+ CHECK_LISTELEMENT_CANARY(element)
1170+#endif
1171 func(element->data TSRMLS_CC);
1172 }
1173 }
1174@@ -197,6 +279,9 @@
1175 zend_llist_element **elements;
1176 zend_llist_element *element, **ptr;
1177
1178+#if HARDENED_PHP_LL_PROTECT
1179+ CHECK_LIST_CANARY(l)
1180+#endif
1181 if (l->count <= 0) {
1182 return;
1183 }
1184@@ -206,6 +291,9 @@
1185 ptr = &elements[0];
1186
1187 for (element=l->head; element; element=element->next) {
1188+#if HARDENED_PHP_LL_PROTECT
1189+ CHECK_LISTELEMENT_CANARY(element)
1190+#endif
1191 *ptr++ = element;
1192 }
1193
1194@@ -228,7 +316,13 @@
1195 {
1196 zend_llist_element *element;
1197
1198+#if HARDENED_PHP_LL_PROTECT
1199+ CHECK_LIST_CANARY(l)
1200+#endif
1201 for (element=l->head; element; element=element->next) {
1202+#if HARDENED_PHP_LL_PROTECT
1203+ CHECK_LISTELEMENT_CANARY(element)
1204+#endif
1205 func(element->data, arg TSRMLS_CC);
1206 }
1207 }
1208@@ -239,8 +333,14 @@
1209 zend_llist_element *element;
1210 va_list args;
1211
1212+#if HARDENED_PHP_LL_PROTECT
1213+ CHECK_LIST_CANARY(l)
1214+#endif
1215 va_start(args, num_args);
1216 for (element=l->head; element; element=element->next) {
1217+#if HARDENED_PHP_LL_PROTECT
1218+ CHECK_LISTELEMENT_CANARY(element)
1219+#endif
1220 func(element->data, num_args, args TSRMLS_CC);
1221 }
1222 va_end(args);
1223@@ -249,6 +349,10 @@
1224
1225 ZEND_API int zend_llist_count(zend_llist *l)
1226 {
1227+#if HARDENED_PHP_LL_PROTECT
1228+ TSRMLS_FETCH();
1229+ CHECK_LIST_CANARY(l)
1230+#endif
1231 return l->count;
1232 }
1233
1234@@ -256,8 +360,15 @@
1235 {
1236 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1237
1238+#if HARDENED_PHP_LL_PROTECT
1239+ TSRMLS_FETCH();
1240+ CHECK_LIST_CANARY(l)
1241+#endif
1242 *current = l->head;
1243 if (*current) {
1244+#if HARDENED_PHP_LL_PROTECT
1245+ CHECK_LISTELEMENT_CANARY(*current)
1246+#endif
1247 return (*current)->data;
1248 } else {
1249 return NULL;
1250@@ -269,8 +380,15 @@
1251 {
1252 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1253
1254+#if HARDENED_PHP_LL_PROTECT
1255+ TSRMLS_FETCH();
1256+ CHECK_LIST_CANARY(l)
1257+#endif
1258 *current = l->tail;
1259 if (*current) {
1260+#if HARDENED_PHP_LL_PROTECT
1261+ CHECK_LISTELEMENT_CANARY(*current)
1262+#endif
1263 return (*current)->data;
1264 } else {
1265 return NULL;
1266@@ -282,9 +400,19 @@
1267 {
1268 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1269
1270+#if HARDENED_PHP_LL_PROTECT
1271+ TSRMLS_FETCH();
1272+ CHECK_LIST_CANARY(l)
1273+#endif
1274 if (*current) {
1275+#if HARDENED_PHP_LL_PROTECT
1276+ CHECK_LISTELEMENT_CANARY(*current)
1277+#endif
1278 *current = (*current)->next;
1279 if (*current) {
1280+#if HARDENED_PHP_LL_PROTECT
1281+ CHECK_LISTELEMENT_CANARY(*current)
1282+#endif
1283 return (*current)->data;
1284 }
1285 }
1286@@ -296,9 +424,19 @@
1287 {
1288 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1289
1290+#if HARDENED_PHP_LL_PROTECT
1291+ TSRMLS_FETCH();
1292+ CHECK_LIST_CANARY(l)
1293+#endif
1294 if (*current) {
1295+#if HARDENED_PHP_LL_PROTECT
1296+ CHECK_LISTELEMENT_CANARY(*current)
1297+#endif
1298 *current = (*current)->prev;
1299 if (*current) {
1300+#if HARDENED_PHP_LL_PROTECT
1301+ CHECK_LISTELEMENT_CANARY(*current)
1302+#endif
1303 return (*current)->data;
1304 }
1305 }
1306diff -Nur php-4.3.11/Zend/zend_llist.h hardened-php-4.3.11-0.2.7/Zend/zend_llist.h
1307--- php-4.3.11/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
1308+++ hardened-php-4.3.11-0.2.7/Zend/zend_llist.h 2005-04-07 02:08:26.000000000 +0200
1309@@ -24,6 +24,9 @@
1310 #include <stdlib.h>
1311
1312 typedef struct _zend_llist_element {
1313+#if HARDENED_PHP_LL_PROTECT
1314+ unsigned int canary;
1315+#endif
1316 struct _zend_llist_element *next;
1317 struct _zend_llist_element *prev;
1318 char data[1]; /* Needs to always be last in the struct */
1319@@ -36,6 +39,9 @@
1320 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
1321
1322 typedef struct _zend_llist {
1323+#if HARDENED_PHP_LL_PROTECT
1324+ unsigned int canary_h; /* head */
1325+#endif
1326 zend_llist_element *head;
1327 zend_llist_element *tail;
1328 size_t size;
1329@@ -43,6 +49,9 @@
1330 llist_dtor_func_t dtor;
1331 unsigned char persistent;
1332 zend_llist_element *traverse_ptr;
1333+#if HARDENED_PHP_LL_PROTECT
1334+ unsigned int canary_t; /* tail */
1335+#endif
1336 } zend_llist;
1337
1338 typedef zend_llist_element* zend_llist_position;
1339diff -Nur php-4.3.11/Zend/zend_modules.h hardened-php-4.3.11-0.2.7/Zend/zend_modules.h
1340--- php-4.3.11/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
1341+++ hardened-php-4.3.11-0.2.7/Zend/zend_modules.h 2005-04-07 02:08:26.000000000 +0200
1342@@ -34,7 +34,7 @@
1343 ZEND_API extern unsigned char second_arg_force_ref[];
1344 ZEND_API extern unsigned char third_arg_force_ref[];
1345
1346-#define ZEND_MODULE_API_NO 20020429
1347+#define ZEND_MODULE_API_NO 1020041222
1348 #ifdef ZTS
1349 #define USING_ZTS 1
1350 #else
1351diff -Nur php-4.3.11/acinclude.m4 hardened-php-4.3.11-0.2.7/acinclude.m4
1352--- php-4.3.11/acinclude.m4 2005-01-25 14:03:06.000000000 +0100
1353+++ hardened-php-4.3.11-0.2.7/acinclude.m4 2005-04-07 02:08:26.000000000 +0200
1354@@ -1173,6 +1173,36 @@
1355 fi
1356 ])
1357
1358+dnl
1359+dnl Check for broken realpath()
1360+dnl
1361+dnl realpath("/etc/hosts/../passwd",XXX) should not return
1362+dnl "/etc/passwd"
1363+dnl
1364+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
1365+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
1366+ AC_TRY_RUN([
1367+main() {
1368+ char buf[4096+1];
1369+ buf[0] = 0;
1370+ realpath("/etc/hosts/../passwd", buf);
1371+ exit(strcmp(buf, "/etc/passwd")==0);
1372+}
1373+ ],[
1374+ ac_cv_broken_realpath=no
1375+ ],[
1376+ ac_cv_broken_realpath=yes
1377+ ],[
1378+ ac_cv_broken_realpath=no
1379+ ])
1380+ ])
1381+ if test "$ac_cv_broken_realpath" = "yes"; then
1382+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
1383+ else
1384+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
1385+ fi
1386+])
1387+
1388 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
1389 dnl
1390 dnl Basically sets up the link-stage for building module-name
1391diff -Nur php-4.3.11/configure hardened-php-4.3.11-0.2.7/configure
1392--- php-4.3.11/configure 2005-03-30 16:35:34.000000000 +0200
1393+++ hardened-php-4.3.11-0.2.7/configure 2005-04-07 02:08:26.000000000 +0200
1394@@ -394,6 +394,16 @@
1395 ac_default_prefix=/usr/local
1396 # Any additions from configure.in:
1397 ac_help="$ac_help
1398+ --disable-hardened-php-mm-protect Disable the Memory Manager protection."
1399+ac_help="$ac_help
1400+ --disable-hardened-php-ll-protect Disable the Linked List protection."
1401+ac_help="$ac_help
1402+ --disable-hardened-php-inc-protect Disable include/require protection."
1403+ac_help="$ac_help
1404+ --disable-hardened-php-fmt-protect Disable format string protection."
1405+ac_help="$ac_help
1406+ --disable-hardened-php-hash-protect Disable Zend HashTable DTOR protection."
1407+ac_help="$ac_help
1408
1409 SAPI modules:
1410 "
1411@@ -846,6 +856,8 @@
1412 ac_help="$ac_help
1413 --disable-tokenizer Disable tokenizer support"
1414 ac_help="$ac_help
1415+ --disable-varfilter Disable Hardened-PHP's variable filter"
1416+ac_help="$ac_help
1417 --enable-wddx Enable WDDX support."
1418 ac_help="$ac_help
1419 --disable-xml Disable XML support using bundled expat lib"
1420@@ -2669,6 +2681,157 @@
1421
1422
1423
1424+# Check whether --enable-hardened-php-mm-protect or --disable-hardened-php-mm-protect was given.
1425+if test "${enable_hardened_php_mm_protect+set}" = set; then
1426+ enableval="$enable_hardened_php_mm_protect"
1427+
1428+ DO_HARDENED_PHP_MM_PROTECT=$enableval
1429+
1430+else
1431+
1432+ DO_HARDENED_PHP_MM_PROTECT=yes
1433+
1434+fi
1435+
1436+
1437+# Check whether --enable-hardened-php-ll-protect or --disable-hardened-php-ll-protect was given.
1438+if test "${enable_hardened_php_ll_protect+set}" = set; then
1439+ enableval="$enable_hardened_php_ll_protect"
1440+
1441+ DO_HARDENED_PHP_LL_PROTECT=$enableval
1442+
1443+else
1444+
1445+ DO_HARDENED_PHP_LL_PROTECT=yes
1446+
1447+fi
1448+
1449+
1450+# Check whether --enable-hardened-php-inc-protect or --disable-hardened-php-inc-protect was given.
1451+if test "${enable_hardened_php_inc_protect+set}" = set; then
1452+ enableval="$enable_hardened_php_inc_protect"
1453+
1454+ DO_HARDENED_PHP_INC_PROTECT=$enableval
1455+
1456+else
1457+
1458+ DO_HARDENED_PHP_INC_PROTECT=yes
1459+
1460+fi
1461+
1462+
1463+# Check whether --enable-hardened-php-fmt-protect or --disable-hardened-php-fmt-protect was given.
1464+if test "${enable_hardened_php_fmt_protect+set}" = set; then
1465+ enableval="$enable_hardened_php_fmt_protect"
1466+
1467+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
1468+
1469+else
1470+
1471+ DO_HARDENED_PHP_FMT_PROTECT=yes
1472+
1473+fi
1474+
1475+
1476+# Check whether --enable-hardened-php-hash-protect or --disable-hardened-php-hash-protect was given.
1477+if test "${enable_hardened_php_hash_protect+set}" = set; then
1478+ enableval="$enable_hardened_php_hash_protect"
1479+
1480+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
1481+
1482+else
1483+
1484+ DO_HARDENED_PHP_HASH_PROTECT=yes
1485+
1486+fi
1487+
1488+
1489+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
1490+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
1491+echo "$ac_t""$DO_HARDENED_PHP_MM_PROTECT" 1>&6
1492+
1493+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
1494+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
1495+echo "$ac_t""$DO_HARDENED_PHP_LL_PROTECT" 1>&6
1496+
1497+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
1498+echo "configure:2733: checking whether to protect include/require statements" >&5
1499+echo "$ac_t""$DO_HARDENED_PHP_INC_PROTECT" 1>&6
1500+
1501+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
1502+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
1503+echo "$ac_t""$DO_HARDENED_PHP_FMT_PROTECT" 1>&6
1504+
1505+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
1506+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
1507+echo "$ac_t""$DO_HARDENED_PHP_HASH_PROTECT" 1>&6
1508+
1509+
1510+cat >> confdefs.h <<\EOF
1511+#define HARDENED_PHP 1
1512+EOF
1513+
1514+
1515+
1516+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
1517+ cat >> confdefs.h <<\EOF
1518+#define HARDENED_PHP_MM_PROTECT 1
1519+EOF
1520+
1521+else
1522+ cat >> confdefs.h <<\EOF
1523+#define HARDENED_PHP_MM_PROTECT 0
1524+EOF
1525+
1526+fi
1527+
1528+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
1529+ cat >> confdefs.h <<\EOF
1530+#define HARDENED_PHP_LL_PROTECT 1
1531+EOF
1532+
1533+else
1534+ cat >> confdefs.h <<\EOF
1535+#define HARDENED_PHP_LL_PROTECT 0
1536+EOF
1537+
1538+fi
1539+
1540+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
1541+ cat >> confdefs.h <<\EOF
1542+#define HARDENED_PHP_INC_PROTECT 1
1543+EOF
1544+
1545+else
1546+ cat >> confdefs.h <<\EOF
1547+#define HARDENED_PHP_INC_PROTECT 0
1548+EOF
1549+
1550+fi
1551+
1552+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
1553+ cat >> confdefs.h <<\EOF
1554+#define HARDENED_PHP_FMT_PROTECT 1
1555+EOF
1556+
1557+else
1558+ cat >> confdefs.h <<\EOF
1559+#define HARDENED_PHP_FMT_PROTECT 0
1560+EOF
1561+
1562+fi
1563+
1564+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
1565+ cat >> confdefs.h <<\EOF
1566+#define HARDENED_PHP_HASH_PROTECT 1
1567+EOF
1568+
1569+else
1570+ cat >> confdefs.h <<\EOF
1571+#define HARDENED_PHP_HASH_PROTECT 0
1572+EOF
1573+
1574+fi
1575
1576
1577
1578@@ -15486,6 +15649,62 @@
1579 fi
1580
1581
1582+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
1583+echo "configure:14928: checking whether realpath is broken" >&5
1584+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
1585+ echo $ac_n "(cached) $ac_c" 1>&6
1586+else
1587+
1588+ if test "$cross_compiling" = yes; then
1589+
1590+ ac_cv_broken_realpath=no
1591+
1592+else
1593+ cat > conftest.$ac_ext <<EOF
1594+#line 14939 "configure"
1595+#include "confdefs.h"
1596+
1597+main() {
1598+ char buf[4096+1];
1599+ buf[0] = 0;
1600+ realpath("/etc/hosts/../passwd", buf);
1601+ exit(strcmp(buf, "/etc/passwd")==0);
1602+}
1603+
1604+EOF
1605+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
1606+then
1607+
1608+ ac_cv_broken_realpath=no
1609+
1610+else
1611+ echo "configure: failed program was:" >&5
1612+ cat conftest.$ac_ext >&5
1613+ rm -fr conftest*
1614+
1615+ ac_cv_broken_realpath=yes
1616+
1617+fi
1618+rm -fr conftest*
1619+fi
1620+
1621+
1622+fi
1623+
1624+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
1625+ if test "$ac_cv_broken_realpath" = "yes"; then
1626+ cat >> confdefs.h <<\EOF
1627+#define PHP_BROKEN_REALPATH 1
1628+EOF
1629+
1630+ else
1631+ cat >> confdefs.h <<\EOF
1632+#define PHP_BROKEN_REALPATH 0
1633+EOF
1634+
1635+ fi
1636+
1637+
1638 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
1639 echo "configure:15491: checking for declared timezone" >&5
1640 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
1641@@ -85975,6 +86194,265 @@
1642 fi
1643
1644
1645+echo $ac_n "checking whether to enable Hardened-PHP's variable filter""... $ac_c" 1>&6
1646+echo "configure:82041: checking whether to enable Hardened-PHP's variable filter" >&5
1647+# Check whether --enable-varfilter or --disable-varfilter was given.
1648+if test "${enable_varfilter+set}" = set; then
1649+ enableval="$enable_varfilter"
1650+ PHP_VARFILTER=$enableval
1651+else
1652+
1653+ PHP_VARFILTER=yes
1654+
1655+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
1656+ PHP_VARFILTER=$PHP_ENABLE_ALL
1657+ fi
1658+
1659+fi
1660+
1661+
1662+
1663+ext_output="yes, shared"
1664+ext_shared=yes
1665+case $PHP_VARFILTER in
1666+shared,*)
1667+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
1668+ ;;
1669+shared)
1670+ PHP_VARFILTER=yes
1671+ ;;
1672+no)
1673+ ext_output=no
1674+ ext_shared=no
1675+ ;;
1676+*)
1677+ ext_output=yes
1678+ ext_shared=no
1679+ ;;
1680+esac
1681+
1682+
1683+
1684+echo "$ac_t""$ext_output" 1>&6
1685+
1686+
1687+
1688+
1689+if test "$PHP_VARFILTER" != "no"; then
1690+ cat >> confdefs.h <<\EOF
1691+#define HAVE_VARFILTER 1
1692+EOF
1693+
1694+
1695+ ext_builddir=ext/varfilter
1696+ ext_srcdir=$abs_srcdir/ext/varfilter
1697+
1698+ ac_extra=
1699+
1700+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
1701+
1702+
1703+
1704+ case ext/varfilter in
1705+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1706+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1707+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1708+ esac
1709+
1710+
1711+
1712+ b_c_pre=$php_c_pre
1713+ b_cxx_pre=$php_cxx_pre
1714+ b_c_meta=$php_c_meta
1715+ b_cxx_meta=$php_cxx_meta
1716+ b_c_post=$php_c_post
1717+ b_cxx_post=$php_cxx_post
1718+ b_lo=$php_lo
1719+
1720+
1721+ old_IFS=$IFS
1722+ for ac_src in varfilter.c; do
1723+
1724+ IFS=.
1725+ set $ac_src
1726+ ac_obj=$1
1727+ IFS=$old_IFS
1728+
1729+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1730+
1731+ case $ac_src in
1732+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1733+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1734+ esac
1735+
1736+ cat >>Makefile.objects<<EOF
1737+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1738+ $ac_comp
1739+EOF
1740+ done
1741+
1742+
1743+ EXT_STATIC="$EXT_STATIC varfilter"
1744+ if test "$ext_shared" != "nocli"; then
1745+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1746+ fi
1747+ else
1748+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
1749+
1750+ case ext/varfilter in
1751+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1752+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1753+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1754+ esac
1755+
1756+
1757+
1758+ b_c_pre=$shared_c_pre
1759+ b_cxx_pre=$shared_cxx_pre
1760+ b_c_meta=$shared_c_meta
1761+ b_cxx_meta=$shared_cxx_meta
1762+ b_c_post=$shared_c_post
1763+ b_cxx_post=$shared_cxx_post
1764+ b_lo=$shared_lo
1765+
1766+
1767+ old_IFS=$IFS
1768+ for ac_src in varfilter.c; do
1769+
1770+ IFS=.
1771+ set $ac_src
1772+ ac_obj=$1
1773+ IFS=$old_IFS
1774+
1775+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
1776+
1777+ case $ac_src in
1778+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1779+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1780+ esac
1781+
1782+ cat >>Makefile.objects<<EOF
1783+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1784+ $ac_comp
1785+EOF
1786+ done
1787+
1788+
1789+ install_modules="install-modules"
1790+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
1791+
1792+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
1793+
1794+ cat >>Makefile.objects<<EOF
1795+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
1796+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
1797+
1798+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
1799+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
1800+
1801+EOF
1802+
1803+ cat >> confdefs.h <<EOF
1804+#define COMPILE_DL_VARFILTER 1
1805+EOF
1806+
1807+ fi
1808+ fi
1809+
1810+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
1811+ if test "$PHP_SAPI" = "cgi"; then
1812+
1813+
1814+ case ext/varfilter in
1815+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1816+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1817+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1818+ esac
1819+
1820+
1821+
1822+ b_c_pre=$php_c_pre
1823+ b_cxx_pre=$php_cxx_pre
1824+ b_c_meta=$php_c_meta
1825+ b_cxx_meta=$php_cxx_meta
1826+ b_c_post=$php_c_post
1827+ b_cxx_post=$php_cxx_post
1828+ b_lo=$php_lo
1829+
1830+
1831+ old_IFS=$IFS
1832+ for ac_src in varfilter.c; do
1833+
1834+ IFS=.
1835+ set $ac_src
1836+ ac_obj=$1
1837+ IFS=$old_IFS
1838+
1839+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1840+
1841+ case $ac_src in
1842+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1843+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1844+ esac
1845+
1846+ cat >>Makefile.objects<<EOF
1847+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1848+ $ac_comp
1849+EOF
1850+ done
1851+
1852+
1853+ EXT_STATIC="$EXT_STATIC varfilter"
1854+ else
1855+
1856+
1857+ case ext/varfilter in
1858+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1859+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1860+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1861+ esac
1862+
1863+
1864+
1865+ b_c_pre=$php_c_pre
1866+ b_cxx_pre=$php_cxx_pre
1867+ b_c_meta=$php_c_meta
1868+ b_cxx_meta=$php_cxx_meta
1869+ b_c_post=$php_c_post
1870+ b_cxx_post=$php_cxx_post
1871+ b_lo=$php_lo
1872+
1873+
1874+ old_IFS=$IFS
1875+ for ac_src in varfilter.c; do
1876+
1877+ IFS=.
1878+ set $ac_src
1879+ ac_obj=$1
1880+ IFS=$old_IFS
1881+
1882+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
1883+
1884+ case $ac_src in
1885+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1886+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1887+ esac
1888+
1889+ cat >>Makefile.objects<<EOF
1890+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1891+ $ac_comp
1892+EOF
1893+ done
1894+
1895+
1896+ fi
1897+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1898+ fi
1899+
1900+ BUILD_DIR="$BUILD_DIR $ext_builddir"
1901+
1902+
1903+fi
1904
1905
1906 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
1907@@ -98629,7 +99107,7 @@
1908 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1909 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1910 streams.c network.c php_open_temporary_file.c php_logos.c \
1911- output.c memory_streams.c user_streams.c; do
1912+ output.c memory_streams.c user_streams.c hardened_php.c; do
1913
1914 IFS=.
1915 set $ac_src
1916@@ -98802,7 +99280,7 @@
1917 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1918 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1919 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1920- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
1921+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
1922
1923 IFS=.
1924 set $ac_src
1925diff -Nur php-4.3.11/configure.in hardened-php-4.3.11-0.2.7/configure.in
1926--- php-4.3.11/configure.in 2005-03-30 16:18:36.000000000 +0200
1927+++ hardened-php-4.3.11-0.2.7/configure.in 2005-04-07 02:08:26.000000000 +0200
1928@@ -227,7 +227,7 @@
1929 sinclude(Zend/acinclude.m4)
1930 sinclude(Zend/Zend.m4)
1931 sinclude(TSRM/tsrm.m4)
1932-
1933+sinclude(main/hardened_php.m4)
1934
1935
1936 divert(2)
1937@@ -595,6 +595,7 @@
1938 AC_FUNC_ALLOCA
1939 dnl PHP_AC_BROKEN_SPRINTF
1940 dnl PHP_AC_BROKEN_SNPRINTF
1941+PHP_AC_BROKEN_REALPATH
1942 PHP_DECLARED_TIMEZONE
1943 PHP_TIME_R_TYPE
1944 PHP_READDIR_R_TYPE
1945@@ -1224,7 +1225,7 @@
1946 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1947 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1948 streams.c network.c php_open_temporary_file.c php_logos.c \
1949- output.c memory_streams.c user_streams.c)
1950+ output.c memory_streams.c user_streams.c hardened_php.c)
1951 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
1952 PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
1953
1954@@ -1237,7 +1238,7 @@
1955 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1956 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1957 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1958- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
1959+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
1960
1961 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1962 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
1963diff -Nur php-4.3.11/ext/mbstring/mbstring.c hardened-php-4.3.11-0.2.7/ext/mbstring/mbstring.c
1964--- php-4.3.11/ext/mbstring/mbstring.c 2005-02-21 09:03:47.000000000 +0100
1965+++ hardened-php-4.3.11-0.2.7/ext/mbstring/mbstring.c 2005-04-07 02:08:26.000000000 +0200
1966@@ -1487,6 +1487,7 @@
1967 char *strtok_buf = NULL, **val_list;
1968 zval *array_ptr = (zval *) arg;
1969 int n, num, val_len, *len_list;
1970+ unsigned int new_val_len;
1971 enum mbfl_no_encoding from_encoding;
1972 mbfl_string string, resvar, resval;
1973 mbfl_encoding_detector *identd = NULL;
1974@@ -1609,8 +1610,14 @@
1975 val_len = len_list[n];
1976 }
1977 n++;
1978- /* add variable to symbol table */
1979- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
1980+ /* we need val to be emalloc()ed */
1981+ val = estrndup(val, val_len);
1982+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
1983+ /* add variable to symbol table */
1984+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
1985+ }
1986+ efree(val);
1987+
1988 if (convd != NULL){
1989 mbfl_string_clear(&resvar);
1990 mbfl_string_clear(&resval);
1991diff -Nur php-4.3.11/ext/standard/array.c hardened-php-4.3.11-0.2.7/ext/standard/array.c
1992--- php-4.3.11/ext/standard/array.c 2004-12-23 17:40:03.000000000 +0100
1993+++ hardened-php-4.3.11-0.2.7/ext/standard/array.c 2005-04-07 02:08:26.000000000 +0200
1994@@ -1153,6 +1153,31 @@
1995 }
1996 }
1997 }
1998+
1999+ if (var_name[0] == 'H') {
2000+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
2001+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
2002+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
2003+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
2004+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
2005+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
2006+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)) {
2007+ return 0;
2008+ }
2009+ } else if (var_name[0] == '_') {
2010+ if ((strcmp(var_name, "_COOKIE")==0)||
2011+ (strcmp(var_name, "_ENV")==0)||
2012+ (strcmp(var_name, "_FILES")==0)||
2013+ (strcmp(var_name, "_GET")==0)||
2014+ (strcmp(var_name, "_POST")==0)||
2015+ (strcmp(var_name, "_REQUEST")==0)||
2016+ (strcmp(var_name, "_SESSION")==0)||
2017+ (strcmp(var_name, "_SERVER")==0)) {
2018+ return 0;
2019+ }
2020+ } else if (strcmp(var_name, "GLOBALS")==0) {
2021+ return 0;
2022+ }
2023
2024 return 1;
2025 }
2026diff -Nur php-4.3.11/ext/standard/basic_functions.c hardened-php-4.3.11-0.2.7/ext/standard/basic_functions.c
2027--- php-4.3.11/ext/standard/basic_functions.c 2005-01-18 12:01:20.000000000 +0100
2028+++ hardened-php-4.3.11-0.2.7/ext/standard/basic_functions.c 2005-04-07 02:08:26.000000000 +0200
2029@@ -687,7 +687,7 @@
2030 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
2031
2032 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2033- PHP_FE(realpath, NULL)
2034+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
2035 #endif
2036
2037 #ifdef HAVE_FNMATCH
2038@@ -3020,6 +3020,34 @@
2039 memcpy(new_key, prefix, prefix_len);
2040 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
2041
2042+ if (new_key[0] == 'H') {
2043+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
2044+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
2045+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
2046+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
2047+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
2048+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
2049+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)) {
2050+ efree(new_key);
2051+ return 0;
2052+ }
2053+ } else if (new_key[0] == '_') {
2054+ if ((strcmp(new_key, "_COOKIE")==0)||
2055+ (strcmp(new_key, "_ENV")==0)||
2056+ (strcmp(new_key, "_FILES")==0)||
2057+ (strcmp(new_key, "_GET")==0)||
2058+ (strcmp(new_key, "_POST")==0)||
2059+ (strcmp(new_key, "_REQUEST")==0)||
2060+ (strcmp(new_key, "_SESSION")==0)||
2061+ (strcmp(new_key, "_SERVER")==0)) {
2062+ efree(new_key);
2063+ return 0;
2064+ }
2065+ } else if (strcmp(new_key, "GLOBALS")==0) {
2066+ efree(new_key);
2067+ return 0;
2068+ }
2069+
2070 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
2071 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
2072
2073diff -Nur php-4.3.11/ext/standard/file.c hardened-php-4.3.11-0.2.7/ext/standard/file.c
2074--- php-4.3.11/ext/standard/file.c 2005-03-27 17:53:59.000000000 +0200
2075+++ hardened-php-4.3.11-0.2.7/ext/standard/file.c 2005-04-07 02:08:26.000000000 +0200
2076@@ -2469,7 +2469,7 @@
2077 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2078 /* {{{ proto string realpath(string path)
2079 Return the resolved path */
2080-PHP_FUNCTION(realpath)
2081+PHP_FUNCTION(real_path)
2082 {
2083 zval **path;
2084 char resolved_path_buff[MAXPATHLEN];
2085diff -Nur php-4.3.11/ext/standard/file.h hardened-php-4.3.11-0.2.7/ext/standard/file.h
2086--- php-4.3.11/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
2087+++ hardened-php-4.3.11-0.2.7/ext/standard/file.h 2005-04-07 02:08:26.000000000 +0200
2088@@ -64,7 +64,7 @@
2089 PHP_FUNCTION(fd_set);
2090 PHP_FUNCTION(fd_isset);
2091 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2092-PHP_FUNCTION(realpath);
2093+PHP_FUNCTION(real_path);
2094 #endif
2095 #ifdef HAVE_FNMATCH
2096 PHP_FUNCTION(fnmatch);
2097diff -Nur php-4.3.11/ext/standard/info.c hardened-php-4.3.11-0.2.7/ext/standard/info.c
2098--- php-4.3.11/ext/standard/info.c 2004-06-09 17:10:19.000000000 +0200
2099+++ hardened-php-4.3.11-0.2.7/ext/standard/info.c 2005-04-07 02:08:26.000000000 +0200
2100@@ -397,7 +397,7 @@
2101
2102 if (flag & PHP_INFO_GENERAL) {
2103 char *zend_version = get_zend_version();
2104- char temp_api[9];
2105+ char temp_api[11];
2106
2107 php_uname = php_get_uname('a');
2108
2109@@ -417,11 +417,22 @@
2110 }
2111 }
2112
2113+#if HARDENED_PHP
2114+ if (!sapi_module.phpinfo_as_text) {
2115+ php_printf("<h1 class=\"p\">Hardened-PHP Version %s/%s</h1>\n", PHP_VERSION, HARDENED_PHP_VERSION);
2116+ } else {
2117+ char temp_ver[40];
2118+
2119+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENED_PHP_VERSION);
2120+ php_info_print_table_row(2, "Hardened-PHP Version", temp_ver);
2121+ }
2122+#else
2123 if (!sapi_module.phpinfo_as_text) {
2124 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2125 } else {
2126 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2127 }
2128+#endif
2129 php_info_print_box_end();
2130 php_info_print_table_start();
2131 php_info_print_table_row(2, "System", php_uname );
2132diff -Nur php-4.3.11/ext/varfilter/CREDITS hardened-php-4.3.11-0.2.7/ext/varfilter/CREDITS
2133--- php-4.3.11/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2134+++ hardened-php-4.3.11-0.2.7/ext/varfilter/CREDITS 2005-04-07 02:08:26.000000000 +0200
2135@@ -0,0 +1,2 @@
2136+varfilter
2137+Stefan Esser
2138\ No newline at end of file
2139diff -Nur php-4.3.11/ext/varfilter/config.m4 hardened-php-4.3.11-0.2.7/ext/varfilter/config.m4
2140--- php-4.3.11/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2141+++ hardened-php-4.3.11-0.2.7/ext/varfilter/config.m4 2005-04-07 02:08:26.000000000 +0200
2142@@ -0,0 +1,11 @@
2143+dnl
2144+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2145+dnl
2146+
2147+PHP_ARG_ENABLE(varfilter, whether to enable Hardened-PHP's variable filter,
2148+[ --disable-varfilter Disable Hardened-PHP's variable filter], yes)
2149+
2150+if test "$PHP_VARFILTER" != "no"; then
2151+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2152+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2153+fi
2154diff -Nur php-4.3.11/ext/varfilter/php_varfilter.h hardened-php-4.3.11-0.2.7/ext/varfilter/php_varfilter.h
2155--- php-4.3.11/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2156+++ hardened-php-4.3.11-0.2.7/ext/varfilter/php_varfilter.h 2005-04-07 02:08:26.000000000 +0200
2157@@ -0,0 +1,72 @@
2158+/*
2159+ +----------------------------------------------------------------------+
2160+ | PHP Version 4 |
2161+ +----------------------------------------------------------------------+
2162+ | Copyright (c) 1997-2003 The PHP Group |
2163+ +----------------------------------------------------------------------+
2164+ | This source file is subject to version 2.02 of the PHP license, |
2165+ | that is bundled with this package in the file LICENSE, and is |
2166+ | available at through the world-wide-web at |
2167+ | http://www.php.net/license/2_02.txt. |
2168+ | If you did not receive a copy of the PHP license and are unable to |
2169+ | obtain it through the world-wide-web, please send a note to |
2170+ | license@php.net so we can mail you a copy immediately. |
2171+ +----------------------------------------------------------------------+
2172+ | Author: Stefan Esser |
2173+ +----------------------------------------------------------------------+
2174+
2175+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2176+*/
2177+
2178+#ifndef PHP_VARFILTER_H
2179+#define PHP_VARFILTER_H
2180+
2181+extern zend_module_entry varfilter_module_entry;
2182+#define phpext_varfilter_ptr &varfilter_module_entry
2183+
2184+#ifdef PHP_WIN32
2185+#define PHP_VARFILTER_API __declspec(dllexport)
2186+#else
2187+#define PHP_VARFILTER_API
2188+#endif
2189+
2190+#ifdef ZTS
2191+#include "TSRM.h"
2192+#endif
2193+
2194+#include "SAPI.h"
2195+
2196+PHP_MINIT_FUNCTION(varfilter);
2197+PHP_MSHUTDOWN_FUNCTION(varfilter);
2198+PHP_RINIT_FUNCTION(varfilter);
2199+PHP_RSHUTDOWN_FUNCTION(varfilter);
2200+PHP_MINFO_FUNCTION(varfilter);
2201+
2202+
2203+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2204+ long max_request_variables;
2205+ long cur_request_variables;
2206+ long max_varname_length;
2207+ long max_value_length;
2208+ long max_array_depth;
2209+ZEND_END_MODULE_GLOBALS(varfilter)
2210+
2211+
2212+#ifdef ZTS
2213+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2214+#else
2215+#define VARFILTER_G(v) (varfilter_globals.v)
2216+#endif
2217+
2218+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2219+
2220+#endif /* PHP_VARFILTER_H */
2221+
2222+
2223+/*
2224+ * Local variables:
2225+ * tab-width: 4
2226+ * c-basic-offset: 4
2227+ * indent-tabs-mode: t
2228+ * End:
2229+ */
2230diff -Nur php-4.3.11/ext/varfilter/varfilter.c hardened-php-4.3.11-0.2.7/ext/varfilter/varfilter.c
2231--- php-4.3.11/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2232+++ hardened-php-4.3.11-0.2.7/ext/varfilter/varfilter.c 2005-04-07 02:08:26.000000000 +0200
2233@@ -0,0 +1,196 @@
2234+/*
2235+ +----------------------------------------------------------------------+
2236+ | PHP Version 4 |
2237+ +----------------------------------------------------------------------+
2238+ | Copyright (c) 1997-2003 The PHP Group |
2239+ +----------------------------------------------------------------------+
2240+ | This source file is subject to version 2.02 of the PHP license, |
2241+ | that is bundled with this package in the file LICENSE, and is |
2242+ | available at through the world-wide-web at |
2243+ | http://www.php.net/license/2_02.txt. |
2244+ | If you did not receive a copy of the PHP license and are unable to |
2245+ | obtain it through the world-wide-web, please send a note to |
2246+ | license@php.net so we can mail you a copy immediately. |
2247+ +----------------------------------------------------------------------+
2248+ | Author: |
2249+ +----------------------------------------------------------------------+
2250+
2251+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2252+*/
2253+
2254+#ifdef HAVE_CONFIG_H
2255+#include "config.h"
2256+#endif
2257+
2258+#include "php.h"
2259+#include "php_ini.h"
2260+#include "ext/standard/info.h"
2261+#include "php_varfilter.h"
2262+#include "hardened_php.h"
2263+
2264+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2265+
2266+/* True global resources - no need for thread safety here */
2267+static int le_varfilter;
2268+
2269+/* {{{ varfilter_module_entry
2270+ */
2271+zend_module_entry varfilter_module_entry = {
2272+#if ZEND_MODULE_API_NO >= 20010901
2273+ STANDARD_MODULE_HEADER,
2274+#endif
2275+ "varfilter",
2276+ NULL,
2277+ PHP_MINIT(varfilter),
2278+ PHP_MSHUTDOWN(varfilter),
2279+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2280+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2281+ PHP_MINFO(varfilter),
2282+#if ZEND_MODULE_API_NO >= 20010901
2283+ "0.2.0", /* Replace with version number for your extension */
2284+#endif
2285+ STANDARD_MODULE_PROPERTIES
2286+};
2287+/* }}} */
2288+
2289+#ifdef COMPILE_DL_VARFILTER
2290+ZEND_GET_MODULE(varfilter)
2291+#endif
2292+
2293+/* {{{ PHP_INI
2294+ */
2295+PHP_INI_BEGIN()
2296+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_SYSTEM, OnUpdateInt, max_request_variables, zend_varfilter_globals, varfilter_globals)
2297+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_SYSTEM, OnUpdateInt, max_varname_length, zend_varfilter_globals, varfilter_globals)
2298+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "10000", PHP_INI_SYSTEM, OnUpdateInt, max_value_length, zend_varfilter_globals, varfilter_globals)
2299+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_SYSTEM, OnUpdateInt, max_array_depth, zend_varfilter_globals, varfilter_globals)
2300+PHP_INI_END()
2301+/* }}} */
2302+
2303+/* {{{ php_varfilter_init_globals
2304+ */
2305+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2306+{
2307+ varfilter_globals->max_request_variables = 200;
2308+ varfilter_globals->cur_request_variables = 0;
2309+ varfilter_globals->max_varname_length = 64;
2310+ varfilter_globals->max_value_length = 10000;
2311+ varfilter_globals->max_array_depth = 100;
2312+}
2313+/* }}} */
2314+
2315+/* {{{ PHP_MINIT_FUNCTION
2316+ */
2317+PHP_MINIT_FUNCTION(varfilter)
2318+{
2319+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2320+ REGISTER_INI_ENTRIES();
2321+
2322+ sapi_register_input_filter(varfilter_input_filter);
2323+ return SUCCESS;
2324+}
2325+/* }}} */
2326+
2327+/* {{{ PHP_MSHUTDOWN_FUNCTION
2328+ */
2329+PHP_MSHUTDOWN_FUNCTION(varfilter)
2330+{
2331+ UNREGISTER_INI_ENTRIES();
2332+
2333+ return SUCCESS;
2334+}
2335+/* }}} */
2336+
2337+/* Remove if there's nothing to do at request start */
2338+/* {{{ PHP_RINIT_FUNCTION
2339+ */
2340+PHP_RINIT_FUNCTION(varfilter)
2341+{
2342+ VARFILTER_G(cur_request_variables) = 0;
2343+
2344+ return SUCCESS;
2345+}
2346+/* }}} */
2347+
2348+/* Remove if there's nothing to do at request end */
2349+/* {{{ PHP_RSHUTDOWN_FUNCTION
2350+ */
2351+PHP_RSHUTDOWN_FUNCTION(varfilter)
2352+{
2353+ return SUCCESS;
2354+}
2355+/* }}} */
2356+
2357+/* {{{ PHP_MINFO_FUNCTION
2358+ */
2359+PHP_MINFO_FUNCTION(varfilter)
2360+{
2361+ php_info_print_table_start();
2362+ php_info_print_table_header(2, "Hardened-PHP's variable filter support", "enabled");
2363+ php_info_print_table_end();
2364+
2365+ DISPLAY_INI_ENTRIES();
2366+}
2367+/* }}} */
2368+
2369+/* {{{ SAPI_INPUT_FILTER_FUNC
2370+ */
2371+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
2372+{
2373+ char *index;
2374+ unsigned int var_len, depth = 0;
2375+
2376+ /* Drop this variable if the limit is reached */
2377+ if (VARFILTER_G(max_request_variables) == VARFILTER_G(cur_request_variables)) {
2378+ php_security_log("tried to register too many variables");
2379+ return 0;
2380+ }
2381+
2382+ /* Drop this variable if it exceeds the value length limit */
2383+ if (VARFILTER_G(max_value_length) < val_len) {
2384+ php_security_log("tried to register a variable with a too long value");
2385+ return 0;
2386+ }
2387+
2388+ /* Find length of variable name */
2389+ index = strchr(var, '[');
2390+ var_len = index ? index-var : strlen(var);
2391+
2392+ /* Drop this variable if it exceeds the varname length limit */
2393+ if (VARFILTER_G(max_varname_length) < var_len) {
2394+ php_security_log("tried to register a variable with a too long variable name");
2395+ return 0;
2396+ }
2397+
2398+ /* Find out array depth */
2399+ while (index) {
2400+ depth++;
2401+ index = strchr(index+1, '[');
2402+ }
2403+
2404+ /* Drop this variable if it exceeds the array depth limit */
2405+ if (VARFILTER_G(max_array_depth) < depth) {
2406+ php_security_log("tried to register a too deep array variable");
2407+ return 0;
2408+ }
2409+
2410+ /* Okay let PHP register this variable */
2411+ VARFILTER_G(cur_request_variables)++;
2412+
2413+ if (new_val_len) {
2414+ *new_val_len = val_len;
2415+ }
2416+
2417+ return 1;
2418+}
2419+/* }}} */
2420+
2421+
2422+/*
2423+ * Local variables:
2424+ * tab-width: 4
2425+ * c-basic-offset: 4
2426+ * End:
2427+ * vim600: noet sw=4 ts=4 fdm=marker
2428+ * vim<600: noet sw=4 ts=4
2429+ */
2430diff -Nur php-4.3.11/main/SAPI.c hardened-php-4.3.11-0.2.7/main/SAPI.c
2431--- php-4.3.11/main/SAPI.c 2005-02-22 15:46:24.000000000 +0100
2432+++ hardened-php-4.3.11-0.2.7/main/SAPI.c 2005-04-07 02:08:26.000000000 +0200
2433@@ -831,6 +831,12 @@
2434 return SUCCESS;
2435 }
2436
2437+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
2438+{
2439+ sapi_module.input_filter = input_filter;
2440+ return SUCCESS;
2441+}
2442+
2443
2444 SAPI_API int sapi_flush(TSRMLS_D)
2445 {
2446diff -Nur php-4.3.11/main/SAPI.h hardened-php-4.3.11-0.2.7/main/SAPI.h
2447--- php-4.3.11/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
2448+++ hardened-php-4.3.11-0.2.7/main/SAPI.h 2005-04-07 02:08:26.000000000 +0200
2449@@ -101,9 +101,14 @@
2450 char *current_user;
2451 int current_user_length;
2452
2453- /* this is necessary for CLI module */
2454- int argc;
2455- char **argv;
2456+ /* this is necessary for CLI module */
2457+ int argc;
2458+ char **argv;
2459+
2460+#if HARDENED_PHP
2461+ /* this is necessary for IP logging */
2462+ char ip_address[64];
2463+#endif
2464 } sapi_request_info;
2465
2466
2467@@ -177,6 +182,7 @@
2468 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
2469 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
2470 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
2471+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC));
2472
2473 SAPI_API int sapi_flush(TSRMLS_D);
2474 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
2475@@ -238,8 +244,11 @@
2476 int (*get_target_uid)(uid_t * TSRMLS_DC);
2477 int (*get_target_gid)(gid_t * TSRMLS_DC);
2478
2479+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
2480+
2481 void (*ini_defaults)(HashTable *configuration_hash);
2482 int phpinfo_as_text;
2483+
2484 };
2485
2486
2487@@ -262,16 +271,23 @@
2488
2489 #define SAPI_DEFAULT_MIMETYPE "text/html"
2490 #define SAPI_DEFAULT_CHARSET ""
2491+
2492+#if HARDENED_PHP
2493+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: Hardened-PHP/" PHP_VERSION
2494+#else
2495 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
2496+#endif
2497
2498 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
2499 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
2500
2501 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
2502+#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC)
2503
2504 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
2505 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
2506 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
2507+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
2508
2509 #define STANDARD_SAPI_MODULE_PROPERTIES
2510
2511diff -Nur php-4.3.11/main/fopen_wrappers.c hardened-php-4.3.11-0.2.7/main/fopen_wrappers.c
2512--- php-4.3.11/main/fopen_wrappers.c 2005-02-03 00:44:07.000000000 +0100
2513+++ hardened-php-4.3.11-0.2.7/main/fopen_wrappers.c 2005-04-07 02:07:07.000000000 +0200
2514@@ -166,6 +166,21 @@
2515 char *pathbuf;
2516 char *ptr;
2517 char *end;
2518+ char path_copy[MAXPATHLEN];
2519+ int path_len;
2520+
2521+ /* Special case path ends with a trailing slash */
2522+ path_len = strlen(path);
2523+ if (path_len >= MAXPATHLEN) {
2524+ errno = EPERM; /* we deny permission to open it */
2525+ return -1;
2526+ }
2527+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
2528+ memcpy(path_copy, path, path_len+1);
2529+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
2530+ path_copy[path_len] = '\0';
2531+ path = (const char *)&path_copy;
2532+ }
2533
2534 pathbuf = estrdup(PG(open_basedir));
2535
2536diff -Nur php-4.3.11/main/hardened_globals.h hardened-php-4.3.11-0.2.7/main/hardened_globals.h
2537--- php-4.3.11/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
2538+++ hardened-php-4.3.11-0.2.7/main/hardened_globals.h 2005-04-07 02:08:26.000000000 +0200
2539@@ -0,0 +1,54 @@
2540+/*
2541+ +----------------------------------------------------------------------+
2542+ | Hardened-PHP |
2543+ +----------------------------------------------------------------------+
2544+ | Copyright (c) 2004 Stefan Esser |
2545+ +----------------------------------------------------------------------+
2546+ | This source file is subject to version 2.02 of the PHP license, |
2547+ | that is bundled with this package in the file LICENSE, and is |
2548+ | available at through the world-wide-web at |
2549+ | http://www.php.net/license/2_02.txt. |
2550+ | If you did not receive a copy of the PHP license and are unable to |
2551+ | obtain it through the world-wide-web, please send a note to |
2552+ | license@php.net so we can mail you a copy immediately. |
2553+ +----------------------------------------------------------------------+
2554+ | Author: Stefan Esser <sesser@php.net> |
2555+ +----------------------------------------------------------------------+
2556+ */
2557+
2558+#ifndef HARDENED_GLOBALS_H
2559+#define HARDENED_GLOBALS_H
2560+
2561+typedef struct _hardened_globals hardened_globals_struct;
2562+
2563+#ifdef ZTS
2564+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
2565+extern int hardened_globals_id;
2566+#else
2567+# define HG(v) (hardened_globals.v)
2568+extern struct _hardened_globals hardened_globals;
2569+#endif
2570+
2571+
2572+struct _hardened_globals {
2573+#if HARDENED_PHP_MM_PROTECT
2574+ unsigned int canary_1;
2575+ unsigned int canary_2;
2576+#endif
2577+#if HARDENED_PHP_LL_PROTECT
2578+ unsigned int canary_3;
2579+ unsigned int canary_4;
2580+ unsigned int ll_canary_inited;
2581+#endif
2582+ unsigned int dummy;
2583+};
2584+
2585+
2586+#endif /* HARDENED_GLOBALS_H */
2587+
2588+/*
2589+ * Local variables:
2590+ * tab-width: 4
2591+ * c-basic-offset: 4
2592+ * End:
2593+ */
2594diff -Nur php-4.3.11/main/hardened_php.c hardened-php-4.3.11-0.2.7/main/hardened_php.c
2595--- php-4.3.11/main/hardened_php.c 1970-01-01 01:00:00.000000000 +0100
2596+++ hardened-php-4.3.11-0.2.7/main/hardened_php.c 2005-04-07 02:08:26.000000000 +0200
2597@@ -0,0 +1,205 @@
2598+/*
2599+ +----------------------------------------------------------------------+
2600+ | Hardened-PHP |
2601+ +----------------------------------------------------------------------+
2602+ | Copyright (c) 2004 Stefan Esser |
2603+ +----------------------------------------------------------------------+
2604+ | This source file is subject to version 2.02 of the PHP license, |
2605+ | that is bundled with this package in the file LICENSE, and is |
2606+ | available at through the world-wide-web at |
2607+ | http://www.php.net/license/2_02.txt. |
2608+ | If you did not receive a copy of the PHP license and are unable to |
2609+ | obtain it through the world-wide-web, please send a note to |
2610+ | license@php.net so we can mail you a copy immediately. |
2611+ +----------------------------------------------------------------------+
2612+ | Author: Stefan Esser <sesser@php.net> |
2613+ +----------------------------------------------------------------------+
2614+ */
2615+/* $Id: hardened_php.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
2616+
2617+#include "php.h"
2618+
2619+#include <stdio.h>
2620+#include <stdlib.h>
2621+
2622+#if HAVE_UNISTD_H
2623+#include <unistd.h>
2624+#endif
2625+#include "SAPI.h"
2626+#include "php_globals.h"
2627+
2628+#if HARDENED_PHP
2629+
2630+#ifdef HAVE_SYS_SOCKET_H
2631+#include <sys/socket.h>
2632+#endif
2633+
2634+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
2635+#undef AF_UNIX
2636+#endif
2637+
2638+#if defined(AF_UNIX)
2639+#include <sys/un.h>
2640+#endif
2641+
2642+#define SYSLOG_PATH "/dev/log"
2643+
2644+#include "snprintf.h"
2645+
2646+#ifdef ZTS
2647+#include "hardened_globals.h"
2648+int hardened_globals_id;
2649+#else
2650+struct _hardened_globals hardened_globals;
2651+#endif
2652+
2653+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
2654+{
2655+ memset(hardened_globals, 0, sizeof(*hardened_globals));
2656+}
2657+
2658+PHPAPI void hardened_startup()
2659+{
2660+#ifdef ZTS
2661+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
2662+#else
2663+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
2664+#endif
2665+}
2666+
2667+PHPAPI void php_security_log(char *str)
2668+{
2669+#if defined(AF_UNIX)
2670+ int s, r;
2671+ struct sockaddr_un saun;
2672+ char buf[1024];
2673+ char *ip_address;
2674+ char *fname;
2675+ TSRMLS_FETCH();
2676+
2677+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
2678+ if (ip_address == NULL) {
2679+ ip_address = "REMOTE_ADDR not set";
2680+ }
2681+
2682+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
2683+
2684+ ap_php_snprintf(buf, 1024, "php security-alert: %s (attacker '%s', file '%s')\n", str, ip_address, fname);
2685+
2686+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
2687+ if (s == -1) {
2688+ return;
2689+ }
2690+
2691+ memset(&saun, 0, sizeof(saun));
2692+ saun.sun_family = AF_UNIX;
2693+ strcpy(saun.sun_path, SYSLOG_PATH);
2694+ /*saun.sun_len = sizeof(saun);*/
2695+
2696+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2697+ if (r) {
2698+ close(s);
2699+ s = socket(AF_UNIX, SOCK_STREAM, 0);
2700+ if (s == -1) {
2701+ return;
2702+ }
2703+
2704+ memset(&saun, 0, sizeof(saun));
2705+ saun.sun_family = AF_UNIX;
2706+ strcpy(saun.sun_path, SYSLOG_PATH);
2707+ /*saun.sun_len = sizeof(saun);*/
2708+
2709+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2710+ if (r) {
2711+ close(s);
2712+ return;
2713+ }
2714+ }
2715+ send(s, buf, strlen(buf), 0);
2716+
2717+ close(s);
2718+#endif
2719+}
2720+#endif
2721+
2722+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2723+
2724+/* will be replaced later with more compatible method */
2725+PHPAPI unsigned int php_canary()
2726+{
2727+ time_t t;
2728+ unsigned int canary;
2729+ int fd;
2730+
2731+ fd = open("/dev/urandom", 0);
2732+ if (fd != -1) {
2733+ int r = read(fd, &canary, sizeof(canary));
2734+ close(fd);
2735+ if (r == sizeof(canary)) {
2736+ return (canary);
2737+ }
2738+ }
2739+ /* not good but we never want to do this */
2740+ time(&t);
2741+ canary = *(unsigned int *)&t + getpid() << 16;
2742+ return (canary);
2743+}
2744+#endif
2745+
2746+#if HARDENED_PHP_INC_PROTECT
2747+
2748+PHPAPI int php_is_valid_include(zval *z)
2749+{
2750+ char *filename;
2751+ int len;
2752+ TSRMLS_FETCH();
2753+
2754+ /* must be of type string */
2755+ if (z->type != IS_STRING || z->value.str.val == NULL) {
2756+ return (0);
2757+ }
2758+
2759+ /* short cut */
2760+ filename = z->value.str.val;
2761+ len = z->value.str.len;
2762+
2763+ /* 1. must be shorter than MAXPATHLEN */
2764+ if (len > MAXPATHLEN) {
2765+ php_security_log("Include filename longer than MAXPATHLEN chars");
2766+ return (0);
2767+ }
2768+
2769+ /* 2. must not be cutted */
2770+ if (len != strlen(filename)) {
2771+ php_security_log("Include filename has a \\0 cut");
2772+ return (0);
2773+ }
2774+
2775+ /* 3. must not be a URL */
2776+ if (strstr(filename, "://")) {
2777+ php_security_log("Include filename is an URL");
2778+ return (0);
2779+ }
2780+
2781+ /* 4. must not be an uploaded file */
2782+ if (SG(rfc1867_uploaded_files)) {
2783+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
2784+ php_security_log("Include filename is an uploaded file");
2785+ return (0);
2786+ }
2787+ }
2788+
2789+ /* passed all tests */
2790+ return (1);
2791+}
2792+
2793+#endif
2794+
2795+/*
2796+ * Local variables:
2797+ * tab-width: 4
2798+ * c-basic-offset: 4
2799+ * End:
2800+ * vim600: sw=4 ts=4 fdm=marker
2801+ * vim<600: sw=4 ts=4
2802+ */
2803diff -Nur php-4.3.11/main/hardened_php.h hardened-php-4.3.11-0.2.7/main/hardened_php.h
2804--- php-4.3.11/main/hardened_php.h 1970-01-01 01:00:00.000000000 +0100
2805+++ hardened-php-4.3.11-0.2.7/main/hardened_php.h 2005-04-07 02:08:45.000000000 +0200
2806@@ -0,0 +1,45 @@
2807+/*
2808+ +----------------------------------------------------------------------+
2809+ | Hardened-PHP |
2810+ +----------------------------------------------------------------------+
2811+ | Copyright (c) 2004 Stefan Esser |
2812+ +----------------------------------------------------------------------+
2813+ | This source file is subject to version 2.02 of the PHP license, |
2814+ | that is bundled with this package in the file LICENSE, and is |
2815+ | available at through the world-wide-web at |
2816+ | http://www.php.net/license/2_02.txt. |
2817+ | If you did not receive a copy of the PHP license and are unable to |
2818+ | obtain it through the world-wide-web, please send a note to |
2819+ | license@php.net so we can mail you a copy immediately. |
2820+ +----------------------------------------------------------------------+
2821+ | Author: Stefan Esser <sesser@php.net> |
2822+ +----------------------------------------------------------------------+
2823+ */
2824+
2825+#ifndef HARDENED_PHP_H
2826+#define HARDENED_PHP_H
2827+
2828+#include "zend.h"
2829+
2830+#if HARDENED_PHP
2831+PHPAPI void php_security_log(char *str);
2832+PHPAPI void hardened_startup();
2833+#define HARDENED_PHP_VERSION "0.2.7"
2834+#endif
2835+
2836+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2837+PHPAPI unsigned int php_canary();
2838+#endif
2839+
2840+#if HARDENED_PHP_INC_PROTECT
2841+PHPAPI int php_is_valid_include(zval *z);
2842+#endif
2843+
2844+#endif /* HARDENED_PHP_H */
2845+
2846+/*
2847+ * Local variables:
2848+ * tab-width: 4
2849+ * c-basic-offset: 4
2850+ * End:
2851+ */
2852diff -Nur php-4.3.11/main/hardened_php.m4 hardened-php-4.3.11-0.2.7/main/hardened_php.m4
2853--- php-4.3.11/main/hardened_php.m4 1970-01-01 01:00:00.000000000 +0100
2854+++ hardened-php-4.3.11-0.2.7/main/hardened_php.m4 2005-04-07 02:08:26.000000000 +0200
2855@@ -0,0 +1,95 @@
2856+dnl
2857+dnl $Id: hardened_php.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
2858+dnl
2859+dnl This file contains Hardened-PHP specific autoconf functions.
2860+dnl
2861+
2862+AC_ARG_ENABLE(hardened-php-mm-protect,
2863+[ --disable-hardened-php-mm-protect Disable the Memory Manager protection.],[
2864+ DO_HARDENED_PHP_MM_PROTECT=$enableval
2865+],[
2866+ DO_HARDENED_PHP_MM_PROTECT=yes
2867+])
2868+
2869+AC_ARG_ENABLE(hardened-php-ll-protect,
2870+[ --disable-hardened-php-ll-protect Disable the Linked List protection.],[
2871+ DO_HARDENED_PHP_LL_PROTECT=$enableval
2872+],[
2873+ DO_HARDENED_PHP_LL_PROTECT=yes
2874+])
2875+
2876+AC_ARG_ENABLE(hardened-php-inc-protect,
2877+[ --disable-hardened-php-inc-protect Disable include/require protection.],[
2878+ DO_HARDENED_PHP_INC_PROTECT=$enableval
2879+],[
2880+ DO_HARDENED_PHP_INC_PROTECT=yes
2881+])
2882+
2883+AC_ARG_ENABLE(hardened-php-fmt-protect,
2884+[ --disable-hardened-php-fmt-protect Disable format string protection.],[
2885+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
2886+],[
2887+ DO_HARDENED_PHP_FMT_PROTECT=yes
2888+])
2889+
2890+AC_ARG_ENABLE(hardened-php-hash-protect,
2891+[ --disable-hardened-php-hash-protect Disable HashTable destructor protection.],[
2892+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
2893+],[
2894+ DO_HARDENED_PHP_HASH_PROTECT=yes
2895+])
2896+
2897+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
2898+AC_MSG_RESULT($DO_HARDENED_PHP_MM_PROTECT)
2899+
2900+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
2901+AC_MSG_RESULT($DO_HARDENED_PHP_LL_PROTECT)
2902+
2903+AC_MSG_CHECKING(whether to protect include/require statements)
2904+AC_MSG_RESULT($DO_HARDENED_PHP_INC_PROTECT)
2905+
2906+AC_MSG_CHECKING(whether to protect PHP Format String functions)
2907+AC_MSG_RESULT($DO_HARDENED_PHP_FMT_PROTECT)
2908+
2909+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
2910+AC_MSG_RESULT($DO_HARDENED_PHP_HASH_PROTECT)
2911+
2912+
2913+AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2914+
2915+
2916+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
2917+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2918+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 1, [Memory Manager Protection])
2919+else
2920+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 0, [Memory Manager Protection])
2921+fi
2922+
2923+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
2924+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2925+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 1, [Linked List Protection])
2926+else
2927+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 0, [Linked List Protection])
2928+fi
2929+
2930+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
2931+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2932+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 1, [Include/Require Protection])
2933+else
2934+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 0, [Include/Require Protection])
2935+fi
2936+
2937+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
2938+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2939+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 1, [Fmt String Protection])
2940+else
2941+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 0, [Fmt String Protection])
2942+fi
2943+
2944+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
2945+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2946+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 1, [HashTable DTOR Protection])
2947+else
2948+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 0, [HashTable DTOR Protection])
2949+fi
2950+
2951diff -Nur php-4.3.11/main/main.c hardened-php-4.3.11-0.2.7/main/main.c
2952--- php-4.3.11/main/main.c 2005-03-08 22:45:51.000000000 +0100
2953+++ hardened-php-4.3.11-0.2.7/main/main.c 2005-04-07 02:08:26.000000000 +0200
2954@@ -100,6 +100,10 @@
2955 PHPAPI int core_globals_id;
2956 #endif
2957
2958+#if HARDENED_PHP
2959+#include "hardened_globals.h"
2960+#endif
2961+
2962 #define ERROR_BUF_LEN 1024
2963
2964 typedef struct {
2965@@ -150,10 +154,33 @@
2966 */
2967 static PHP_INI_MH(OnChangeMemoryLimit)
2968 {
2969+#if HARDENED_PHP
2970+ long orig_memory_limit;
2971+
2972+ if (entry->modified) {
2973+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
2974+ } else {
2975+ orig_memory_limit = 1<<30;
2976+ }
2977+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
2978+ orig_memory_limit = 1<<30;
2979+ }
2980+#endif
2981 if (new_value) {
2982 PG(memory_limit) = zend_atoi(new_value, new_value_length);
2983+#if HARDENED_PHP
2984+ if (PG(memory_limit) > orig_memory_limit) {
2985+ PG(memory_limit) = orig_memory_limit;
2986+ php_security_log("script tried to increase memory_limit above allowed value");
2987+ return FAILURE;
2988+ }
2989+#endif
2990 } else {
2991+#if HARDENED_PHP
2992+ PG(memory_limit) = orig_memory_limit;
2993+#else
2994 PG(memory_limit) = 1<<30; /* effectively, no limit */
2995+#endif
2996 }
2997 return zend_set_memory_limit(PG(memory_limit));
2998 }
2999@@ -1092,6 +1119,10 @@
3000 tsrm_ls = ts_resource(0);
3001 #endif
3002
3003+#if HARDENED_PHP
3004+ hardened_startup();
3005+#endif
3006+
3007 sapi_initialize_empty_request(TSRMLS_C);
3008 sapi_activate(TSRMLS_C);
3009
3010@@ -1104,6 +1135,12 @@
3011 php_output_startup();
3012 php_output_activate(TSRMLS_C);
3013
3014+#if HARDENED_PHP_INC_PROTECT
3015+ zuf.is_valid_include = php_is_valid_include;
3016+#endif
3017+#if HARDENED_PHP
3018+ zuf.security_log_function = php_security_log;
3019+#endif
3020 zuf.error_function = php_error_cb;
3021 zuf.printf_function = php_printf;
3022 zuf.write_function = php_body_write_wrapper;
3023@@ -1205,6 +1242,10 @@
3024 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
3025 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);
3026 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
3027+#if HARDENED_PHP
3028+ REGISTER_MAIN_LONG_CONSTANT("HARDENED_PHP", 1, CONST_PERSISTENT | CONST_CS);
3029+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENED_PHP_VERSION", HARDENED_PHP_VERSION, sizeof(HARDENED_PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
3030+#endif
3031 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
3032 php_output_register_constants(TSRMLS_C);
3033 php_rfc1867_register_constants(TSRMLS_C);
3034diff -Nur php-4.3.11/main/php.h hardened-php-4.3.11-0.2.7/main/php.h
3035--- php-4.3.11/main/php.h 2005-03-08 22:45:51.000000000 +0100
3036+++ hardened-php-4.3.11-0.2.7/main/php.h 2005-04-07 02:08:26.000000000 +0200
3037@@ -35,11 +35,19 @@
3038 #include "zend_qsort.h"
3039 #include "php_compat.h"
3040
3041+
3042 #include "zend_API.h"
3043
3044 #undef sprintf
3045 #define sprintf php_sprintf
3046
3047+#if HARDENED_PHP
3048+#if HAVE_REALPATH
3049+#undef realpath
3050+#define realpath php_realpath
3051+#endif
3052+#endif
3053+
3054 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
3055 #undef PHP_DEBUG
3056 #define PHP_DEBUG ZEND_DEBUG
3057@@ -436,6 +444,10 @@
3058 #endif
3059 #endif /* !XtOffsetOf */
3060
3061+#if HARDENED_PHP
3062+#include "hardened_php.h"
3063+#endif
3064+
3065 #endif
3066
3067 /*
3068diff -Nur php-4.3.11/main/php_config.h.in hardened-php-4.3.11-0.2.7/main/php_config.h.in
3069--- php-4.3.11/main/php_config.h.in 2005-03-30 16:35:47.000000000 +0200
3070+++ hardened-php-4.3.11-0.2.7/main/php_config.h.in 2005-04-07 02:08:26.000000000 +0200
3071@@ -839,6 +839,39 @@
3072 /* Enabling BIND8 compatibility for Panther */
3073 #undef BIND_8_COMPAT
3074
3075+/* Hardened-PHP */
3076+#undef HARDENED_PHP
3077+
3078+/* Memory Manager Protection */
3079+#undef HARDENED_PHP_MM_PROTECT
3080+
3081+/* Memory Manager Protection */
3082+#undef HARDENED_PHP_MM_PROTECT
3083+
3084+/* Linked List Protection */
3085+#undef HARDENED_PHP_LL_PROTECT
3086+
3087+/* Linked List Protection */
3088+#undef HARDENED_PHP_LL_PROTECT
3089+
3090+/* Include/Require Protection */
3091+#undef HARDENED_PHP_INC_PROTECT
3092+
3093+/* Include/Require Protection */
3094+#undef HARDENED_PHP_INC_PROTECT
3095+
3096+/* Fmt String Protection */
3097+#undef HARDENED_PHP_FMT_PROTECT
3098+
3099+/* Fmt String Protection */
3100+#undef HARDENED_PHP_FMT_PROTECT
3101+
3102+/* HashTable DTOR Protection */
3103+#undef HARDENED_PHP_HASH_PROTECT
3104+
3105+/* HashTable DTOR Protection */
3106+#undef HARDENED_PHP_HASH_PROTECT
3107+
3108 /* Whether you have AOLserver */
3109 #undef HAVE_AOLSERVER
3110
3111@@ -1122,6 +1155,12 @@
3112 /* Define if you have the getaddrinfo function */
3113 #undef HAVE_GETADDRINFO
3114
3115+/* Whether realpath is broken */
3116+#undef PHP_BROKEN_REALPATH
3117+
3118+/* Whether realpath is broken */
3119+#undef PHP_BROKEN_REALPATH
3120+
3121 /* Whether system headers declare timezone */
3122 #undef HAVE_DECLARED_TIMEZONE
3123
3124diff -Nur php-4.3.11/main/php_content_types.c hardened-php-4.3.11-0.2.7/main/php_content_types.c
3125--- php-4.3.11/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
3126+++ hardened-php-4.3.11-0.2.7/main/php_content_types.c 2005-04-07 02:08:26.000000000 +0200
3127@@ -77,6 +77,7 @@
3128 sapi_register_post_entries(php_post_entries);
3129 sapi_register_default_post_reader(php_default_post_reader);
3130 sapi_register_treat_data(php_default_treat_data);
3131+ sapi_register_input_filter(php_default_input_filter);
3132 return SUCCESS;
3133 }
3134 /* }}} */
3135diff -Nur php-4.3.11/main/php_variables.c hardened-php-4.3.11-0.2.7/main/php_variables.c
3136--- php-4.3.11/main/php_variables.c 2004-10-18 17:08:46.000000000 +0200
3137+++ hardened-php-4.3.11-0.2.7/main/php_variables.c 2005-04-07 02:08:26.000000000 +0200
3138@@ -211,17 +211,28 @@
3139 while (var) {
3140 val = strchr(var, '=');
3141 if (val) { /* have a value */
3142- int val_len;
3143+ unsigned int val_len, new_val_len;
3144
3145 *val++ = '\0';
3146 php_url_decode(var, strlen(var));
3147 val_len = php_url_decode(val, strlen(val));
3148- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3149+ val = estrndup(val, val_len);
3150+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3151+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3152+ }
3153+ efree(val);
3154 }
3155 var = php_strtok_r(NULL, "&", &strtok_buf);
3156 }
3157 }
3158
3159+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
3160+{
3161+ /* TODO: check .ini setting here and apply user-defined input filter */
3162+ *new_val_len = val_len;
3163+ return 1;
3164+}
3165+
3166 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
3167 {
3168 char *res = NULL, *var, *val, *separator=NULL;
3169@@ -299,15 +310,26 @@
3170 while (var) {
3171 val = strchr(var, '=');
3172 if (val) { /* have a value */
3173- int val_len;
3174+ unsigned int val_len, new_val_len;
3175
3176 *val++ = '\0';
3177 php_url_decode(var, strlen(var));
3178 val_len = php_url_decode(val, strlen(val));
3179- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3180+ val = estrndup(val, val_len);
3181+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3182+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3183+ }
3184+ efree(val);
3185 } else {
3186+ unsigned int val_len, new_val_len;
3187+
3188 php_url_decode(var, strlen(var));
3189- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
3190+ val_len = 0;
3191+ val = estrndup("", 0);
3192+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3193+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3194+ }
3195+ efree(val);
3196 }
3197 var = php_strtok_r(NULL, separator, &strtok_buf);
3198 }
3199diff -Nur php-4.3.11/main/rfc1867.c hardened-php-4.3.11-0.2.7/main/rfc1867.c
3200--- php-4.3.11/main/rfc1867.c 2005-02-15 01:28:39.000000000 +0100
3201+++ hardened-php-4.3.11-0.2.7/main/rfc1867.c 2005-04-07 02:08:26.000000000 +0200
3202@@ -891,21 +891,24 @@
3203 if (!filename && param) {
3204
3205 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
3206+ unsigned int new_val_len; /* Dummy variable */
3207
3208 if (!value) {
3209 value = estrdup("");
3210 }
3211
3212+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
3213 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
3214- if (php_mb_encoding_translation(TSRMLS_C)) {
3215- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
3216- &num_vars, &num_vars_max TSRMLS_CC);
3217- } else {
3218- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3219- }
3220+ if (php_mb_encoding_translation(TSRMLS_C)) {
3221+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
3222+ &num_vars, &num_vars_max TSRMLS_CC);
3223+ } else {
3224+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3225+ }
3226 #else
3227- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3228+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3229 #endif
3230+ }
3231 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
3232 max_file_size = atol(value);
3233 }
3234diff -Nur php-4.3.11/main/snprintf.c hardened-php-4.3.11-0.2.7/main/snprintf.c
3235--- php-4.3.11/main/snprintf.c 2004-11-16 00:27:26.000000000 +0100
3236+++ hardened-php-4.3.11-0.2.7/main/snprintf.c 2005-04-07 02:08:26.000000000 +0200
3237@@ -850,7 +850,11 @@
3238
3239
3240 case 'n':
3241+#if HARDENED_PHP_FMT_PROTECT
3242+ php_security_log("'n' specifier within format string");
3243+#else
3244 *(va_arg(ap, int *)) = cc;
3245+#endif
3246 break;
3247
3248 /*
3249diff -Nur php-4.3.11/main/spprintf.c hardened-php-4.3.11-0.2.7/main/spprintf.c
3250--- php-4.3.11/main/spprintf.c 2003-09-29 03:09:36.000000000 +0200
3251+++ hardened-php-4.3.11-0.2.7/main/spprintf.c 2005-04-07 02:08:26.000000000 +0200
3252@@ -531,7 +531,11 @@
3253
3254
3255 case 'n':
3256+#if HARDENED_PHP_FMT_PROTECT
3257+ php_security_log("'n' specifier within format string");
3258+#else
3259 *(va_arg(ap, int *)) = cc;
3260+#endif
3261 break;
3262
3263 /*
3264diff -Nur php-4.3.11/php.ini-dist hardened-php-4.3.11-0.2.7/php.ini-dist
3265--- php-4.3.11/php.ini-dist 2005-02-14 09:26:10.000000000 +0100
3266+++ hardened-php-4.3.11-0.2.7/php.ini-dist 2005-04-07 02:08:26.000000000 +0200
3267@@ -1109,6 +1109,23 @@
3268 ;exif.decode_jis_motorola = JIS
3269 ;exif.decode_jis_intel = JIS
3270
3271+[varfilter]
3272+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3273+; Hardened-PHP's variable filter
3274+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3275+
3276+; Maximum number of input variables per request
3277+varfilter.max_request_variables = 200
3278+
3279+; Maximum characters in input variable names
3280+varfilter.max_varname_length = 64
3281+
3282+; Maximum length of input variable values
3283+varfilter.max_value_length = 10000
3284+
3285+; Maximum depth of input variable arrays
3286+varfilter.max_array_depth = 100
3287+
3288 ; Local Variables:
3289 ; tab-width: 4
3290 ; End:
3291diff -Nur php-4.3.11/php.ini-recommended hardened-php-4.3.11-0.2.7/php.ini-recommended
3292--- php-4.3.11/php.ini-recommended 2005-02-14 09:26:10.000000000 +0100
3293+++ hardened-php-4.3.11-0.2.7/php.ini-recommended 2005-04-07 02:08:26.000000000 +0200
3294@@ -1107,6 +1107,23 @@
3295 ;exif.decode_jis_motorola = JIS
3296 ;exif.decode_jis_intel = JIS
3297
3298+[varfilter]
3299+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3300+; Hardened-PHP's variable filter
3301+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3302+
3303+; Maximum number of input variables per request
3304+varfilter.max_request_variables = 200
3305+
3306+; Maximum characters in input variable names
3307+varfilter.max_varname_length = 64
3308+
3309+; Maximum length of input variable values
3310+varfilter.max_value_length = 10000
3311+
3312+; Maximum depth of input variable arrays
3313+varfilter.max_array_depth = 100
3314+
3315 ; Local Variables:
3316 ; tab-width: 4
3317 ; End:
3318diff -Nur php-4.3.11/sapi/apache/mod_php4.c hardened-php-4.3.11-0.2.7/sapi/apache/mod_php4.c
3319--- php-4.3.11/sapi/apache/mod_php4.c 2004-07-21 18:25:28.000000000 +0200
3320+++ hardened-php-4.3.11-0.2.7/sapi/apache/mod_php4.c 2005-04-07 02:08:26.000000000 +0200
3321@@ -446,7 +446,7 @@
3322 sapi_apache_get_fd,
3323 sapi_apache_force_http_10,
3324 sapi_apache_get_target_uid,
3325- sapi_apache_get_target_gid
3326+ sapi_apache_get_target_gid,
3327 };
3328 /* }}} */
3329
3330@@ -892,7 +892,11 @@
3331 {
3332 TSRMLS_FETCH();
3333 if (PG(expose_php)) {
3334+#if HARDENED_PHP
3335+ ap_add_version_component("Hardened-PHP/" PHP_VERSION);
3336+#else
3337 ap_add_version_component("PHP/" PHP_VERSION);
3338+#endif
3339 }
3340 }
3341 #endif
3342diff -Nur php-4.3.11/sapi/apache2filter/sapi_apache2.c hardened-php-4.3.11-0.2.7/sapi/apache2filter/sapi_apache2.c
3343--- php-4.3.11/sapi/apache2filter/sapi_apache2.c 2005-01-07 07:28:36.000000000 +0100
3344+++ hardened-php-4.3.11-0.2.7/sapi/apache2filter/sapi_apache2.c 2005-04-07 02:08:26.000000000 +0200
3345@@ -563,7 +563,11 @@
3346 {
3347 TSRMLS_FETCH();
3348 if (PG(expose_php)) {
3349+#if HARDENED_PHP
3350+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3351+#else
3352 ap_add_version_component(p, "PHP/" PHP_VERSION);
3353+#endif
3354 }
3355 }
3356
3357diff -Nur php-4.3.11/sapi/apache2handler/sapi_apache2.c hardened-php-4.3.11-0.2.7/sapi/apache2handler/sapi_apache2.c
3358--- php-4.3.11/sapi/apache2handler/sapi_apache2.c 2005-03-10 12:39:04.000000000 +0100
3359+++ hardened-php-4.3.11-0.2.7/sapi/apache2handler/sapi_apache2.c 2005-04-07 02:08:26.000000000 +0200
3360@@ -345,7 +345,11 @@
3361 {
3362 TSRMLS_FETCH();
3363 if (PG(expose_php)) {
3364+#if HARDENED_PHP
3365+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3366+#else
3367 ap_add_version_component(p, "PHP/" PHP_VERSION);
3368+#endif
3369 }
3370 }
3371
3372diff -Nur php-4.3.11/sapi/cgi/cgi_main.c hardened-php-4.3.11-0.2.7/sapi/cgi/cgi_main.c
3373--- php-4.3.11/sapi/cgi/cgi_main.c 2005-02-11 03:12:30.000000000 +0100
3374+++ hardened-php-4.3.11-0.2.7/sapi/cgi/cgi_main.c 2005-04-07 02:08:26.000000000 +0200
3375@@ -1435,11 +1435,19 @@
3376 SG(headers_sent) = 1;
3377 SG(request_info).no_headers = 1;
3378 }
3379+#if HARDENED_PHP
3380+#if ZEND_DEBUG
3381+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3382+#else
3383+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3384+#endif
3385+#else
3386 #if ZEND_DEBUG
3387 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());
3388 #else
3389 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());
3390 #endif
3391+#endif
3392 php_end_ob_buffers(1 TSRMLS_CC);
3393 exit(1);
3394 break;
3395diff -Nur php-4.3.11/sapi/cli/php_cli.c hardened-php-4.3.11-0.2.7/sapi/cli/php_cli.c
3396--- php-4.3.11/sapi/cli/php_cli.c 2005-03-22 16:09:36.000000000 +0100
3397+++ hardened-php-4.3.11-0.2.7/sapi/cli/php_cli.c 2005-04-07 02:08:26.000000000 +0200
3398@@ -652,11 +652,19 @@
3399 if (php_request_startup(TSRMLS_C)==FAILURE) {
3400 goto err;
3401 }
3402+#if HARDENED_PHP
3403+#if ZEND_DEBUG
3404+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3405+#else
3406+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3407+#endif
3408+#else
3409 #if ZEND_DEBUG
3410 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());
3411 #else
3412 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());
3413 #endif
3414+#endif
3415 php_end_ob_buffers(1 TSRMLS_CC);
3416 exit_status=1;
3417 goto out;
diff --git a/0.2.7/hardened-php-5.0.4-0.2.7.patch b/0.2.7/hardened-php-5.0.4-0.2.7.patch
new file mode 100644
index 0000000..2b1372a
--- /dev/null
+++ b/0.2.7/hardened-php-5.0.4-0.2.7.patch
@@ -0,0 +1,3100 @@
1diff -Nur php-5.0.4/TSRM/TSRM.h hardened-php-5.0.4-0.2.7/TSRM/TSRM.h
2--- php-5.0.4/TSRM/TSRM.h 2005-03-11 12:12:07.000000000 +0100
3+++ hardened-php-5.0.4-0.2.7/TSRM/TSRM.h 2005-04-07 02:04:38.000000000 +0200
4@@ -33,6 +33,13 @@
5 # define TSRM_API
6 #endif
7
8+#if HARDENED_PHP
9+# if HAVE_REALPATH
10+# undef realpath
11+# define realpath php_realpath
12+# endif
13+#endif
14+
15 /* Only compile multi-threading functions if we're in ZTS mode */
16 #ifdef ZTS
17
18@@ -88,6 +95,7 @@
19
20 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
21
22+
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26diff -Nur php-5.0.4/TSRM/tsrm_virtual_cwd.c hardened-php-5.0.4-0.2.7/TSRM/tsrm_virtual_cwd.c
27--- php-5.0.4/TSRM/tsrm_virtual_cwd.c 2005-03-11 12:09:42.000000000 +0100
28+++ hardened-php-5.0.4-0.2.7/TSRM/tsrm_virtual_cwd.c 2005-04-07 02:04:38.000000000 +0200
29@@ -197,6 +197,165 @@
30 return p;
31 }
32
33+#if HARDENED_PHP
34+CWD_API char *php_realpath(const char *path, char *resolved)
35+{
36+ struct stat sb;
37+ char *p, *q, *s;
38+ size_t left_len, resolved_len;
39+ unsigned symlinks;
40+ int serrno, slen;
41+ int is_dir = 1;
42+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
43+
44+ serrno = errno;
45+ symlinks = 0;
46+ if (path[0] == '/') {
47+ resolved[0] = '/';
48+ resolved[1] = '\0';
49+ if (path[1] == '\0')
50+ return (resolved);
51+ resolved_len = 1;
52+ left_len = strlcpy(left, path + 1, sizeof(left));
53+ } else {
54+ if (getcwd(resolved, PATH_MAX) == NULL) {
55+ strlcpy(resolved, ".", PATH_MAX);
56+ return (NULL);
57+ }
58+ resolved_len = strlen(resolved);
59+ left_len = strlcpy(left, path, sizeof(left));
60+ }
61+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
62+ errno = ENAMETOOLONG;
63+ return (NULL);
64+ }
65+
66+ /*
67+ * Iterate over path components in `left'.
68+ */
69+ while (left_len != 0) {
70+ /*
71+ * Extract the next path component and adjust `left'
72+ * and its length.
73+ */
74+ p = strchr(left, '/');
75+ s = p ? p : left + left_len;
76+ if (s - left >= sizeof(next_token)) {
77+ errno = ENAMETOOLONG;
78+ return (NULL);
79+ }
80+ memcpy(next_token, left, s - left);
81+ next_token[s - left] = '\0';
82+ left_len -= s - left;
83+ if (p != NULL)
84+ memmove(left, s + 1, left_len + 1);
85+ if (resolved[resolved_len - 1] != '/') {
86+ if (resolved_len + 1 >= PATH_MAX) {
87+ errno = ENAMETOOLONG;
88+ return (NULL);
89+ }
90+ resolved[resolved_len++] = '/';
91+ resolved[resolved_len] = '\0';
92+ }
93+ if (next_token[0] == '\0')
94+ continue;
95+ else if (strcmp(next_token, ".") == 0)
96+ continue;
97+ else if (strcmp(next_token, "..") == 0) {
98+ /*
99+ * Strip the last path component except when we have
100+ * single "/"
101+ */
102+ if (!is_dir) {
103+ errno = ENOENT;
104+ return (NULL);
105+ }
106+ if (resolved_len > 1) {
107+ resolved[resolved_len - 1] = '\0';
108+ q = strrchr(resolved, '/');
109+ *q = '\0';
110+ resolved_len = q - resolved;
111+ }
112+ continue;
113+ }
114+
115+ /*
116+ * Append the next path component and lstat() it. If
117+ * lstat() fails we still can return successfully if
118+ * there are no more path components left.
119+ */
120+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
121+ if (resolved_len >= PATH_MAX) {
122+ errno = ENAMETOOLONG;
123+ return (NULL);
124+ }
125+ if (lstat(resolved, &sb) != 0) {
126+ if (errno == ENOENT && p == NULL) {
127+ errno = serrno;
128+ return (resolved);
129+ }
130+ return (NULL);
131+ }
132+ if (S_ISLNK(sb.st_mode)) {
133+ if (symlinks++ > MAXSYMLINKS) {
134+ errno = ELOOP;
135+ return (NULL);
136+ }
137+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
138+ if (slen < 0)
139+ return (NULL);
140+ symlink[slen] = '\0';
141+ if (symlink[0] == '/') {
142+ resolved[1] = 0;
143+ resolved_len = 1;
144+ } else if (resolved_len > 1) {
145+ /* Strip the last path component. */
146+ resolved[resolved_len - 1] = '\0';
147+ q = strrchr(resolved, '/');
148+ *q = '\0';
149+ resolved_len = q - resolved;
150+ }
151+
152+ /*
153+ * If there are any path components left, then
154+ * append them to symlink. The result is placed
155+ * in `left'.
156+ */
157+ if (p != NULL) {
158+ if (symlink[slen - 1] != '/') {
159+ if (slen + 1 >= sizeof(symlink)) {
160+ errno = ENAMETOOLONG;
161+ return (NULL);
162+ }
163+ symlink[slen] = '/';
164+ symlink[slen + 1] = 0;
165+ }
166+ left_len = strlcat(symlink, left, sizeof(left));
167+ if (left_len >= sizeof(left)) {
168+ errno = ENAMETOOLONG;
169+ return (NULL);
170+ }
171+ }
172+ left_len = strlcpy(left, symlink, sizeof(left));
173+ } else {
174+ if (S_ISDIR(sb.st_mode)) {
175+ is_dir = 1;
176+ } else {
177+ is_dir = 0;
178+ }
179+ }
180+ }
181+
182+ /*
183+ * Remove trailing slash except when the resolved pathname
184+ * is a single "/".
185+ */
186+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
187+ resolved[resolved_len - 1] = '\0';
188+ return (resolved);
189+}
190+#endif
191+
192 CWD_API void virtual_cwd_startup(void)
193 {
194 char cwd[MAXPATHLEN];
195@@ -321,8 +480,7 @@
196 path = resolved_path;
197 path_length = strlen(path);
198 } else {
199- /* disable for now
200- return 1; */
201+ return 1;
202 }
203 }
204 } else { /* Concat current directory with relative path and then run realpath() on it */
205@@ -348,9 +506,8 @@
206 path = resolved_path;
207 path_length = strlen(path);
208 } else {
209- /* disable for now
210 free(tmp);
211- return 1; */
212+ return 1;
213 }
214 }
215 free(tmp);
216diff -Nur php-5.0.4/TSRM/tsrm_virtual_cwd.h hardened-php-5.0.4-0.2.7/TSRM/tsrm_virtual_cwd.h
217--- php-5.0.4/TSRM/tsrm_virtual_cwd.h 2005-03-11 12:07:17.000000000 +0100
218+++ hardened-php-5.0.4-0.2.7/TSRM/tsrm_virtual_cwd.h 2005-04-07 02:04:38.000000000 +0200
219@@ -128,6 +128,22 @@
220
221 typedef int (*verify_path_func)(const cwd_state *);
222
223+#ifndef HAVE_STRLCPY
224+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
225+#undef strlcpy
226+#define strlcpy php_strlcpy
227+#endif
228+
229+#ifndef HAVE_STRLCAT
230+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
231+#undef strlcat
232+#define strlcat php_strlcat
233+#endif
234+
235+
236+#if HARDENED_PHP
237+CWD_API char *php_realpath(const char *path, char *resolved);
238+#endif
239 CWD_API void virtual_cwd_startup(void);
240 CWD_API void virtual_cwd_shutdown(void);
241 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
242diff -Nur php-5.0.4/Zend/zend.c hardened-php-5.0.4-0.2.7/Zend/zend.c
243--- php-5.0.4/Zend/zend.c 2005-03-16 00:47:12.000000000 +0100
244+++ hardened-php-5.0.4-0.2.7/Zend/zend.c 2005-04-07 02:04:38.000000000 +0200
245@@ -54,6 +54,12 @@
246 ZEND_API void (*zend_unblock_interruptions)(void);
247 ZEND_API void (*zend_ticks_function)(int ticks);
248 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
249+#if HARDENED_PHP
250+ZEND_API void (*zend_security_log)(char *str);
251+#endif
252+#if HARDENED_PHP_INC_PROTECT
253+ZEND_API int (*zend_is_valid_include)(zval *z);
254+#endif
255 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
256
257 void (*zend_on_timeout)(int seconds TSRMLS_DC);
258@@ -545,6 +551,14 @@
259 extern zend_scanner_globals language_scanner_globals;
260 #endif
261
262+ /* Set up Hardened-PHP utility functions first */
263+#if HARDENED_PHP
264+ zend_security_log = utility_functions->security_log_function;
265+#endif
266+#if HARDENED_PHP_INC_PROTECT
267+ zend_is_valid_include = utility_functions->is_valid_include;
268+#endif
269+
270 #ifdef ZTS
271 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
272 #else
273diff -Nur php-5.0.4/Zend/zend.h hardened-php-5.0.4-0.2.7/Zend/zend.h
274--- php-5.0.4/Zend/zend.h 2005-03-10 12:30:44.000000000 +0100
275+++ hardened-php-5.0.4-0.2.7/Zend/zend.h 2005-04-07 02:04:38.000000000 +0200
276@@ -359,6 +359,12 @@
277 void (*on_timeout)(int seconds TSRMLS_DC);
278 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
279 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
280+#if HARDENED_PHP
281+ void (*security_log_function)(char *str);
282+#endif
283+#if HARDENED_PHP_INC_PROTECT
284+ int (*is_valid_include)(zval *z);
285+#endif
286 } zend_utility_functions;
287
288
289@@ -496,6 +502,16 @@
290 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
291 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
292 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
293+#if HARDENED_PHP
294+extern ZEND_API void (*zend_security_log)(char *str);
295+#endif
296+#if HARDENED_PHP_INC_PROTECT
297+extern ZEND_API int (*zend_is_valid_include)(zval *z);
298+#endif
299+
300+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
301+ZEND_API unsigned int zend_canary(void);
302+#endif
303
304
305 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
306@@ -620,6 +636,10 @@
307 #define ZEND_MAX_RESERVED_RESOURCES 4
308
309
310+#if HARDENED_PHP
311+#include "hardened_globals.h"
312+#endif
313+
314 #endif /* ZEND_H */
315
316 /*
317diff -Nur php-5.0.4/Zend/zend_API.h hardened-php-5.0.4-0.2.7/Zend/zend_API.h
318--- php-5.0.4/Zend/zend_API.h 2005-01-22 13:29:13.000000000 +0100
319+++ hardened-php-5.0.4-0.2.7/Zend/zend_API.h 2005-04-07 02:04:38.000000000 +0200
320@@ -47,6 +47,7 @@
321 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
322
323 #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
324+#define ZEND_STATIC_FE(zend_name, name, arg_info) { zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), 0 },
325
326 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
327 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
328diff -Nur php-5.0.4/Zend/zend_alloc.c hardened-php-5.0.4-0.2.7/Zend/zend_alloc.c
329--- php-5.0.4/Zend/zend_alloc.c 2004-08-27 18:49:54.000000000 +0200
330+++ hardened-php-5.0.4-0.2.7/Zend/zend_alloc.c 2005-04-07 02:12:14.000000000 +0200
331@@ -64,6 +64,11 @@
332 # define END_MAGIC_SIZE 0
333 #endif
334
335+#if HARDENED_PHP_MM_PROTECT
336+# define CANARY_SIZE sizeof(unsigned int)
337+#else
338+# define CANARY_SIZE 0
339+#endif
340
341 # if MEMORY_LIMIT
342 # if ZEND_DEBUG
343@@ -104,9 +109,17 @@
344 if (p==AG(head)) { \
345 AG(head) = p->pNext; \
346 } else { \
347+ if (p != p->pLast->pNext) { \
348+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
349+ exit(1); \
350+ } \
351 p->pLast->pNext = p->pNext; \
352 } \
353 if (p->pNext) { \
354+ if (p != p->pNext->pLast) { \
355+ zend_security_log("linked list corrupt on efree() - heap corruption detected"); \
356+ exit(1); \
357+ } \
358 p->pNext->pLast = p->pLast; \
359 }
360 #else
361@@ -145,6 +158,12 @@
362 DECLARE_CACHE_VARS();
363 TSRMLS_FETCH();
364
365+#if HARDENED_PHP_MM_PROTECT
366+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
367+ zend_security_log("emalloc() - requested size would result in integer overflow");
368+ exit(1);
369+ }
370+#endif
371 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
372
373 #if !ZEND_DISABLE_MEMORY_CACHE
374@@ -163,6 +182,10 @@
375 AG(cache_stats)[CACHE_INDEX][1]++;
376 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
377 #endif
378+#if HARDENED_PHP_MM_PROTECT
379+ p->canary = HG(canary_1);
380+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
381+#endif
382 p->cached = 0;
383 p->size = size;
384 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
385@@ -179,7 +202,7 @@
386 AG(allocated_memory_peak) = AG(allocated_memory);
387 }
388 #endif
389- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
390+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
391 #if !ZEND_DISABLE_MEMORY_CACHE
392 }
393 #endif
394@@ -211,7 +234,10 @@
395 # endif
396 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
397 #endif
398-
399+#if HARDENED_PHP_MM_PROTECT
400+ p->canary = HG(canary_1);
401+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
402+#endif
403 HANDLE_UNBLOCK_INTERRUPTIONS();
404 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
405 }
406@@ -239,6 +265,10 @@
407 }
408 }
409
410+
411+#if HARDENED_PHP
412+ zend_security_log("Possible integer overflow catched by safe_emalloc()");
413+#endif
414 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
415 return 0;
416 }
417@@ -247,9 +277,22 @@
418
419 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
420 {
421+#if HARDENED_PHP_MM_PROTECT
422+ unsigned int *canary_2;
423+#endif
424 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
425 DECLARE_CACHE_VARS();
426 TSRMLS_FETCH();
427+
428+#if HARDENED_PHP_MM_PROTECT
429+ canary_2 = (unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
430+ if (p->canary != HG(canary_1) || *canary_2 != HG(canary_2)) {
431+ zend_security_log("canary mismatch on efree() - heap overflow or double efree detected");
432+ exit(1);
433+ }
434+ /* to catch double efree()s */
435+ *canary_2 = p->canary = 0;
436+#endif
437
438 #if defined(ZTS) && TSRM_DEBUG
439 if (p->thread_id != tsrm_thread_id()) {
440@@ -291,23 +334,35 @@
441
442 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
443 {
444- void *p;
445- int final_size = size*nmemb;
446+ char *p;
447+ size_t _size = nmemb * size;
448+
449+ if (nmemb && (_size/nmemb!=size)) {
450+#if HARDENED_PHP
451+ zend_security_log("Possible integer overflow catched by ecalloc()");
452+#endif
453+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
454+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
455+ kill(getpid(), SIGSEGV);
456+#else
457+ exit(1);
458+#endif
459+ }
460
461- HANDLE_BLOCK_INTERRUPTIONS();
462- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
463- if (!p) {
464- HANDLE_UNBLOCK_INTERRUPTIONS();
465- return (void *) p;
466+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
467+ if (p) {
468+ memset(p, 0, _size);
469 }
470- memset(p, 0, final_size);
471- HANDLE_UNBLOCK_INTERRUPTIONS();
472- return p;
473+
474+ return ((void *)p);
475 }
476
477
478 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
479 {
480+#if HARDENED_PHP_MM_PROTECT
481+ unsigned int canary_2;
482+#endif
483 zend_mem_header *p;
484 zend_mem_header *orig;
485 DECLARE_CACHE_VARS();
486@@ -319,6 +374,14 @@
487
488 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
489
490+#if HARDENED_PHP_MM_PROTECT
491+ canary_2 = *(unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
492+ if (p->canary != HG(canary_1) || canary_2 != HG(canary_2)) {
493+ zend_security_log("canary mismatch on erealloc() - heap overflow detected");
494+ exit(1);
495+ }
496+#endif
497+
498 #if defined(ZTS) && TSRM_DEBUG
499 if (p->thread_id != tsrm_thread_id()) {
500 void *new_p;
501@@ -342,7 +405,7 @@
502 }
503 #endif
504 REMOVE_POINTER_FROM_LIST(p);
505- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
506+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
507 if (!p) {
508 if (!allow_failure) {
509 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
510@@ -364,6 +427,9 @@
511 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
512 #endif
513
514+#if HARDENED_PHP_MM_PROTECT
515+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
516+#endif
517 p->size = size;
518
519 HANDLE_UNBLOCK_INTERRUPTIONS();
520@@ -439,6 +505,10 @@
521 {
522 AG(head) = NULL;
523
524+#if HARDENED_PHP_MM_PROTECT
525+ HG(canary_1) = zend_canary();
526+ HG(canary_2) = zend_canary();
527+#endif
528 #if MEMORY_LIMIT
529 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
530 AG(allocated_memory) = 0;
531diff -Nur php-5.0.4/Zend/zend_alloc.h hardened-php-5.0.4-0.2.7/Zend/zend_alloc.h
532--- php-5.0.4/Zend/zend_alloc.h 2004-08-11 08:13:12.000000000 +0200
533+++ hardened-php-5.0.4-0.2.7/Zend/zend_alloc.h 2005-04-07 02:04:38.000000000 +0200
534@@ -35,6 +35,9 @@
535 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
536
537 typedef struct _zend_mem_header {
538+#if HARDENED_PHP_MM_PROTECT
539+ unsigned int canary;
540+#endif
541 #if ZEND_DEBUG
542 long magic;
543 char *filename;
544diff -Nur php-5.0.4/Zend/zend_builtin_functions.c hardened-php-5.0.4-0.2.7/Zend/zend_builtin_functions.c
545--- php-5.0.4/Zend/zend_builtin_functions.c 2005-03-14 10:13:14.000000000 +0100
546+++ hardened-php-5.0.4-0.2.7/Zend/zend_builtin_functions.c 2005-04-07 02:04:38.000000000 +0200
547@@ -52,6 +52,9 @@
548 static ZEND_FUNCTION(crash);
549 #endif
550 #endif
551+#if HARDENED_PHP_MM_PROTECT_DEBUG
552+static ZEND_FUNCTION(heap_overflow);
553+#endif
554 static ZEND_FUNCTION(get_included_files);
555 static ZEND_FUNCTION(is_subclass_of);
556 static ZEND_FUNCTION(is_a);
557@@ -111,6 +114,9 @@
558 ZEND_FE(crash, NULL)
559 #endif
560 #endif
561+#if HARDENED_PHP_MM_PROTECT_DEBUG
562+ ZEND_FE(heap_overflow, NULL)
563+#endif
564 ZEND_FE(get_included_files, NULL)
565 ZEND_FALIAS(get_required_files, get_included_files, NULL)
566 ZEND_FE(is_subclass_of, NULL)
567@@ -999,6 +1005,19 @@
568
569 #endif /* ZEND_DEBUG */
570
571+
572+#if HARDENED_PHP_MM_PROTECT_DEBUG
573+ZEND_FUNCTION(heap_overflow)
574+{
575+ char *nowhere = emalloc(10);
576+
577+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
578+
579+ efree(nowhere);
580+}
581+#endif
582+
583+
584 /* {{{ proto array get_included_files(void)
585 Returns an array with the file names that were include_once()'d */
586 ZEND_FUNCTION(get_included_files)
587diff -Nur php-5.0.4/Zend/zend_canary.c hardened-php-5.0.4-0.2.7/Zend/zend_canary.c
588--- php-5.0.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
589+++ hardened-php-5.0.4-0.2.7/Zend/zend_canary.c 2005-04-07 02:04:38.000000000 +0200
590@@ -0,0 +1,58 @@
591+/*
592+ +----------------------------------------------------------------------+
593+ | Hardened-PHP |
594+ +----------------------------------------------------------------------+
595+ | Copyright (c) 2004 Stefan Esser |
596+ +----------------------------------------------------------------------+
597+ | This source file is subject to version 2.02 of the PHP license, |
598+ | that is bundled with this package in the file LICENSE, and is |
599+ | available at through the world-wide-web at |
600+ | http://www.php.net/license/2_02.txt. |
601+ | If you did not receive a copy of the PHP license and are unable to |
602+ | obtain it through the world-wide-web, please send a note to |
603+ | license@php.net so we can mail you a copy immediately. |
604+ +----------------------------------------------------------------------+
605+ | Author: Stefan Esser <sesser@php.net> |
606+ +----------------------------------------------------------------------+
607+ */
608+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
609+
610+#include "zend.h"
611+
612+#include <stdio.h>
613+#include <stdlib.h>
614+
615+
616+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
617+
618+/* will be replaced later with more compatible method */
619+ZEND_API unsigned int zend_canary()
620+{
621+ time_t t;
622+ unsigned int canary;
623+ int fd;
624+
625+ fd = open("/dev/urandom", 0);
626+ if (fd != -1) {
627+ int r = read(fd, &canary, sizeof(canary));
628+ close(fd);
629+ if (r == sizeof(canary)) {
630+ return (canary);
631+ }
632+ }
633+ /* not good but we never want to do this */
634+ time(&t);
635+ canary = *(unsigned int *)&t + getpid() << 16;
636+ return (canary);
637+}
638+#endif
639+
640+
641+/*
642+ * Local variables:
643+ * tab-width: 4
644+ * c-basic-offset: 4
645+ * End:
646+ * vim600: sw=4 ts=4 fdm=marker
647+ * vim<600: sw=4 ts=4
648+ */
649diff -Nur php-5.0.4/Zend/zend_execute.c hardened-php-5.0.4-0.2.7/Zend/zend_execute.c
650--- php-5.0.4/Zend/zend_execute.c 2005-03-21 17:22:10.000000000 +0100
651+++ hardened-php-5.0.4-0.2.7/Zend/zend_execute.c 2005-04-07 02:04:38.000000000 +0200
652@@ -3523,7 +3523,12 @@
653 int dummy = 1;
654 zend_file_handle file_handle;
655
656+#if HARDENED_PHP_INC_PROTECT
657+ if (zend_is_valid_include(inc_filename)
658+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
659+#else
660 if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
661+#endif
662
663 if (!file_handle.opened_path) {
664 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
665@@ -3548,6 +3553,11 @@
666 break;
667 case ZEND_INCLUDE:
668 case ZEND_REQUIRE:
669+#if HARDENED_PHP_INC_PROTECT
670+ if (!zend_is_valid_include(inc_filename)) {
671+ break;
672+ }
673+#endif
674 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
675 break;
676 case ZEND_EVAL: {
677diff -Nur php-5.0.4/Zend/zend_extensions.h hardened-php-5.0.4-0.2.7/Zend/zend_extensions.h
678--- php-5.0.4/Zend/zend_extensions.h 2004-11-25 21:26:48.000000000 +0100
679+++ hardened-php-5.0.4-0.2.7/Zend/zend_extensions.h 2005-04-07 02:04:38.000000000 +0200
680@@ -24,10 +24,11 @@
681
682 #include "zend_compile.h"
683
684-/* The first number is the engine version and the rest is the date.
685+/* The first number is a flag saying that Hardened-PHP is used
686+ * the second number is the engine version and the rest is the date.
687 * This way engine 2 API no. is always greater than engine 1 API no..
688 */
689-#define ZEND_EXTENSION_API_NO 220040412
690+#define ZEND_EXTENSION_API_NO 1220040412
691
692 typedef struct _zend_extension_version_info {
693 int zend_extension_api_no;
694diff -Nur php-5.0.4/Zend/zend_hash.c hardened-php-5.0.4-0.2.7/Zend/zend_hash.c
695--- php-5.0.4/Zend/zend_hash.c 2004-07-10 09:45:49.000000000 +0200
696+++ hardened-php-5.0.4-0.2.7/Zend/zend_hash.c 2005-04-07 02:06:13.000000000 +0200
697@@ -21,6 +21,18 @@
698
699 #include "zend.h"
700
701+#if HARDENED_PHP_HASH_PROTECT
702+ unsigned int zend_hash_canary = 0x1234567;
703+ zend_bool zend_hash_canary_inited = 0;
704+#endif
705+
706+#define CHECK_HASH_CANARY(hash) \
707+ if (zend_hash_canary != (hash)->canary) { \
708+ zend_security_log("Zend HashTable canary was overwritten"); \
709+ exit(1); \
710+ }
711+
712+
713 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
714 (element)->pNext = (list_head); \
715 (element)->pLast = NULL; \
716@@ -138,6 +150,9 @@
717 {
718 uint i = 3;
719 Bucket **tmp;
720+#if HARDENED_PHP_HASH_PROTECT
721+ TSRMLS_FETCH();
722+#endif
723
724 SET_INCONSISTENT(HT_OK);
725
726@@ -147,6 +162,13 @@
727
728 ht->nTableSize = 1 << i;
729 ht->nTableMask = ht->nTableSize - 1;
730+#if HARDENED_PHP_HASH_PROTECT
731+ if (zend_hash_canary_inited==0) {
732+ zend_hash_canary = zend_canary();
733+ zend_hash_canary_inited = 1;
734+ }
735+ ht->canary = zend_hash_canary;
736+#endif
737 ht->pDestructor = pDestructor;
738 ht->arBuckets = NULL;
739 ht->pListHead = NULL;
740@@ -226,6 +248,9 @@
741 }
742 #endif
743 if (ht->pDestructor) {
744+#if HARDENED_PHP_HASH_PROTECT
745+ CHECK_HASH_CANARY(ht);
746+#endif
747 ht->pDestructor(p->pData);
748 }
749 UPDATE_DATA(ht, p, pData, nDataSize);
750@@ -291,6 +316,9 @@
751 }
752 #endif
753 if (ht->pDestructor) {
754+#if HARDENED_PHP_HASH_PROTECT
755+ CHECK_HASH_CANARY(ht);
756+#endif
757 ht->pDestructor(p->pData);
758 }
759 UPDATE_DATA(ht, p, pData, nDataSize);
760@@ -366,6 +394,9 @@
761 }
762 #endif
763 if (ht->pDestructor) {
764+#if HARDENED_PHP_HASH_PROTECT
765+ CHECK_HASH_CANARY(ht);
766+#endif
767 ht->pDestructor(p->pData);
768 }
769 UPDATE_DATA(ht, p, pData, nDataSize);
770@@ -414,7 +445,7 @@
771 IS_CONSISTENT(ht);
772
773 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
774- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
775+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
776 if (t) {
777 HANDLE_BLOCK_INTERRUPTIONS();
778 ht->arBuckets = t;
779@@ -424,6 +455,7 @@
780 HANDLE_UNBLOCK_INTERRUPTIONS();
781 return SUCCESS;
782 }
783+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
784 return FAILURE;
785 }
786 return SUCCESS;
787@@ -487,6 +519,9 @@
788 ht->pInternalPointer = p->pListNext;
789 }
790 if (ht->pDestructor) {
791+#if HARDENED_PHP_HASH_PROTECT
792+ CHECK_HASH_CANARY(ht);
793+#endif
794 ht->pDestructor(p->pData);
795 }
796 if (!p->pDataPtr) {
797@@ -516,6 +551,9 @@
798 q = p;
799 p = p->pListNext;
800 if (ht->pDestructor) {
801+#if HARDENED_PHP_HASH_PROTECT
802+ CHECK_HASH_CANARY(ht);
803+#endif
804 ht->pDestructor(q->pData);
805 }
806 if (!q->pDataPtr && q->pData) {
807@@ -542,6 +580,9 @@
808 q = p;
809 p = p->pListNext;
810 if (ht->pDestructor) {
811+#if HARDENED_PHP_HASH_PROTECT
812+ CHECK_HASH_CANARY(ht);
813+#endif
814 ht->pDestructor(q->pData);
815 }
816 if (!q->pDataPtr && q->pData) {
817@@ -571,6 +612,9 @@
818 HANDLE_BLOCK_INTERRUPTIONS();
819
820 if (ht->pDestructor) {
821+#if HARDENED_PHP_HASH_PROTECT
822+ CHECK_HASH_CANARY(ht);
823+#endif
824 ht->pDestructor(p->pData);
825 }
826 if (!p->pDataPtr) {
827diff -Nur php-5.0.4/Zend/zend_hash.h hardened-php-5.0.4-0.2.7/Zend/zend_hash.h
828--- php-5.0.4/Zend/zend_hash.h 2004-01-08 18:31:47.000000000 +0100
829+++ hardened-php-5.0.4-0.2.7/Zend/zend_hash.h 2005-04-07 02:04:38.000000000 +0200
830@@ -58,6 +58,9 @@
831 } Bucket;
832
833 typedef struct _hashtable {
834+#if HARDENED_PHP_HASH_PROTECT
835+ unsigned int canary;
836+#endif
837 uint nTableSize;
838 uint nTableMask;
839 uint nNumOfElements;
840diff -Nur php-5.0.4/Zend/zend_llist.c hardened-php-5.0.4-0.2.7/Zend/zend_llist.c
841--- php-5.0.4/Zend/zend_llist.c 2004-01-08 18:31:47.000000000 +0100
842+++ hardened-php-5.0.4-0.2.7/Zend/zend_llist.c 2005-04-07 02:04:38.000000000 +0200
843@@ -22,9 +22,34 @@
844 #include "zend.h"
845 #include "zend_llist.h"
846 #include "zend_qsort.h"
847+#include "zend_globals.h"
848+
849+#define CHECK_LIST_CANARY(list) \
850+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
851+ zend_security_log("linked list canary was overwritten"); \
852+ exit(1); \
853+ }
854+
855+#define CHECK_LISTELEMENT_CANARY(elem) \
856+ if (HG(canary_3) != (elem)->canary) { \
857+ zend_security_log("linked list element canary was overwritten"); \
858+ exit(1); \
859+ }
860+
861
862 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
863 {
864+#if HARDENED_PHP_LL_PROTECT
865+ TSRMLS_FETCH();
866+
867+ if (!HG(ll_canary_inited)) {
868+ HG(canary_3) = zend_canary();
869+ HG(canary_4) = zend_canary();
870+ HG(ll_canary_inited) = 1;
871+ }
872+ l->canary_h = HG(canary_3);
873+ l->canary_t = HG(canary_4);
874+#endif
875 l->head = NULL;
876 l->tail = NULL;
877 l->count = 0;
878@@ -38,6 +63,11 @@
879 {
880 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
881
882+#if HARDENED_PHP_LL_PROTECT
883+ TSRMLS_FETCH();
884+ CHECK_LIST_CANARY(l)
885+ tmp->canary = HG(canary_3);
886+#endif
887 tmp->prev = l->tail;
888 tmp->next = NULL;
889 if (l->tail) {
890@@ -56,6 +86,11 @@
891 {
892 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
893
894+#if HARDENED_PHP_LL_PROTECT
895+ TSRMLS_FETCH();
896+ CHECK_LIST_CANARY(l)
897+ tmp->canary = HG(canary_3);
898+#endif
899 tmp->next = l->head;
900 tmp->prev = NULL;
901 if (l->head) {
902@@ -93,10 +128,20 @@
903 zend_llist_element *current=l->head;
904 zend_llist_element *next;
905
906+#if HARDENED_PHP_LL_PROTECT
907+ TSRMLS_FETCH();
908+ CHECK_LIST_CANARY(l)
909+#endif
910 while (current) {
911+#if HARDENED_PHP_LL_PROTECT
912+ CHECK_LISTELEMENT_CANARY(current)
913+#endif
914 next = current->next;
915 if (compare(current->data, element)) {
916 DEL_LLIST_ELEMENT(current, l);
917+#if HARDENED_PHP_LL_PROTECT
918+ current->canary = 0;
919+#endif
920 break;
921 }
922 current = next;
923@@ -108,7 +153,14 @@
924 {
925 zend_llist_element *current=l->head, *next;
926
927+#if HARDENED_PHP_LL_PROTECT
928+ TSRMLS_FETCH();
929+ CHECK_LIST_CANARY(l)
930+#endif
931 while (current) {
932+#if HARDENED_PHP_LL_PROTECT
933+ CHECK_LISTELEMENT_CANARY(current)
934+#endif
935 next = current->next;
936 if (l->dtor) {
937 l->dtor(current->data);
938@@ -133,7 +185,14 @@
939 zend_llist_element *old_tail;
940 void *data;
941
942+#if HARDENED_PHP_LL_PROTECT
943+ TSRMLS_FETCH();
944+ CHECK_LIST_CANARY(l)
945+#endif
946 if ((old_tail = l->tail)) {
947+#if HARDENED_PHP_LL_PROTECT
948+ CHECK_LISTELEMENT_CANARY(old_tail)
949+#endif
950 if (l->tail->prev) {
951 l->tail->prev->next = NULL;
952 }
953@@ -159,9 +218,16 @@
954 {
955 zend_llist_element *ptr;
956
957+#if HARDENED_PHP_LL_PROTECT
958+ TSRMLS_FETCH();
959+ CHECK_LIST_CANARY(src)
960+#endif
961 zend_llist_init(dst, src->size, src->dtor, src->persistent);
962 ptr = src->head;
963 while (ptr) {
964+#if HARDENED_PHP_LL_PROTECT
965+ CHECK_LISTELEMENT_CANARY(ptr)
966+#endif
967 zend_llist_add_element(dst, ptr->data);
968 ptr = ptr->next;
969 }
970@@ -172,11 +238,21 @@
971 {
972 zend_llist_element *element, *next;
973
974+#if HARDENED_PHP_LL_PROTECT
975+ TSRMLS_FETCH();
976+ CHECK_LIST_CANARY(l)
977+#endif
978 element=l->head;
979 while (element) {
980+#if HARDENED_PHP_LL_PROTECT
981+ CHECK_LISTELEMENT_CANARY(element)
982+#endif
983 next = element->next;
984 if (func(element->data)) {
985 DEL_LLIST_ELEMENT(element, l);
986+#if HARDENED_PHP_LL_PROTECT
987+ element->canary = 0;
988+#endif
989 }
990 element = next;
991 }
992@@ -187,7 +263,13 @@
993 {
994 zend_llist_element *element;
995
996+#if HARDENED_PHP_LL_PROTECT
997+ CHECK_LIST_CANARY(l)
998+#endif
999 for (element=l->head; element; element=element->next) {
1000+#if HARDENED_PHP_LL_PROTECT
1001+ CHECK_LISTELEMENT_CANARY(element)
1002+#endif
1003 func(element->data TSRMLS_CC);
1004 }
1005 }
1006@@ -199,6 +281,9 @@
1007 zend_llist_element **elements;
1008 zend_llist_element *element, **ptr;
1009
1010+#if HARDENED_PHP_LL_PROTECT
1011+ CHECK_LIST_CANARY(l)
1012+#endif
1013 if (l->count <= 0) {
1014 return;
1015 }
1016@@ -208,6 +293,9 @@
1017 ptr = &elements[0];
1018
1019 for (element=l->head; element; element=element->next) {
1020+#if HARDENED_PHP_LL_PROTECT
1021+ CHECK_LISTELEMENT_CANARY(element)
1022+#endif
1023 *ptr++ = element;
1024 }
1025
1026@@ -230,7 +318,13 @@
1027 {
1028 zend_llist_element *element;
1029
1030+#if HARDENED_PHP_LL_PROTECT
1031+ CHECK_LIST_CANARY(l)
1032+#endif
1033 for (element=l->head; element; element=element->next) {
1034+#if HARDENED_PHP_LL_PROTECT
1035+ CHECK_LISTELEMENT_CANARY(element)
1036+#endif
1037 func(element->data, arg TSRMLS_CC);
1038 }
1039 }
1040@@ -241,8 +335,14 @@
1041 zend_llist_element *element;
1042 va_list args;
1043
1044+#if HARDENED_PHP_LL_PROTECT
1045+ CHECK_LIST_CANARY(l)
1046+#endif
1047 va_start(args, num_args);
1048 for (element=l->head; element; element=element->next) {
1049+#if HARDENED_PHP_LL_PROTECT
1050+ CHECK_LISTELEMENT_CANARY(element)
1051+#endif
1052 func(element->data, num_args, args TSRMLS_CC);
1053 }
1054 va_end(args);
1055@@ -251,6 +351,10 @@
1056
1057 ZEND_API int zend_llist_count(zend_llist *l)
1058 {
1059+#if HARDENED_PHP_LL_PROTECT
1060+ TSRMLS_FETCH();
1061+ CHECK_LIST_CANARY(l)
1062+#endif
1063 return l->count;
1064 }
1065
1066@@ -259,8 +363,15 @@
1067 {
1068 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1069
1070+#if HARDENED_PHP_LL_PROTECT
1071+ TSRMLS_FETCH();
1072+ CHECK_LIST_CANARY(l)
1073+#endif
1074 *current = l->head;
1075 if (*current) {
1076+#if HARDENED_PHP_LL_PROTECT
1077+ CHECK_LISTELEMENT_CANARY(*current)
1078+#endif
1079 return (*current)->data;
1080 } else {
1081 return NULL;
1082@@ -272,8 +383,15 @@
1083 {
1084 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1085
1086+#if HARDENED_PHP_LL_PROTECT
1087+ TSRMLS_FETCH();
1088+ CHECK_LIST_CANARY(l)
1089+#endif
1090 *current = l->tail;
1091 if (*current) {
1092+#if HARDENED_PHP_LL_PROTECT
1093+ CHECK_LISTELEMENT_CANARY(*current)
1094+#endif
1095 return (*current)->data;
1096 } else {
1097 return NULL;
1098@@ -285,9 +403,19 @@
1099 {
1100 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1101
1102+#if HARDENED_PHP_LL_PROTECT
1103+ TSRMLS_FETCH();
1104+ CHECK_LIST_CANARY(l)
1105+#endif
1106 if (*current) {
1107+#if HARDENED_PHP_LL_PROTECT
1108+ CHECK_LISTELEMENT_CANARY(*current)
1109+#endif
1110 *current = (*current)->next;
1111 if (*current) {
1112+#if HARDENED_PHP_LL_PROTECT
1113+ CHECK_LISTELEMENT_CANARY(*current)
1114+#endif
1115 return (*current)->data;
1116 }
1117 }
1118@@ -299,9 +427,19 @@
1119 {
1120 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1121
1122+#if HARDENED_PHP_LL_PROTECT
1123+ TSRMLS_FETCH();
1124+ CHECK_LIST_CANARY(l)
1125+#endif
1126 if (*current) {
1127+#if HARDENED_PHP_LL_PROTECT
1128+ CHECK_LISTELEMENT_CANARY(*current)
1129+#endif
1130 *current = (*current)->prev;
1131 if (*current) {
1132+#if HARDENED_PHP_LL_PROTECT
1133+ CHECK_LISTELEMENT_CANARY(*current)
1134+#endif
1135 return (*current)->data;
1136 }
1137 }
1138diff -Nur php-5.0.4/Zend/zend_llist.h hardened-php-5.0.4-0.2.7/Zend/zend_llist.h
1139--- php-5.0.4/Zend/zend_llist.h 2004-01-08 18:31:47.000000000 +0100
1140+++ hardened-php-5.0.4-0.2.7/Zend/zend_llist.h 2005-04-07 02:04:38.000000000 +0200
1141@@ -23,6 +23,9 @@
1142 #define ZEND_LLIST_H
1143
1144 typedef struct _zend_llist_element {
1145+#if HARDENED_PHP_LL_PROTECT
1146+ unsigned int canary;
1147+#endif
1148 struct _zend_llist_element *next;
1149 struct _zend_llist_element *prev;
1150 char data[1]; /* Needs to always be last in the struct */
1151@@ -35,6 +38,9 @@
1152 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
1153
1154 typedef struct _zend_llist {
1155+#if HARDENED_PHP_LL_PROTECT
1156+ unsigned int canary_h; /* head */
1157+#endif
1158 zend_llist_element *head;
1159 zend_llist_element *tail;
1160 size_t count;
1161@@ -42,6 +48,9 @@
1162 llist_dtor_func_t dtor;
1163 unsigned char persistent;
1164 zend_llist_element *traverse_ptr;
1165+#if HARDENED_PHP_LL_PROTECT
1166+ unsigned int canary_t; /* tail */
1167+#endif
1168 } zend_llist;
1169
1170 typedef zend_llist_element* zend_llist_position;
1171diff -Nur php-5.0.4/Zend/zend_modules.h hardened-php-5.0.4-0.2.7/Zend/zend_modules.h
1172--- php-5.0.4/Zend/zend_modules.h 2005-03-16 00:47:12.000000000 +0100
1173+++ hardened-php-5.0.4-0.2.7/Zend/zend_modules.h 2005-04-07 02:04:38.000000000 +0200
1174@@ -38,7 +38,7 @@
1175 extern struct _zend_arg_info fourth_arg_force_ref[5];
1176 extern struct _zend_arg_info all_args_by_ref[1];
1177
1178-#define ZEND_MODULE_API_NO 20041030
1179+#define ZEND_MODULE_API_NO 1020041030
1180 #ifdef ZTS
1181 #define USING_ZTS 1
1182 #else
1183diff -Nur php-5.0.4/acinclude.m4 hardened-php-5.0.4-0.2.7/acinclude.m4
1184--- php-5.0.4/acinclude.m4 2005-01-25 14:02:45.000000000 +0100
1185+++ hardened-php-5.0.4-0.2.7/acinclude.m4 2005-04-07 02:04:39.000000000 +0200
1186@@ -1169,6 +1169,36 @@
1187 fi
1188 ])
1189
1190+dnl
1191+dnl Check for broken realpath()
1192+dnl
1193+dnl realpath("/etc/hosts/../passwd",XXX) should not return
1194+dnl "/etc/passwd"
1195+dnl
1196+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
1197+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
1198+ AC_TRY_RUN([
1199+main() {
1200+ char buf[4096+1];
1201+ buf[0] = 0;
1202+ realpath("/etc/hosts/../passwd", buf);
1203+ exit(strcmp(buf, "/etc/passwd")==0);
1204+}
1205+ ],[
1206+ ac_cv_broken_realpath=no
1207+ ],[
1208+ ac_cv_broken_realpath=yes
1209+ ],[
1210+ ac_cv_broken_realpath=no
1211+ ])
1212+ ])
1213+ if test "$ac_cv_broken_realpath" = "yes"; then
1214+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
1215+ else
1216+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
1217+ fi
1218+])
1219+
1220 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
1221 dnl
1222 dnl Basically sets up the link-stage for building module-name
1223diff -Nur php-5.0.4/configure hardened-php-5.0.4-0.2.7/configure
1224--- php-5.0.4/configure 2005-04-03 11:42:50.000000000 +0200
1225+++ hardened-php-5.0.4-0.2.7/configure 2005-04-07 02:04:39.000000000 +0200
1226@@ -401,6 +401,16 @@
1227 ac_default_prefix=/usr/local
1228 # Any additions from configure.in:
1229 ac_help="$ac_help
1230+ --disable-hardened-php-mm-protect Disable the Memory Manager protection."
1231+ac_help="$ac_help
1232+ --disable-hardened-php-ll-protect Disable the Linked List protection."
1233+ac_help="$ac_help
1234+ --disable-hardened-php-inc-protect Disable include/require protection."
1235+ac_help="$ac_help
1236+ --disable-hardened-php-fmt-protect Disable format string protection."
1237+ac_help="$ac_help
1238+ --disable-hardened-php-hash-protect Disable Zend HashTable DTOR protection."
1239+ac_help="$ac_help
1240
1241 SAPI modules:
1242 "
1243@@ -857,6 +867,8 @@
1244 ac_help="$ac_help
1245 --disable-tokenizer Disable tokenizer support"
1246 ac_help="$ac_help
1247+ --disable-varfilter Disable Hardened-PHP's variable filter"
1248+ac_help="$ac_help
1249 --enable-wddx Enable WDDX support."
1250 ac_help="$ac_help
1251 --disable-xml Disable XML support."
1252@@ -2749,6 +2761,157 @@
1253
1254
1255
1256+# Check whether --enable-hardened-php-mm-protect or --disable-hardened-php-mm-protect was given.
1257+if test "${enable_hardened_php_mm_protect+set}" = set; then
1258+ enableval="$enable_hardened_php_mm_protect"
1259+
1260+ DO_HARDENED_PHP_MM_PROTECT=$enableval
1261+
1262+else
1263+
1264+ DO_HARDENED_PHP_MM_PROTECT=yes
1265+
1266+fi
1267+
1268+
1269+# Check whether --enable-hardened-php-ll-protect or --disable-hardened-php-ll-protect was given.
1270+if test "${enable_hardened_php_ll_protect+set}" = set; then
1271+ enableval="$enable_hardened_php_ll_protect"
1272+
1273+ DO_HARDENED_PHP_LL_PROTECT=$enableval
1274+
1275+else
1276+
1277+ DO_HARDENED_PHP_LL_PROTECT=yes
1278+
1279+fi
1280+
1281+
1282+# Check whether --enable-hardened-php-inc-protect or --disable-hardened-php-inc-protect was given.
1283+if test "${enable_hardened_php_inc_protect+set}" = set; then
1284+ enableval="$enable_hardened_php_inc_protect"
1285+
1286+ DO_HARDENED_PHP_INC_PROTECT=$enableval
1287+
1288+else
1289+
1290+ DO_HARDENED_PHP_INC_PROTECT=yes
1291+
1292+fi
1293+
1294+
1295+# Check whether --enable-hardened-php-fmt-protect or --disable-hardened-php-fmt-protect was given.
1296+if test "${enable_hardened_php_fmt_protect+set}" = set; then
1297+ enableval="$enable_hardened_php_fmt_protect"
1298+
1299+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
1300+
1301+else
1302+
1303+ DO_HARDENED_PHP_FMT_PROTECT=yes
1304+
1305+fi
1306+
1307+
1308+# Check whether --enable-hardened-php-hash-protect or --disable-hardened-php-hash-protect was given.
1309+if test "${enable_hardened_php_hash_protect+set}" = set; then
1310+ enableval="$enable_hardened_php_hash_protect"
1311+
1312+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
1313+
1314+else
1315+
1316+ DO_HARDENED_PHP_HASH_PROTECT=yes
1317+
1318+fi
1319+
1320+
1321+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
1322+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
1323+echo "$ac_t""$DO_HARDENED_PHP_MM_PROTECT" 1>&6
1324+
1325+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
1326+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
1327+echo "$ac_t""$DO_HARDENED_PHP_LL_PROTECT" 1>&6
1328+
1329+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
1330+echo "configure:2733: checking whether to protect include/require statements" >&5
1331+echo "$ac_t""$DO_HARDENED_PHP_INC_PROTECT" 1>&6
1332+
1333+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
1334+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
1335+echo "$ac_t""$DO_HARDENED_PHP_FMT_PROTECT" 1>&6
1336+
1337+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
1338+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
1339+echo "$ac_t""$DO_HARDENED_PHP_HASH_PROTECT" 1>&6
1340+
1341+
1342+cat >> confdefs.h <<\EOF
1343+#define HARDENED_PHP 1
1344+EOF
1345+
1346+
1347+
1348+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
1349+ cat >> confdefs.h <<\EOF
1350+#define HARDENED_PHP_MM_PROTECT 1
1351+EOF
1352+
1353+else
1354+ cat >> confdefs.h <<\EOF
1355+#define HARDENED_PHP_MM_PROTECT 0
1356+EOF
1357+
1358+fi
1359+
1360+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
1361+ cat >> confdefs.h <<\EOF
1362+#define HARDENED_PHP_LL_PROTECT 1
1363+EOF
1364+
1365+else
1366+ cat >> confdefs.h <<\EOF
1367+#define HARDENED_PHP_LL_PROTECT 0
1368+EOF
1369+
1370+fi
1371+
1372+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
1373+ cat >> confdefs.h <<\EOF
1374+#define HARDENED_PHP_INC_PROTECT 1
1375+EOF
1376+
1377+else
1378+ cat >> confdefs.h <<\EOF
1379+#define HARDENED_PHP_INC_PROTECT 0
1380+EOF
1381+
1382+fi
1383+
1384+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
1385+ cat >> confdefs.h <<\EOF
1386+#define HARDENED_PHP_FMT_PROTECT 1
1387+EOF
1388+
1389+else
1390+ cat >> confdefs.h <<\EOF
1391+#define HARDENED_PHP_FMT_PROTECT 0
1392+EOF
1393+
1394+fi
1395+
1396+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
1397+ cat >> confdefs.h <<\EOF
1398+#define HARDENED_PHP_HASH_PROTECT 1
1399+EOF
1400+
1401+else
1402+ cat >> confdefs.h <<\EOF
1403+#define HARDENED_PHP_HASH_PROTECT 0
1404+EOF
1405+
1406+fi
1407
1408
1409
1410@@ -17390,6 +17553,62 @@
1411 fi
1412
1413
1414+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
1415+echo "configure:14928: checking whether realpath is broken" >&5
1416+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
1417+ echo $ac_n "(cached) $ac_c" 1>&6
1418+else
1419+
1420+ if test "$cross_compiling" = yes; then
1421+
1422+ ac_cv_broken_realpath=no
1423+
1424+else
1425+ cat > conftest.$ac_ext <<EOF
1426+#line 14939 "configure"
1427+#include "confdefs.h"
1428+
1429+main() {
1430+ char buf[4096+1];
1431+ buf[0] = 0;
1432+ realpath("/etc/hosts/../passwd", buf);
1433+ exit(strcmp(buf, "/etc/passwd")==0);
1434+}
1435+
1436+EOF
1437+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
1438+then
1439+
1440+ ac_cv_broken_realpath=no
1441+
1442+else
1443+ echo "configure: failed program was:" >&5
1444+ cat conftest.$ac_ext >&5
1445+ rm -fr conftest*
1446+
1447+ ac_cv_broken_realpath=yes
1448+
1449+fi
1450+rm -fr conftest*
1451+fi
1452+
1453+
1454+fi
1455+
1456+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
1457+ if test "$ac_cv_broken_realpath" = "yes"; then
1458+ cat >> confdefs.h <<\EOF
1459+#define PHP_BROKEN_REALPATH 1
1460+EOF
1461+
1462+ else
1463+ cat >> confdefs.h <<\EOF
1464+#define PHP_BROKEN_REALPATH 0
1465+EOF
1466+
1467+ fi
1468+
1469+
1470 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
1471 echo "configure:17395: checking for declared timezone" >&5
1472 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
1473@@ -86878,6 +87097,265 @@
1474 fi
1475
1476
1477+echo $ac_n "checking whether to enable Hardened-PHP's variable filter""... $ac_c" 1>&6
1478+echo "configure:82041: checking whether to enable Hardened-PHP's variable filter" >&5
1479+# Check whether --enable-varfilter or --disable-varfilter was given.
1480+if test "${enable_varfilter+set}" = set; then
1481+ enableval="$enable_varfilter"
1482+ PHP_VARFILTER=$enableval
1483+else
1484+
1485+ PHP_VARFILTER=yes
1486+
1487+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
1488+ PHP_VARFILTER=$PHP_ENABLE_ALL
1489+ fi
1490+
1491+fi
1492+
1493+
1494+
1495+ext_output="yes, shared"
1496+ext_shared=yes
1497+case $PHP_VARFILTER in
1498+shared,*)
1499+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
1500+ ;;
1501+shared)
1502+ PHP_VARFILTER=yes
1503+ ;;
1504+no)
1505+ ext_output=no
1506+ ext_shared=no
1507+ ;;
1508+*)
1509+ ext_output=yes
1510+ ext_shared=no
1511+ ;;
1512+esac
1513+
1514+
1515+
1516+echo "$ac_t""$ext_output" 1>&6
1517+
1518+
1519+
1520+
1521+if test "$PHP_VARFILTER" != "no"; then
1522+ cat >> confdefs.h <<\EOF
1523+#define HAVE_VARFILTER 1
1524+EOF
1525+
1526+
1527+ ext_builddir=ext/varfilter
1528+ ext_srcdir=$abs_srcdir/ext/varfilter
1529+
1530+ ac_extra=
1531+
1532+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
1533+
1534+
1535+
1536+ case ext/varfilter in
1537+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1538+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1539+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1540+ esac
1541+
1542+
1543+
1544+ b_c_pre=$php_c_pre
1545+ b_cxx_pre=$php_cxx_pre
1546+ b_c_meta=$php_c_meta
1547+ b_cxx_meta=$php_cxx_meta
1548+ b_c_post=$php_c_post
1549+ b_cxx_post=$php_cxx_post
1550+ b_lo=$php_lo
1551+
1552+
1553+ old_IFS=$IFS
1554+ for ac_src in varfilter.c; do
1555+
1556+ IFS=.
1557+ set $ac_src
1558+ ac_obj=$1
1559+ IFS=$old_IFS
1560+
1561+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1562+
1563+ case $ac_src in
1564+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1565+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1566+ esac
1567+
1568+ cat >>Makefile.objects<<EOF
1569+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1570+ $ac_comp
1571+EOF
1572+ done
1573+
1574+
1575+ EXT_STATIC="$EXT_STATIC varfilter"
1576+ if test "$ext_shared" != "nocli"; then
1577+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1578+ fi
1579+ else
1580+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
1581+
1582+ case ext/varfilter in
1583+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1584+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1585+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1586+ esac
1587+
1588+
1589+
1590+ b_c_pre=$shared_c_pre
1591+ b_cxx_pre=$shared_cxx_pre
1592+ b_c_meta=$shared_c_meta
1593+ b_cxx_meta=$shared_cxx_meta
1594+ b_c_post=$shared_c_post
1595+ b_cxx_post=$shared_cxx_post
1596+ b_lo=$shared_lo
1597+
1598+
1599+ old_IFS=$IFS
1600+ for ac_src in varfilter.c; do
1601+
1602+ IFS=.
1603+ set $ac_src
1604+ ac_obj=$1
1605+ IFS=$old_IFS
1606+
1607+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
1608+
1609+ case $ac_src in
1610+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1611+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1612+ esac
1613+
1614+ cat >>Makefile.objects<<EOF
1615+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1616+ $ac_comp
1617+EOF
1618+ done
1619+
1620+
1621+ install_modules="install-modules"
1622+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
1623+
1624+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
1625+
1626+ cat >>Makefile.objects<<EOF
1627+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
1628+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
1629+
1630+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
1631+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
1632+
1633+EOF
1634+
1635+ cat >> confdefs.h <<EOF
1636+#define COMPILE_DL_VARFILTER 1
1637+EOF
1638+
1639+ fi
1640+ fi
1641+
1642+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
1643+ if test "$PHP_SAPI" = "cgi"; then
1644+
1645+
1646+ case ext/varfilter in
1647+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1648+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1649+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1650+ esac
1651+
1652+
1653+
1654+ b_c_pre=$php_c_pre
1655+ b_cxx_pre=$php_cxx_pre
1656+ b_c_meta=$php_c_meta
1657+ b_cxx_meta=$php_cxx_meta
1658+ b_c_post=$php_c_post
1659+ b_cxx_post=$php_cxx_post
1660+ b_lo=$php_lo
1661+
1662+
1663+ old_IFS=$IFS
1664+ for ac_src in varfilter.c; do
1665+
1666+ IFS=.
1667+ set $ac_src
1668+ ac_obj=$1
1669+ IFS=$old_IFS
1670+
1671+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1672+
1673+ case $ac_src in
1674+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1675+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1676+ esac
1677+
1678+ cat >>Makefile.objects<<EOF
1679+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1680+ $ac_comp
1681+EOF
1682+ done
1683+
1684+
1685+ EXT_STATIC="$EXT_STATIC varfilter"
1686+ else
1687+
1688+
1689+ case ext/varfilter in
1690+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1691+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1692+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1693+ esac
1694+
1695+
1696+
1697+ b_c_pre=$php_c_pre
1698+ b_cxx_pre=$php_cxx_pre
1699+ b_c_meta=$php_c_meta
1700+ b_cxx_meta=$php_cxx_meta
1701+ b_c_post=$php_c_post
1702+ b_cxx_post=$php_cxx_post
1703+ b_lo=$php_lo
1704+
1705+
1706+ old_IFS=$IFS
1707+ for ac_src in varfilter.c; do
1708+
1709+ IFS=.
1710+ set $ac_src
1711+ ac_obj=$1
1712+ IFS=$old_IFS
1713+
1714+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
1715+
1716+ case $ac_src in
1717+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
1718+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
1719+ esac
1720+
1721+ cat >>Makefile.objects<<EOF
1722+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1723+ $ac_comp
1724+EOF
1725+ done
1726+
1727+
1728+ fi
1729+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1730+ fi
1731+
1732+ BUILD_DIR="$BUILD_DIR $ext_builddir"
1733+
1734+
1735+fi
1736
1737
1738 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
1739@@ -97351,7 +97829,7 @@
1740 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1741 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1742 network.c php_open_temporary_file.c php_logos.c \
1743- output.c ; do
1744+ output.c hardened_php.c ; do
1745
1746 IFS=.
1747 set $ac_src
1748@@ -97579,7 +98057,7 @@
1749 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1750 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1751 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
1752- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
1753+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
1754
1755 IFS=.
1756 set $ac_src
1757diff -Nur php-5.0.4/configure.in hardened-php-5.0.4-0.2.7/configure.in
1758--- php-5.0.4/configure.in 2005-03-30 23:43:12.000000000 +0200
1759+++ hardened-php-5.0.4-0.2.7/configure.in 2005-04-07 02:04:39.000000000 +0200
1760@@ -235,7 +235,7 @@
1761 sinclude(Zend/acinclude.m4)
1762 sinclude(Zend/Zend.m4)
1763 sinclude(TSRM/tsrm.m4)
1764-
1765+sinclude(main/hardened_php.m4)
1766
1767
1768 divert(2)
1769@@ -620,6 +620,7 @@
1770 AC_FUNC_ALLOCA
1771 dnl PHP_AC_BROKEN_SPRINTF
1772 dnl PHP_AC_BROKEN_SNPRINTF
1773+PHP_AC_BROKEN_REALPATH
1774 PHP_DECLARED_TIMEZONE
1775 PHP_TIME_R_TYPE
1776 PHP_READDIR_R_TYPE
1777@@ -1262,7 +1263,7 @@
1778 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1779 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1780 network.c php_open_temporary_file.c php_logos.c \
1781- output.c )
1782+ output.c hardened_php.c )
1783
1784 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
1785 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
1786@@ -1280,7 +1281,7 @@
1787 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1788 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1789 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
1790- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
1791+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
1792
1793 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1794 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
1795diff -Nur php-5.0.4/ext/standard/array.c hardened-php-5.0.4-0.2.7/ext/standard/array.c
1796--- php-5.0.4/ext/standard/array.c 2005-03-12 11:12:49.000000000 +0100
1797+++ hardened-php-5.0.4-0.2.7/ext/standard/array.c 2005-04-07 02:04:39.000000000 +0200
1798@@ -1255,6 +1255,31 @@
1799 }
1800 }
1801 }
1802+
1803+ if (var_name[0] == 'H') {
1804+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1805+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1806+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1807+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1808+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1809+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1810+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)) {
1811+ return 0;
1812+ }
1813+ } else if (var_name[0] == '_') {
1814+ if ((strcmp(var_name, "_COOKIE")==0)||
1815+ (strcmp(var_name, "_ENV")==0)||
1816+ (strcmp(var_name, "_FILES")==0)||
1817+ (strcmp(var_name, "_GET")==0)||
1818+ (strcmp(var_name, "_POST")==0)||
1819+ (strcmp(var_name, "_REQUEST")==0)||
1820+ (strcmp(var_name, "_SESSION")==0)||
1821+ (strcmp(var_name, "_SERVER")==0)) {
1822+ return 0;
1823+ }
1824+ } else if (strcmp(var_name, "GLOBALS")==0) {
1825+ return 0;
1826+ }
1827
1828 return 1;
1829 }
1830diff -Nur php-5.0.4/ext/standard/basic_functions.c hardened-php-5.0.4-0.2.7/ext/standard/basic_functions.c
1831--- php-5.0.4/ext/standard/basic_functions.c 2005-03-10 13:10:57.000000000 +0100
1832+++ hardened-php-5.0.4-0.2.7/ext/standard/basic_functions.c 2005-04-07 02:04:39.000000000 +0200
1833@@ -617,7 +617,7 @@
1834 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1835
1836 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1837- PHP_FE(realpath, NULL)
1838+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1839 #endif
1840
1841 #ifdef HAVE_FNMATCH
1842@@ -3124,6 +3124,34 @@
1843 memcpy(new_key, prefix, prefix_len);
1844 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
1845
1846+ if (new_key[0] == 'H') {
1847+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1848+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1849+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1850+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1851+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1852+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1853+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)) {
1854+ efree(new_key);
1855+ return 0;
1856+ }
1857+ } else if (new_key[0] == '_') {
1858+ if ((strcmp(new_key, "_COOKIE")==0)||
1859+ (strcmp(new_key, "_ENV")==0)||
1860+ (strcmp(new_key, "_FILES")==0)||
1861+ (strcmp(new_key, "_GET")==0)||
1862+ (strcmp(new_key, "_POST")==0)||
1863+ (strcmp(new_key, "_REQUEST")==0)||
1864+ (strcmp(new_key, "_SESSION")==0)||
1865+ (strcmp(new_key, "_SERVER")==0)) {
1866+ efree(new_key);
1867+ return 0;
1868+ }
1869+ } else if (strcmp(new_key, "GLOBALS")==0) {
1870+ efree(new_key);
1871+ return 0;
1872+ }
1873+
1874 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1875 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1876
1877diff -Nur php-5.0.4/ext/standard/file.c hardened-php-5.0.4-0.2.7/ext/standard/file.c
1878--- php-5.0.4/ext/standard/file.c 2005-03-27 17:53:30.000000000 +0200
1879+++ hardened-php-5.0.4-0.2.7/ext/standard/file.c 2005-04-07 02:04:39.000000000 +0200
1880@@ -2044,7 +2044,7 @@
1881 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1882 /* {{{ proto string realpath(string path)
1883 Return the resolved path */
1884-PHP_FUNCTION(realpath)
1885+PHP_FUNCTION(real_path)
1886 {
1887 zval **path;
1888 char resolved_path_buff[MAXPATHLEN];
1889diff -Nur php-5.0.4/ext/standard/file.h hardened-php-5.0.4-0.2.7/ext/standard/file.h
1890--- php-5.0.4/ext/standard/file.h 2004-06-21 23:08:05.000000000 +0200
1891+++ hardened-php-5.0.4-0.2.7/ext/standard/file.h 2005-04-07 02:04:39.000000000 +0200
1892@@ -60,7 +60,7 @@
1893 PHP_FUNCTION(fd_set);
1894 PHP_FUNCTION(fd_isset);
1895 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1896-PHP_FUNCTION(realpath);
1897+PHP_FUNCTION(real_path);
1898 PHP_FUNCTION(fnmatch);
1899 #endif
1900 PHP_NAMED_FUNCTION(php_if_ftruncate);
1901diff -Nur php-5.0.4/ext/standard/info.c hardened-php-5.0.4-0.2.7/ext/standard/info.c
1902--- php-5.0.4/ext/standard/info.c 2004-05-02 15:23:30.000000000 +0200
1903+++ hardened-php-5.0.4-0.2.7/ext/standard/info.c 2005-04-07 02:04:39.000000000 +0200
1904@@ -394,7 +394,7 @@
1905
1906 if (flag & PHP_INFO_GENERAL) {
1907 char *zend_version = get_zend_version();
1908- char temp_api[10];
1909+ char temp_api[11];
1910 char *logo_guid;
1911
1912 php_uname = php_get_uname('a');
1913@@ -415,11 +415,22 @@
1914 PUTS("\" alt=\"PHP Logo\" /></a>");
1915 }
1916
1917+#if HARDENED_PHP
1918+ if (!sapi_module.phpinfo_as_text) {
1919+ php_printf("<h1 class=\"p\">Hardened-PHP Version %s/%s</h1>\n", PHP_VERSION, HARDENED_PHP_VERSION);
1920+ } else {
1921+ char temp_ver[40];
1922+
1923+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENED_PHP_VERSION);
1924+ php_info_print_table_row(2, "Hardened-PHP Version", temp_ver);
1925+ }
1926+#else
1927 if (!sapi_module.phpinfo_as_text) {
1928 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
1929 } else {
1930 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1931- }
1932+ }
1933+#endif
1934 php_info_print_box_end();
1935 php_info_print_table_start();
1936 php_info_print_table_row(2, "System", php_uname );
1937diff -Nur php-5.0.4/ext/varfilter/CREDITS hardened-php-5.0.4-0.2.7/ext/varfilter/CREDITS
1938--- php-5.0.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
1939+++ hardened-php-5.0.4-0.2.7/ext/varfilter/CREDITS 2005-04-07 02:04:39.000000000 +0200
1940@@ -0,0 +1,2 @@
1941+varfilter
1942+Stefan Esser
1943\ No newline at end of file
1944diff -Nur php-5.0.4/ext/varfilter/config.m4 hardened-php-5.0.4-0.2.7/ext/varfilter/config.m4
1945--- php-5.0.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
1946+++ hardened-php-5.0.4-0.2.7/ext/varfilter/config.m4 2005-04-07 02:04:39.000000000 +0200
1947@@ -0,0 +1,11 @@
1948+dnl
1949+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
1950+dnl
1951+
1952+PHP_ARG_ENABLE(varfilter, whether to enable Hardened-PHP's variable filter,
1953+[ --disable-varfilter Disable Hardened-PHP's variable filter], yes)
1954+
1955+if test "$PHP_VARFILTER" != "no"; then
1956+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
1957+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
1958+fi
1959diff -Nur php-5.0.4/ext/varfilter/php_varfilter.h hardened-php-5.0.4-0.2.7/ext/varfilter/php_varfilter.h
1960--- php-5.0.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
1961+++ hardened-php-5.0.4-0.2.7/ext/varfilter/php_varfilter.h 2005-04-07 02:04:39.000000000 +0200
1962@@ -0,0 +1,72 @@
1963+/*
1964+ +----------------------------------------------------------------------+
1965+ | PHP Version 4 |
1966+ +----------------------------------------------------------------------+
1967+ | Copyright (c) 1997-2003 The PHP Group |
1968+ +----------------------------------------------------------------------+
1969+ | This source file is subject to version 2.02 of the PHP license, |
1970+ | that is bundled with this package in the file LICENSE, and is |
1971+ | available at through the world-wide-web at |
1972+ | http://www.php.net/license/2_02.txt. |
1973+ | If you did not receive a copy of the PHP license and are unable to |
1974+ | obtain it through the world-wide-web, please send a note to |
1975+ | license@php.net so we can mail you a copy immediately. |
1976+ +----------------------------------------------------------------------+
1977+ | Author: Stefan Esser |
1978+ +----------------------------------------------------------------------+
1979+
1980+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
1981+*/
1982+
1983+#ifndef PHP_VARFILTER_H
1984+#define PHP_VARFILTER_H
1985+
1986+extern zend_module_entry varfilter_module_entry;
1987+#define phpext_varfilter_ptr &varfilter_module_entry
1988+
1989+#ifdef PHP_WIN32
1990+#define PHP_VARFILTER_API __declspec(dllexport)
1991+#else
1992+#define PHP_VARFILTER_API
1993+#endif
1994+
1995+#ifdef ZTS
1996+#include "TSRM.h"
1997+#endif
1998+
1999+#include "SAPI.h"
2000+
2001+PHP_MINIT_FUNCTION(varfilter);
2002+PHP_MSHUTDOWN_FUNCTION(varfilter);
2003+PHP_RINIT_FUNCTION(varfilter);
2004+PHP_RSHUTDOWN_FUNCTION(varfilter);
2005+PHP_MINFO_FUNCTION(varfilter);
2006+
2007+
2008+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2009+ long max_request_variables;
2010+ long cur_request_variables;
2011+ long max_varname_length;
2012+ long max_value_length;
2013+ long max_array_depth;
2014+ZEND_END_MODULE_GLOBALS(varfilter)
2015+
2016+
2017+#ifdef ZTS
2018+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2019+#else
2020+#define VARFILTER_G(v) (varfilter_globals.v)
2021+#endif
2022+
2023+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2024+
2025+#endif /* PHP_VARFILTER_H */
2026+
2027+
2028+/*
2029+ * Local variables:
2030+ * tab-width: 4
2031+ * c-basic-offset: 4
2032+ * indent-tabs-mode: t
2033+ * End:
2034+ */
2035diff -Nur php-5.0.4/ext/varfilter/varfilter.c hardened-php-5.0.4-0.2.7/ext/varfilter/varfilter.c
2036--- php-5.0.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2037+++ hardened-php-5.0.4-0.2.7/ext/varfilter/varfilter.c 2005-04-07 02:04:39.000000000 +0200
2038@@ -0,0 +1,196 @@
2039+/*
2040+ +----------------------------------------------------------------------+
2041+ | PHP Version 4 |
2042+ +----------------------------------------------------------------------+
2043+ | Copyright (c) 1997-2003 The PHP Group |
2044+ +----------------------------------------------------------------------+
2045+ | This source file is subject to version 2.02 of the PHP license, |
2046+ | that is bundled with this package in the file LICENSE, and is |
2047+ | available at through the world-wide-web at |
2048+ | http://www.php.net/license/2_02.txt. |
2049+ | If you did not receive a copy of the PHP license and are unable to |
2050+ | obtain it through the world-wide-web, please send a note to |
2051+ | license@php.net so we can mail you a copy immediately. |
2052+ +----------------------------------------------------------------------+
2053+ | Author: |
2054+ +----------------------------------------------------------------------+
2055+
2056+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2057+*/
2058+
2059+#ifdef HAVE_CONFIG_H
2060+#include "config.h"
2061+#endif
2062+
2063+#include "php.h"
2064+#include "php_ini.h"
2065+#include "ext/standard/info.h"
2066+#include "php_varfilter.h"
2067+#include "hardened_php.h"
2068+
2069+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2070+
2071+/* True global resources - no need for thread safety here */
2072+static int le_varfilter;
2073+
2074+/* {{{ varfilter_module_entry
2075+ */
2076+zend_module_entry varfilter_module_entry = {
2077+#if ZEND_MODULE_API_NO >= 20010901
2078+ STANDARD_MODULE_HEADER,
2079+#endif
2080+ "varfilter",
2081+ NULL,
2082+ PHP_MINIT(varfilter),
2083+ PHP_MSHUTDOWN(varfilter),
2084+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2085+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2086+ PHP_MINFO(varfilter),
2087+#if ZEND_MODULE_API_NO >= 20010901
2088+ "0.2.0", /* Replace with version number for your extension */
2089+#endif
2090+ STANDARD_MODULE_PROPERTIES
2091+};
2092+/* }}} */
2093+
2094+#ifdef COMPILE_DL_VARFILTER
2095+ZEND_GET_MODULE(varfilter)
2096+#endif
2097+
2098+/* {{{ PHP_INI
2099+ */
2100+PHP_INI_BEGIN()
2101+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_SYSTEM, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2102+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_SYSTEM, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2103+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "10000", PHP_INI_SYSTEM, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2104+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_SYSTEM, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2105+PHP_INI_END()
2106+/* }}} */
2107+
2108+/* {{{ php_varfilter_init_globals
2109+ */
2110+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2111+{
2112+ varfilter_globals->max_request_variables = 200;
2113+ varfilter_globals->cur_request_variables = 0;
2114+ varfilter_globals->max_varname_length = 64;
2115+ varfilter_globals->max_value_length = 10000;
2116+ varfilter_globals->max_array_depth = 100;
2117+}
2118+/* }}} */
2119+
2120+/* {{{ PHP_MINIT_FUNCTION
2121+ */
2122+PHP_MINIT_FUNCTION(varfilter)
2123+{
2124+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2125+ REGISTER_INI_ENTRIES();
2126+
2127+ sapi_register_input_filter(varfilter_input_filter);
2128+ return SUCCESS;
2129+}
2130+/* }}} */
2131+
2132+/* {{{ PHP_MSHUTDOWN_FUNCTION
2133+ */
2134+PHP_MSHUTDOWN_FUNCTION(varfilter)
2135+{
2136+ UNREGISTER_INI_ENTRIES();
2137+
2138+ return SUCCESS;
2139+}
2140+/* }}} */
2141+
2142+/* Remove if there's nothing to do at request start */
2143+/* {{{ PHP_RINIT_FUNCTION
2144+ */
2145+PHP_RINIT_FUNCTION(varfilter)
2146+{
2147+ VARFILTER_G(cur_request_variables) = 0;
2148+
2149+ return SUCCESS;
2150+}
2151+/* }}} */
2152+
2153+/* Remove if there's nothing to do at request end */
2154+/* {{{ PHP_RSHUTDOWN_FUNCTION
2155+ */
2156+PHP_RSHUTDOWN_FUNCTION(varfilter)
2157+{
2158+ return SUCCESS;
2159+}
2160+/* }}} */
2161+
2162+/* {{{ PHP_MINFO_FUNCTION
2163+ */
2164+PHP_MINFO_FUNCTION(varfilter)
2165+{
2166+ php_info_print_table_start();
2167+ php_info_print_table_header(2, "Hardened-PHP's variable filter support", "enabled");
2168+ php_info_print_table_end();
2169+
2170+ DISPLAY_INI_ENTRIES();
2171+}
2172+/* }}} */
2173+
2174+/* {{{ SAPI_INPUT_FILTER_FUNC
2175+ */
2176+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
2177+{
2178+ char *index;
2179+ unsigned int var_len, depth = 0;
2180+
2181+ /* Drop this variable if the limit is reached */
2182+ if (VARFILTER_G(max_request_variables) == VARFILTER_G(cur_request_variables)) {
2183+ php_security_log("tried to register too many variables");
2184+ return 0;
2185+ }
2186+
2187+ /* Drop this variable if it exceeds the value length limit */
2188+ if (VARFILTER_G(max_value_length) < val_len) {
2189+ php_security_log("tried to register a variable with a too long value");
2190+ return 0;
2191+ }
2192+
2193+ /* Find length of variable name */
2194+ index = strchr(var, '[');
2195+ var_len = index ? index-var : strlen(var);
2196+
2197+ /* Drop this variable if it exceeds the varname length limit */
2198+ if (VARFILTER_G(max_varname_length) < var_len) {
2199+ php_security_log("tried to register a variable with a too long variable name");
2200+ return 0;
2201+ }
2202+
2203+ /* Find out array depth */
2204+ while (index) {
2205+ depth++;
2206+ index = strchr(index+1, '[');
2207+ }
2208+
2209+ /* Drop this variable if it exceeds the array depth limit */
2210+ if (VARFILTER_G(max_array_depth) < depth) {
2211+ php_security_log("tried to register a too deep array variable");
2212+ return 0;
2213+ }
2214+
2215+ /* Okay let PHP register this variable */
2216+ VARFILTER_G(cur_request_variables)++;
2217+
2218+ if (new_val_len) {
2219+ *new_val_len = val_len;
2220+ }
2221+
2222+ return 1;
2223+}
2224+/* }}} */
2225+
2226+
2227+/*
2228+ * Local variables:
2229+ * tab-width: 4
2230+ * c-basic-offset: 4
2231+ * End:
2232+ * vim600: noet sw=4 ts=4 fdm=marker
2233+ * vim<600: noet sw=4 ts=4
2234+ */
2235diff -Nur php-5.0.4/main/SAPI.c hardened-php-5.0.4-0.2.7/main/SAPI.c
2236--- php-5.0.4/main/SAPI.c 2005-02-22 15:46:15.000000000 +0100
2237+++ hardened-php-5.0.4-0.2.7/main/SAPI.c 2005-04-07 02:04:39.000000000 +0200
2238@@ -821,6 +821,12 @@
2239 zend_hash_del(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1);
2240 }
2241
2242+SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
2243+{
2244+ sapi_module.input_filter = input_filter;
2245+ return SUCCESS;
2246+}
2247+
2248
2249 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
2250 {
2251@@ -835,11 +841,6 @@
2252 return SUCCESS;
2253 }
2254
2255-SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC))
2256-{
2257- sapi_module.input_filter = input_filter;
2258- return SUCCESS;
2259-}
2260
2261 SAPI_API int sapi_flush(TSRMLS_D)
2262 {
2263diff -Nur php-5.0.4/main/SAPI.h hardened-php-5.0.4-0.2.7/main/SAPI.h
2264--- php-5.0.4/main/SAPI.h 2004-01-08 18:33:04.000000000 +0100
2265+++ hardened-php-5.0.4-0.2.7/main/SAPI.h 2005-04-07 02:04:39.000000000 +0200
2266@@ -103,9 +103,14 @@
2267 char *current_user;
2268 int current_user_length;
2269
2270- /* this is necessary for CLI module */
2271- int argc;
2272- char **argv;
2273+ /* this is necessary for CLI module */
2274+ int argc;
2275+ char **argv;
2276+
2277+#if HARDENED_PHP
2278+ /* this is necessary for IP logging */
2279+ char ip_address[64];
2280+#endif
2281 } sapi_request_info;
2282
2283
2284@@ -270,7 +275,11 @@
2285
2286 #define SAPI_DEFAULT_MIMETYPE "text/html"
2287 #define SAPI_DEFAULT_CHARSET ""
2288+#if HARDENED_PHP
2289+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: Hardened-PHP/" PHP_VERSION
2290+#else
2291 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
2292+#endif
2293
2294 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
2295 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
2296diff -Nur php-5.0.4/main/fopen_wrappers.c hardened-php-5.0.4-0.2.7/main/fopen_wrappers.c
2297--- php-5.0.4/main/fopen_wrappers.c 2005-03-11 07:55:22.000000000 +0100
2298+++ hardened-php-5.0.4-0.2.7/main/fopen_wrappers.c 2005-04-07 02:05:49.000000000 +0200
2299@@ -163,6 +163,21 @@
2300 char *pathbuf;
2301 char *ptr;
2302 char *end;
2303+ char path_copy[MAXPATHLEN];
2304+ int path_len;
2305+
2306+ /* Special case path ends with a trailing slash */
2307+ path_len = strlen(path);
2308+ if (path_len >= MAXPATHLEN) {
2309+ errno = EPERM; /* we deny permission to open it */
2310+ return -1;
2311+ }
2312+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
2313+ memcpy(path_copy, path, path_len+1);
2314+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
2315+ path_copy[path_len] = '\0';
2316+ path = (const char *)&path_copy;
2317+ }
2318
2319 pathbuf = estrdup(PG(open_basedir));
2320
2321diff -Nur php-5.0.4/main/hardened_globals.h hardened-php-5.0.4-0.2.7/main/hardened_globals.h
2322--- php-5.0.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
2323+++ hardened-php-5.0.4-0.2.7/main/hardened_globals.h 2005-04-07 02:04:39.000000000 +0200
2324@@ -0,0 +1,54 @@
2325+/*
2326+ +----------------------------------------------------------------------+
2327+ | Hardened-PHP |
2328+ +----------------------------------------------------------------------+
2329+ | Copyright (c) 2004 Stefan Esser |
2330+ +----------------------------------------------------------------------+
2331+ | This source file is subject to version 2.02 of the PHP license, |
2332+ | that is bundled with this package in the file LICENSE, and is |
2333+ | available at through the world-wide-web at |
2334+ | http://www.php.net/license/2_02.txt. |
2335+ | If you did not receive a copy of the PHP license and are unable to |
2336+ | obtain it through the world-wide-web, please send a note to |
2337+ | license@php.net so we can mail you a copy immediately. |
2338+ +----------------------------------------------------------------------+
2339+ | Author: Stefan Esser <sesser@php.net> |
2340+ +----------------------------------------------------------------------+
2341+ */
2342+
2343+#ifndef HARDENED_GLOBALS_H
2344+#define HARDENED_GLOBALS_H
2345+
2346+typedef struct _hardened_globals hardened_globals_struct;
2347+
2348+#ifdef ZTS
2349+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
2350+extern int hardened_globals_id;
2351+#else
2352+# define HG(v) (hardened_globals.v)
2353+extern struct _hardened_globals hardened_globals;
2354+#endif
2355+
2356+
2357+struct _hardened_globals {
2358+#if HARDENED_PHP_MM_PROTECT
2359+ unsigned int canary_1;
2360+ unsigned int canary_2;
2361+#endif
2362+#if HARDENED_PHP_LL_PROTECT
2363+ unsigned int canary_3;
2364+ unsigned int canary_4;
2365+ unsigned int ll_canary_inited;
2366+#endif
2367+ unsigned int dummy;
2368+};
2369+
2370+
2371+#endif /* HARDENED_GLOBALS_H */
2372+
2373+/*
2374+ * Local variables:
2375+ * tab-width: 4
2376+ * c-basic-offset: 4
2377+ * End:
2378+ */
2379diff -Nur php-5.0.4/main/hardened_php.c hardened-php-5.0.4-0.2.7/main/hardened_php.c
2380--- php-5.0.4/main/hardened_php.c 1970-01-01 01:00:00.000000000 +0100
2381+++ hardened-php-5.0.4-0.2.7/main/hardened_php.c 2005-04-07 02:04:39.000000000 +0200
2382@@ -0,0 +1,205 @@
2383+/*
2384+ +----------------------------------------------------------------------+
2385+ | Hardened-PHP |
2386+ +----------------------------------------------------------------------+
2387+ | Copyright (c) 2004 Stefan Esser |
2388+ +----------------------------------------------------------------------+
2389+ | This source file is subject to version 2.02 of the PHP license, |
2390+ | that is bundled with this package in the file LICENSE, and is |
2391+ | available at through the world-wide-web at |
2392+ | http://www.php.net/license/2_02.txt. |
2393+ | If you did not receive a copy of the PHP license and are unable to |
2394+ | obtain it through the world-wide-web, please send a note to |
2395+ | license@php.net so we can mail you a copy immediately. |
2396+ +----------------------------------------------------------------------+
2397+ | Author: Stefan Esser <sesser@php.net> |
2398+ +----------------------------------------------------------------------+
2399+ */
2400+/* $Id: hardened_php.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
2401+
2402+#include "php.h"
2403+
2404+#include <stdio.h>
2405+#include <stdlib.h>
2406+
2407+#if HAVE_UNISTD_H
2408+#include <unistd.h>
2409+#endif
2410+#include "SAPI.h"
2411+#include "php_globals.h"
2412+
2413+#if HARDENED_PHP
2414+
2415+#ifdef HAVE_SYS_SOCKET_H
2416+#include <sys/socket.h>
2417+#endif
2418+
2419+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
2420+#undef AF_UNIX
2421+#endif
2422+
2423+#if defined(AF_UNIX)
2424+#include <sys/un.h>
2425+#endif
2426+
2427+#define SYSLOG_PATH "/dev/log"
2428+
2429+#include "snprintf.h"
2430+
2431+#ifdef ZTS
2432+#include "hardened_globals.h"
2433+int hardened_globals_id;
2434+#else
2435+struct _hardened_globals hardened_globals;
2436+#endif
2437+
2438+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
2439+{
2440+ memset(hardened_globals, 0, sizeof(*hardened_globals));
2441+}
2442+
2443+PHPAPI void hardened_startup()
2444+{
2445+#ifdef ZTS
2446+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
2447+#else
2448+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
2449+#endif
2450+}
2451+
2452+PHPAPI void php_security_log(char *str)
2453+{
2454+#if defined(AF_UNIX)
2455+ int s, r;
2456+ struct sockaddr_un saun;
2457+ char buf[1024];
2458+ char *ip_address;
2459+ char *fname;
2460+ TSRMLS_FETCH();
2461+
2462+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
2463+ if (ip_address == NULL) {
2464+ ip_address = "REMOTE_ADDR not set";
2465+ }
2466+
2467+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
2468+
2469+ ap_php_snprintf(buf, 1024, "php security-alert: %s (attacker '%s', file '%s')\n", str, ip_address, fname);
2470+
2471+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
2472+ if (s == -1) {
2473+ return;
2474+ }
2475+
2476+ memset(&saun, 0, sizeof(saun));
2477+ saun.sun_family = AF_UNIX;
2478+ strcpy(saun.sun_path, SYSLOG_PATH);
2479+ /*saun.sun_len = sizeof(saun);*/
2480+
2481+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2482+ if (r) {
2483+ close(s);
2484+ s = socket(AF_UNIX, SOCK_STREAM, 0);
2485+ if (s == -1) {
2486+ return;
2487+ }
2488+
2489+ memset(&saun, 0, sizeof(saun));
2490+ saun.sun_family = AF_UNIX;
2491+ strcpy(saun.sun_path, SYSLOG_PATH);
2492+ /*saun.sun_len = sizeof(saun);*/
2493+
2494+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2495+ if (r) {
2496+ close(s);
2497+ return;
2498+ }
2499+ }
2500+ send(s, buf, strlen(buf), 0);
2501+
2502+ close(s);
2503+#endif
2504+}
2505+#endif
2506+
2507+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2508+
2509+/* will be replaced later with more compatible method */
2510+PHPAPI unsigned int php_canary()
2511+{
2512+ time_t t;
2513+ unsigned int canary;
2514+ int fd;
2515+
2516+ fd = open("/dev/urandom", 0);
2517+ if (fd != -1) {
2518+ int r = read(fd, &canary, sizeof(canary));
2519+ close(fd);
2520+ if (r == sizeof(canary)) {
2521+ return (canary);
2522+ }
2523+ }
2524+ /* not good but we never want to do this */
2525+ time(&t);
2526+ canary = *(unsigned int *)&t + getpid() << 16;
2527+ return (canary);
2528+}
2529+#endif
2530+
2531+#if HARDENED_PHP_INC_PROTECT
2532+
2533+PHPAPI int php_is_valid_include(zval *z)
2534+{
2535+ char *filename;
2536+ int len;
2537+ TSRMLS_FETCH();
2538+
2539+ /* must be of type string */
2540+ if (z->type != IS_STRING || z->value.str.val == NULL) {
2541+ return (0);
2542+ }
2543+
2544+ /* short cut */
2545+ filename = z->value.str.val;
2546+ len = z->value.str.len;
2547+
2548+ /* 1. must be shorter than MAXPATHLEN */
2549+ if (len > MAXPATHLEN) {
2550+ php_security_log("Include filename longer than MAXPATHLEN chars");
2551+ return (0);
2552+ }
2553+
2554+ /* 2. must not be cutted */
2555+ if (len != strlen(filename)) {
2556+ php_security_log("Include filename has a \\0 cut");
2557+ return (0);
2558+ }
2559+
2560+ /* 3. must not be a URL */
2561+ if (strstr(filename, "://")) {
2562+ php_security_log("Include filename is an URL");
2563+ return (0);
2564+ }
2565+
2566+ /* 4. must not be an uploaded file */
2567+ if (SG(rfc1867_uploaded_files)) {
2568+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
2569+ php_security_log("Include filename is an uploaded file");
2570+ return (0);
2571+ }
2572+ }
2573+
2574+ /* passed all tests */
2575+ return (1);
2576+}
2577+
2578+#endif
2579+
2580+/*
2581+ * Local variables:
2582+ * tab-width: 4
2583+ * c-basic-offset: 4
2584+ * End:
2585+ * vim600: sw=4 ts=4 fdm=marker
2586+ * vim<600: sw=4 ts=4
2587+ */
2588diff -Nur php-5.0.4/main/hardened_php.h hardened-php-5.0.4-0.2.7/main/hardened_php.h
2589--- php-5.0.4/main/hardened_php.h 1970-01-01 01:00:00.000000000 +0100
2590+++ hardened-php-5.0.4-0.2.7/main/hardened_php.h 2005-04-07 02:05:01.000000000 +0200
2591@@ -0,0 +1,45 @@
2592+/*
2593+ +----------------------------------------------------------------------+
2594+ | Hardened-PHP |
2595+ +----------------------------------------------------------------------+
2596+ | Copyright (c) 2004 Stefan Esser |
2597+ +----------------------------------------------------------------------+
2598+ | This source file is subject to version 2.02 of the PHP license, |
2599+ | that is bundled with this package in the file LICENSE, and is |
2600+ | available at through the world-wide-web at |
2601+ | http://www.php.net/license/2_02.txt. |
2602+ | If you did not receive a copy of the PHP license and are unable to |
2603+ | obtain it through the world-wide-web, please send a note to |
2604+ | license@php.net so we can mail you a copy immediately. |
2605+ +----------------------------------------------------------------------+
2606+ | Author: Stefan Esser <sesser@php.net> |
2607+ +----------------------------------------------------------------------+
2608+ */
2609+
2610+#ifndef HARDENED_PHP_H
2611+#define HARDENED_PHP_H
2612+
2613+#include "zend.h"
2614+
2615+#if HARDENED_PHP
2616+PHPAPI void php_security_log(char *str);
2617+PHPAPI void hardened_startup();
2618+#define HARDENED_PHP_VERSION "0.2.7"
2619+#endif
2620+
2621+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2622+PHPAPI unsigned int php_canary();
2623+#endif
2624+
2625+#if HARDENED_PHP_INC_PROTECT
2626+PHPAPI int php_is_valid_include(zval *z);
2627+#endif
2628+
2629+#endif /* HARDENED_PHP_H */
2630+
2631+/*
2632+ * Local variables:
2633+ * tab-width: 4
2634+ * c-basic-offset: 4
2635+ * End:
2636+ */
2637diff -Nur php-5.0.4/main/hardened_php.m4 hardened-php-5.0.4-0.2.7/main/hardened_php.m4
2638--- php-5.0.4/main/hardened_php.m4 1970-01-01 01:00:00.000000000 +0100
2639+++ hardened-php-5.0.4-0.2.7/main/hardened_php.m4 2005-04-07 02:04:39.000000000 +0200
2640@@ -0,0 +1,95 @@
2641+dnl
2642+dnl $Id: hardened_php.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
2643+dnl
2644+dnl This file contains Hardened-PHP specific autoconf functions.
2645+dnl
2646+
2647+AC_ARG_ENABLE(hardened-php-mm-protect,
2648+[ --disable-hardened-php-mm-protect Disable the Memory Manager protection.],[
2649+ DO_HARDENED_PHP_MM_PROTECT=$enableval
2650+],[
2651+ DO_HARDENED_PHP_MM_PROTECT=yes
2652+])
2653+
2654+AC_ARG_ENABLE(hardened-php-ll-protect,
2655+[ --disable-hardened-php-ll-protect Disable the Linked List protection.],[
2656+ DO_HARDENED_PHP_LL_PROTECT=$enableval
2657+],[
2658+ DO_HARDENED_PHP_LL_PROTECT=yes
2659+])
2660+
2661+AC_ARG_ENABLE(hardened-php-inc-protect,
2662+[ --disable-hardened-php-inc-protect Disable include/require protection.],[
2663+ DO_HARDENED_PHP_INC_PROTECT=$enableval
2664+],[
2665+ DO_HARDENED_PHP_INC_PROTECT=yes
2666+])
2667+
2668+AC_ARG_ENABLE(hardened-php-fmt-protect,
2669+[ --disable-hardened-php-fmt-protect Disable format string protection.],[
2670+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
2671+],[
2672+ DO_HARDENED_PHP_FMT_PROTECT=yes
2673+])
2674+
2675+AC_ARG_ENABLE(hardened-php-hash-protect,
2676+[ --disable-hardened-php-hash-protect Disable HashTable destructor protection.],[
2677+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
2678+],[
2679+ DO_HARDENED_PHP_HASH_PROTECT=yes
2680+])
2681+
2682+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
2683+AC_MSG_RESULT($DO_HARDENED_PHP_MM_PROTECT)
2684+
2685+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
2686+AC_MSG_RESULT($DO_HARDENED_PHP_LL_PROTECT)
2687+
2688+AC_MSG_CHECKING(whether to protect include/require statements)
2689+AC_MSG_RESULT($DO_HARDENED_PHP_INC_PROTECT)
2690+
2691+AC_MSG_CHECKING(whether to protect PHP Format String functions)
2692+AC_MSG_RESULT($DO_HARDENED_PHP_FMT_PROTECT)
2693+
2694+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
2695+AC_MSG_RESULT($DO_HARDENED_PHP_HASH_PROTECT)
2696+
2697+
2698+AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2699+
2700+
2701+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
2702+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2703+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 1, [Memory Manager Protection])
2704+else
2705+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 0, [Memory Manager Protection])
2706+fi
2707+
2708+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
2709+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2710+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 1, [Linked List Protection])
2711+else
2712+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 0, [Linked List Protection])
2713+fi
2714+
2715+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
2716+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2717+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 1, [Include/Require Protection])
2718+else
2719+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 0, [Include/Require Protection])
2720+fi
2721+
2722+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
2723+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2724+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 1, [Fmt String Protection])
2725+else
2726+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 0, [Fmt String Protection])
2727+fi
2728+
2729+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
2730+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2731+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 1, [HashTable DTOR Protection])
2732+else
2733+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 0, [HashTable DTOR Protection])
2734+fi
2735+
2736diff -Nur php-5.0.4/main/main.c hardened-php-5.0.4-0.2.7/main/main.c
2737--- php-5.0.4/main/main.c 2005-03-24 02:11:35.000000000 +0100
2738+++ hardened-php-5.0.4-0.2.7/main/main.c 2005-04-07 02:04:39.000000000 +0200
2739@@ -92,6 +92,10 @@
2740
2741 #include "SAPI.h"
2742 #include "rfc1867.h"
2743+#if HARDENED_PHP
2744+#include "hardened_globals.h"
2745+#endif
2746+
2747 /* }}} */
2748
2749 #ifndef ZTS
2750@@ -116,10 +120,33 @@
2751 */
2752 static PHP_INI_MH(OnChangeMemoryLimit)
2753 {
2754+#if HARDENED_PHP
2755+ long orig_memory_limit;
2756+
2757+ if (entry->modified) {
2758+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
2759+ } else {
2760+ orig_memory_limit = 1<<30;
2761+ }
2762+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
2763+ orig_memory_limit = 1<<30;
2764+ }
2765+#endif
2766 if (new_value) {
2767 PG(memory_limit) = zend_atoi(new_value, new_value_length);
2768+#if HARDENED_PHP
2769+ if (PG(memory_limit) > orig_memory_limit) {
2770+ PG(memory_limit) = orig_memory_limit;
2771+ php_security_log("script tried to increase memory_limit above allowed value");
2772+ return FAILURE;
2773+ }
2774+#endif
2775 } else {
2776+#if HARDENED_PHP
2777+ PG(memory_limit) = orig_memory_limit;
2778+#else
2779 PG(memory_limit) = 1<<30; /* effectively, no limit */
2780+#endif
2781 }
2782 return zend_set_memory_limit(PG(memory_limit));
2783 }
2784@@ -1313,6 +1340,10 @@
2785 tsrm_ls = ts_resource(0);
2786 #endif
2787
2788+#if HARDENED_PHP
2789+ hardened_startup();
2790+#endif
2791+
2792 module_shutdown = 0;
2793 module_startup = 1;
2794 sapi_initialize_empty_request(TSRMLS_C);
2795@@ -1326,6 +1357,12 @@
2796
2797 php_output_startup();
2798
2799+#if HARDENED_PHP_INC_PROTECT
2800+ zuf.is_valid_include = php_is_valid_include;
2801+#endif
2802+#if HARDENED_PHP
2803+ zuf.security_log_function = php_security_log;
2804+#endif
2805 zuf.error_function = php_error_cb;
2806 zuf.printf_function = php_printf;
2807 zuf.write_function = php_body_write_wrapper;
2808@@ -1429,6 +1466,10 @@
2809 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
2810 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);
2811 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
2812+#if HARDENED_PHP
2813+ REGISTER_MAIN_LONG_CONSTANT("HARDENED_PHP", 1, CONST_PERSISTENT | CONST_CS);
2814+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENED_PHP_VERSION", HARDENED_PHP_VERSION, sizeof(HARDENED_PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
2815+#endif
2816 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
2817 php_output_register_constants(TSRMLS_C);
2818 php_rfc1867_register_constants(TSRMLS_C);
2819diff -Nur php-5.0.4/main/php.h hardened-php-5.0.4-0.2.7/main/php.h
2820--- php-5.0.4/main/php.h 2005-03-14 10:41:39.000000000 +0100
2821+++ hardened-php-5.0.4-0.2.7/main/php.h 2005-04-07 02:04:39.000000000 +0200
2822@@ -35,11 +35,19 @@
2823 #include "zend_qsort.h"
2824 #include "php_compat.h"
2825
2826+
2827 #include "zend_API.h"
2828
2829 #undef sprintf
2830 #define sprintf php_sprintf
2831
2832+#if HARDENED_PHP
2833+#if HAVE_REALPATH
2834+#undef realpath
2835+#define realpath php_realpath
2836+#endif
2837+#endif
2838+
2839 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
2840 #undef PHP_DEBUG
2841 #define PHP_DEBUG ZEND_DEBUG
2842@@ -341,6 +349,7 @@
2843 #define PHP_FUNCTION ZEND_FUNCTION
2844 #define PHP_METHOD ZEND_METHOD
2845
2846+#define PHP_STATIC_FE ZEND_STATIC_FE
2847 #define PHP_NAMED_FE ZEND_NAMED_FE
2848 #define PHP_FE ZEND_FE
2849 #define PHP_FALIAS ZEND_FALIAS
2850@@ -446,6 +455,10 @@
2851 #endif
2852 #endif /* !XtOffsetOf */
2853
2854+#if HARDENED_PHP
2855+#include "hardened_php.h"
2856+#endif
2857+
2858 #endif
2859
2860 /*
2861diff -Nur php-5.0.4/main/php_config.h.in hardened-php-5.0.4-0.2.7/main/php_config.h.in
2862--- php-5.0.4/main/php_config.h.in 2005-04-03 11:42:53.000000000 +0200
2863+++ hardened-php-5.0.4-0.2.7/main/php_config.h.in 2005-04-07 02:04:39.000000000 +0200
2864@@ -746,6 +746,39 @@
2865 /* hardcode for each of the cross compiler host */
2866 #undef PHP_UNAME
2867
2868+/* Hardened-PHP */
2869+#undef HARDENED_PHP
2870+
2871+/* Memory Manager Protection */
2872+#undef HARDENED_PHP_MM_PROTECT
2873+
2874+/* Memory Manager Protection */
2875+#undef HARDENED_PHP_MM_PROTECT
2876+
2877+/* Linked List Protection */
2878+#undef HARDENED_PHP_LL_PROTECT
2879+
2880+/* Linked List Protection */
2881+#undef HARDENED_PHP_LL_PROTECT
2882+
2883+/* Include/Require Protection */
2884+#undef HARDENED_PHP_INC_PROTECT
2885+
2886+/* Include/Require Protection */
2887+#undef HARDENED_PHP_INC_PROTECT
2888+
2889+/* Fmt String Protection */
2890+#undef HARDENED_PHP_FMT_PROTECT
2891+
2892+/* Fmt String Protection */
2893+#undef HARDENED_PHP_FMT_PROTECT
2894+
2895+/* HashTable DTOR Protection */
2896+#undef HARDENED_PHP_HASH_PROTECT
2897+
2898+/* HashTable DTOR Protection */
2899+#undef HARDENED_PHP_HASH_PROTECT
2900+
2901 /* Whether you have AOLserver */
2902 #undef HAVE_AOLSERVER
2903
2904@@ -1077,6 +1110,12 @@
2905 /* Define if you have the getaddrinfo function */
2906 #undef HAVE_GETADDRINFO
2907
2908+/* Whether realpath is broken */
2909+#undef PHP_BROKEN_REALPATH
2910+
2911+/* Whether realpath is broken */
2912+#undef PHP_BROKEN_REALPATH
2913+
2914 /* Whether system headers declare timezone */
2915 #undef HAVE_DECLARED_TIMEZONE
2916
2917diff -Nur php-5.0.4/main/snprintf.c hardened-php-5.0.4-0.2.7/main/snprintf.c
2918--- php-5.0.4/main/snprintf.c 2004-11-16 00:14:40.000000000 +0100
2919+++ hardened-php-5.0.4-0.2.7/main/snprintf.c 2005-04-07 02:04:39.000000000 +0200
2920@@ -1013,7 +1013,11 @@
2921
2922
2923 case 'n':
2924+#if HARDENED_PHP_FMT_PROTECT
2925+ php_security_log("'n' specifier within format string");
2926+#else
2927 *(va_arg(ap, int *)) = cc;
2928+#endif
2929 break;
2930
2931 /*
2932diff -Nur php-5.0.4/main/spprintf.c hardened-php-5.0.4-0.2.7/main/spprintf.c
2933--- php-5.0.4/main/spprintf.c 2004-04-16 01:04:49.000000000 +0200
2934+++ hardened-php-5.0.4-0.2.7/main/spprintf.c 2005-04-07 02:04:39.000000000 +0200
2935@@ -630,7 +630,11 @@
2936
2937
2938 case 'n':
2939+#if HARDENED_PHP_FMT_PROTECT
2940+ php_security_log("'n' specifier within format string");
2941+#else
2942 *(va_arg(ap, int *)) = xbuf->len;
2943+#endif
2944 break;
2945
2946 /*
2947diff -Nur php-5.0.4/php.ini-dist hardened-php-5.0.4-0.2.7/php.ini-dist
2948--- php-5.0.4/php.ini-dist 2005-03-01 01:25:09.000000000 +0100
2949+++ hardened-php-5.0.4-0.2.7/php.ini-dist 2005-04-07 02:04:39.000000000 +0200
2950@@ -1187,6 +1187,23 @@
2951 ; instead of original one.
2952 soap.wsdl_cache_ttl=86400
2953
2954+[varfilter]
2955+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2956+; Hardened-PHP's variable filter
2957+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2958+
2959+; Maximum number of input variables per request
2960+varfilter.max_request_variables = 200
2961+
2962+; Maximum characters in input variable names
2963+varfilter.max_varname_length = 64
2964+
2965+; Maximum length of input variable values
2966+varfilter.max_value_length = 10000
2967+
2968+; Maximum depth of input variable arrays
2969+varfilter.max_array_depth = 100
2970+
2971 ; Local Variables:
2972 ; tab-width: 4
2973 ; End:
2974diff -Nur php-5.0.4/php.ini-recommended hardened-php-5.0.4-0.2.7/php.ini-recommended
2975--- php-5.0.4/php.ini-recommended 2005-03-01 01:25:09.000000000 +0100
2976+++ hardened-php-5.0.4-0.2.7/php.ini-recommended 2005-04-07 02:04:39.000000000 +0200
2977@@ -1245,6 +1245,23 @@
2978 ; instead of original one.
2979 soap.wsdl_cache_ttl=86400
2980
2981+[varfilter]
2982+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2983+; Hardened-PHP's variable filter
2984+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2985+
2986+; Maximum number of input variables per request
2987+varfilter.max_request_variables = 200
2988+
2989+; Maximum characters in input variable names
2990+varfilter.max_varname_length = 64
2991+
2992+; Maximum length of input variable values
2993+varfilter.max_value_length = 10000
2994+
2995+; Maximum depth of input variable arrays
2996+varfilter.max_array_depth = 100
2997+
2998 ; Local Variables:
2999 ; tab-width: 4
3000 ; End:
3001diff -Nur php-5.0.4/sapi/apache/mod_php5.c hardened-php-5.0.4-0.2.7/sapi/apache/mod_php5.c
3002--- php-5.0.4/sapi/apache/mod_php5.c 2004-07-14 11:43:26.000000000 +0200
3003+++ hardened-php-5.0.4-0.2.7/sapi/apache/mod_php5.c 2005-04-07 02:04:39.000000000 +0200
3004@@ -447,7 +447,7 @@
3005 sapi_apache_get_fd,
3006 sapi_apache_force_http_10,
3007 sapi_apache_get_target_uid,
3008- sapi_apache_get_target_gid
3009+ sapi_apache_get_target_gid,
3010 };
3011 /* }}} */
3012
3013@@ -899,7 +899,11 @@
3014 {
3015 TSRMLS_FETCH();
3016 if (PG(expose_php)) {
3017+#if HARDENED_PHP
3018+ ap_add_version_component("Hardened-PHP/" PHP_VERSION);
3019+#else
3020 ap_add_version_component("PHP/" PHP_VERSION);
3021+#endif
3022 }
3023 }
3024 #endif
3025diff -Nur php-5.0.4/sapi/apache2filter/sapi_apache2.c hardened-php-5.0.4-0.2.7/sapi/apache2filter/sapi_apache2.c
3026--- php-5.0.4/sapi/apache2filter/sapi_apache2.c 2005-01-07 07:28:24.000000000 +0100
3027+++ hardened-php-5.0.4-0.2.7/sapi/apache2filter/sapi_apache2.c 2005-04-07 02:04:39.000000000 +0200
3028@@ -572,7 +572,11 @@
3029 {
3030 TSRMLS_FETCH();
3031 if (PG(expose_php)) {
3032+#if HARDENED_PHP
3033+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3034+#else
3035 ap_add_version_component(p, "PHP/" PHP_VERSION);
3036+#endif
3037 }
3038 }
3039
3040diff -Nur php-5.0.4/sapi/apache2handler/sapi_apache2.c hardened-php-5.0.4-0.2.7/sapi/apache2handler/sapi_apache2.c
3041--- php-5.0.4/sapi/apache2handler/sapi_apache2.c 2005-03-10 12:23:57.000000000 +0100
3042+++ hardened-php-5.0.4-0.2.7/sapi/apache2handler/sapi_apache2.c 2005-04-07 02:04:39.000000000 +0200
3043@@ -340,7 +340,11 @@
3044 {
3045 TSRMLS_FETCH();
3046 if (PG(expose_php)) {
3047+#if HARDENED_PHP
3048+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3049+#else
3050 ap_add_version_component(p, "PHP/" PHP_VERSION);
3051+#endif
3052 }
3053 }
3054
3055diff -Nur php-5.0.4/sapi/cgi/cgi_main.c hardened-php-5.0.4-0.2.7/sapi/cgi/cgi_main.c
3056--- php-5.0.4/sapi/cgi/cgi_main.c 2005-02-11 03:06:48.000000000 +0100
3057+++ hardened-php-5.0.4-0.2.7/sapi/cgi/cgi_main.c 2005-04-07 02:04:39.000000000 +0200
3058@@ -1414,11 +1414,19 @@
3059 SG(headers_sent) = 1;
3060 SG(request_info).no_headers = 1;
3061 }
3062+#if HARDENED_PHP
3063+#if ZEND_DEBUG
3064+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3065+#else
3066+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3067+#endif
3068+#else
3069 #if ZEND_DEBUG
3070 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());
3071 #else
3072 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());
3073 #endif
3074+#endif
3075 php_end_ob_buffers(1 TSRMLS_CC);
3076 exit(1);
3077 break;
3078diff -Nur php-5.0.4/sapi/cli/php_cli.c hardened-php-5.0.4-0.2.7/sapi/cli/php_cli.c
3079--- php-5.0.4/sapi/cli/php_cli.c 2005-03-22 16:09:20.000000000 +0100
3080+++ hardened-php-5.0.4-0.2.7/sapi/cli/php_cli.c 2005-04-07 02:04:39.000000000 +0200
3081@@ -694,11 +694,19 @@
3082 if (php_request_startup(TSRMLS_C)==FAILURE) {
3083 goto err;
3084 }
3085+#if HARDENED_PHP
3086+#if ZEND_DEBUG
3087+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3088+#else
3089+ php_printf("Hardened-PHP %s/%s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENED_PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
3090+#endif
3091+#else
3092 #if ZEND_DEBUG
3093 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());
3094 #else
3095 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());
3096 #endif
3097+#endif
3098 php_end_ob_buffers(1 TSRMLS_CC);
3099 exit_status=1;
3100 goto out;