summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:57:37 +0200
committerjvoisin2019-10-13 12:57:37 +0200
commit5fea1ebe59050ca0bc8de210e93e8fb4ae6cd8c8 (patch)
tree32a7da950a47305fdc5753a3eeae0b500c6b3a04
parentad5a70c7aedd0a78de0915b6434a76a4976528c0 (diff)
Add more patches
-rw-r--r--0.2.6/hardened-php-4.3.10-0.2.6.patch3408
-rw-r--r--0.4.10/hardening-patch-4.4.2-0.4.10.patch8393
-rw-r--r--0.4.13/hardening-patch-5.1.4-0.4.13.patch8620
-rw-r--r--0.4.6/hardening-patch-4.4.1-0.4.6.patch8089
-rw-r--r--0.4.9/hardening-patch-4.4.2-0.4.9.patch8369
5 files changed, 36879 insertions, 0 deletions
diff --git a/0.2.6/hardened-php-4.3.10-0.2.6.patch b/0.2.6/hardened-php-4.3.10-0.2.6.patch
new file mode 100644
index 0000000..0d12417
--- /dev/null
+++ b/0.2.6/hardened-php-4.3.10-0.2.6.patch
@@ -0,0 +1,3408 @@
1diff -Nur php-4.3.10/README.input_filter hardened-php-4.3.10-0.2.6/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.6/README.input_filter 2004-12-22 16:16:30.000000000 +0100
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.6/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.6/TSRM/TSRM.h 2004-12-22 16:16:30.000000000 +0100
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.6/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.6/TSRM/tsrm_virtual_cwd.c 2004-12-22 16:16:30.000000000 +0100
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);
422diff -Nur php-4.3.10/TSRM/tsrm_virtual_cwd.h hardened-php-4.3.10-0.2.6/TSRM/tsrm_virtual_cwd.h
423--- php-4.3.10/TSRM/tsrm_virtual_cwd.h 2003-09-20 04:08:12.000000000 +0200
424+++ hardened-php-4.3.10-0.2.6/TSRM/tsrm_virtual_cwd.h 2004-12-22 16:16:30.000000000 +0100
425@@ -128,6 +128,22 @@
426
427 typedef int (*verify_path_func)(const cwd_state *);
428
429+#ifndef HAVE_STRLCPY
430+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
431+#undef strlcpy
432+#define strlcpy php_strlcpy
433+#endif
434+
435+#ifndef HAVE_STRLCAT
436+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
437+#undef strlcat
438+#define strlcat php_strlcat
439+#endif
440+
441+
442+#if HARDENED_PHP
443+CWD_API char *php_realpath(const char *path, char *resolved);
444+#endif
445 CWD_API void virtual_cwd_startup(void);
446 CWD_API void virtual_cwd_shutdown(void);
447 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
448diff -Nur php-4.3.10/Zend/zend.c hardened-php-4.3.10-0.2.6/Zend/zend.c
449--- php-4.3.10/Zend/zend.c 2004-12-06 16:35:03.000000000 +0100
450+++ hardened-php-4.3.10-0.2.6/Zend/zend.c 2004-12-22 16:16:30.000000000 +0100
451@@ -53,6 +53,12 @@
452 ZEND_API void (*zend_unblock_interruptions)(void);
453 ZEND_API void (*zend_ticks_function)(int ticks);
454 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
455+#if HARDENED_PHP
456+ZEND_API void (*zend_security_log)(char *str);
457+#endif
458+#if HARDENED_PHP_INC_PROTECT
459+ZEND_API int (*zend_is_valid_include)(zval *z);
460+#endif
461
462 void (*zend_on_timeout)(int seconds TSRMLS_DC);
463
464@@ -424,6 +430,14 @@
465 extern zend_scanner_globals language_scanner_globals;
466 #endif
467
468+ /* Set up Hardened-PHP utility functions first */
469+#if HARDENED_PHP
470+ zend_security_log = utility_functions->security_log_function;
471+#endif
472+#if HARDENED_PHP_INC_PROTECT
473+ zend_is_valid_include = utility_functions->is_valid_include;
474+#endif
475+
476 #ifdef ZTS
477 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
478 #else
479diff -Nur php-4.3.10/Zend/zend.h hardened-php-4.3.10-0.2.6/Zend/zend.h
480--- php-4.3.10/Zend/zend.h 2004-07-28 21:06:48.000000000 +0200
481+++ hardened-php-4.3.10-0.2.6/Zend/zend.h 2004-12-22 16:31:29.000000000 +0100
482@@ -261,9 +261,9 @@
483 struct _zval_struct {
484 /* Variable information */
485 zvalue_value value; /* value */
486+ zend_uint refcount;
487 zend_uchar type; /* active type */
488 zend_uchar is_ref;
489- zend_ushort refcount;
490 };
491
492
493@@ -324,6 +324,12 @@
494 void (*ticks_function)(int ticks);
495 void (*on_timeout)(int seconds TSRMLS_DC);
496 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
497+#if HARDENED_PHP
498+ void (*security_log_function)(char *str);
499+#endif
500+#if HARDENED_PHP_INC_PROTECT
501+ int (*is_valid_include)(zval *z);
502+#endif
503 } zend_utility_functions;
504
505
506@@ -455,7 +461,16 @@
507 extern ZEND_API void (*zend_ticks_function)(int ticks);
508 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);
509 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
510+#if HARDENED_PHP
511+extern ZEND_API void (*zend_security_log)(char *str);
512+#endif
513+#if HARDENED_PHP_INC_PROTECT
514+extern ZEND_API int (*zend_is_valid_include)(zval *z);
515+#endif
516
517+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
518+ZEND_API unsigned int zend_canary(void);
519+#endif
520
521 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
522
523@@ -574,6 +589,10 @@
524 #define EMPTY_SWITCH_DEFAULT_CASE()
525 #endif
526
527+#if HARDENED_PHP
528+#include "hardened_globals.h"
529+#endif
530+
531 #endif /* ZEND_H */
532
533 /*
534diff -Nur php-4.3.10/Zend/zend_alloc.c hardened-php-4.3.10-0.2.6/Zend/zend_alloc.c
535--- php-4.3.10/Zend/zend_alloc.c 2004-08-27 18:51:25.000000000 +0200
536+++ hardened-php-4.3.10-0.2.6/Zend/zend_alloc.c 2004-12-22 16:16:30.000000000 +0100
537@@ -56,6 +56,11 @@
538 # define END_MAGIC_SIZE 0
539 #endif
540
541+#if HARDENED_PHP_MM_PROTECT
542+# define CANARY_SIZE sizeof(unsigned int)
543+#else
544+# define CANARY_SIZE 0
545+#endif
546
547 # if MEMORY_LIMIT
548 # if ZEND_DEBUG
549@@ -129,6 +134,12 @@
550 DECLARE_CACHE_VARS();
551 TSRMLS_FETCH();
552
553+#if HARDENED_PHP_MM_PROTECT
554+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
555+ zend_security_log("emalloc() - requested size would result in integer overflow");
556+ exit(1);
557+ }
558+#endif
559 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
560
561 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
562@@ -146,6 +157,10 @@
563 AG(cache_stats)[CACHE_INDEX][1]++;
564 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
565 #endif
566+#if HARDENED_PHP_MM_PROTECT
567+ p->canary = HG(canary_1);
568+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
569+#endif
570 p->cached = 0;
571 p->size = size;
572 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
573@@ -161,7 +176,7 @@
574 AG(allocated_memory_peak) = AG(allocated_memory);
575 }
576 #endif
577- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
578+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
579 }
580
581 HANDLE_BLOCK_INTERRUPTIONS();
582@@ -191,7 +206,10 @@
583 # endif
584 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
585 #endif
586-
587+#if HARDENED_PHP_MM_PROTECT
588+ p->canary = HG(canary_1);
589+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
590+#endif
591 HANDLE_UNBLOCK_INTERRUPTIONS();
592 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
593 }
594@@ -218,17 +236,33 @@
595 return emalloc_rel(lval + offset);
596 }
597 }
598-
599+
600+#if HARDENED_PHP
601+ zend_security_log("Possible integer overflow catched by safe_emalloc()");
602+#endif
603 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
604 return 0;
605 }
606
607 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
608 {
609+#if HARDENED_PHP_MM_PROTECT
610+ unsigned int *canary_2;
611+#endif
612 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
613 DECLARE_CACHE_VARS();
614 TSRMLS_FETCH();
615
616+#if HARDENED_PHP_MM_PROTECT
617+ canary_2 = (unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
618+ if (p->canary != HG(canary_1) || *canary_2 != HG(canary_2)) {
619+ zend_security_log("canary mismatch on efree() - heap overflow or double efree detected");
620+ exit(1);
621+ }
622+ /* to catch double efree()s */
623+ *canary_2 = p->canary = 0;
624+#endif
625+
626 #if defined(ZTS) && TSRM_DEBUG
627 if (p->thread_id != tsrm_thread_id()) {
628 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
629@@ -273,6 +307,9 @@
630 size_t _size = nmemb * size;
631
632 if (nmemb && (_size/nmemb!=size)) {
633+#if HARDENED_PHP
634+ zend_security_log("Possible integer overflow catched by ecalloc()");
635+#endif
636 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
637 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
638 kill(getpid(), SIGSEGV);
639@@ -292,6 +329,9 @@
640
641 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
642 {
643+#if HARDENED_PHP_MM_PROTECT
644+ unsigned int canary_2;
645+#endif
646 zend_mem_header *p;
647 zend_mem_header *orig;
648 DECLARE_CACHE_VARS();
649@@ -303,6 +343,14 @@
650
651 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
652
653+#if HARDENED_PHP_MM_PROTECT
654+ canary_2 = *(unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
655+ if (p->canary != HG(canary_1) || canary_2 != HG(canary_2)) {
656+ zend_security_log("canary mismatch on erealloc() - heap overflow detected");
657+ exit(1);
658+ }
659+#endif
660+
661 #if defined(ZTS) && TSRM_DEBUG
662 if (p->thread_id != tsrm_thread_id()) {
663 void *new_p;
664@@ -326,7 +374,7 @@
665 }
666 #endif
667 REMOVE_POINTER_FROM_LIST(p);
668- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
669+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
670 if (!p) {
671 if (!allow_failure) {
672 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
673@@ -348,6 +396,9 @@
674 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
675 #endif
676
677+#if HARDENED_PHP_MM_PROTECT
678+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
679+#endif
680 p->size = size;
681
682 HANDLE_UNBLOCK_INTERRUPTIONS();
683@@ -423,6 +474,10 @@
684 {
685 AG(head) = NULL;
686
687+#if HARDENED_PHP_MM_PROTECT
688+ HG(canary_1) = zend_canary();
689+ HG(canary_2) = zend_canary();
690+#endif
691 #if MEMORY_LIMIT
692 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
693 AG(allocated_memory) = 0;
694diff -Nur php-4.3.10/Zend/zend_alloc.h hardened-php-4.3.10-0.2.6/Zend/zend_alloc.h
695--- php-4.3.10/Zend/zend_alloc.h 2004-08-11 08:10:46.000000000 +0200
696+++ hardened-php-4.3.10-0.2.6/Zend/zend_alloc.h 2004-12-22 16:16:30.000000000 +0100
697@@ -32,6 +32,9 @@
698 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
699
700 typedef struct _zend_mem_header {
701+#if HARDENED_PHP_MM_PROTECT
702+ unsigned int canary;
703+#endif
704 #if ZEND_DEBUG
705 long magic;
706 char *filename;
707diff -Nur php-4.3.10/Zend/zend_builtin_functions.c hardened-php-4.3.10-0.2.6/Zend/zend_builtin_functions.c
708--- php-4.3.10/Zend/zend_builtin_functions.c 2004-04-01 21:05:01.000000000 +0200
709+++ hardened-php-4.3.10-0.2.6/Zend/zend_builtin_functions.c 2004-12-22 16:16:30.000000000 +0100
710@@ -49,6 +49,9 @@
711 static ZEND_FUNCTION(crash);
712 #endif
713 #endif
714+#if HARDENED_PHP_MM_PROTECT_DEBUG
715+static ZEND_FUNCTION(heap_overflow);
716+#endif
717 static ZEND_FUNCTION(get_included_files);
718 static ZEND_FUNCTION(is_subclass_of);
719 static ZEND_FUNCTION(is_a);
720@@ -101,6 +104,9 @@
721 ZEND_FE(crash, NULL)
722 #endif
723 #endif
724+#if HARDENED_PHP_MM_PROTECT_DEBUG
725+ ZEND_FE(heap_overflow, NULL)
726+#endif
727 ZEND_FE(get_included_files, NULL)
728 ZEND_FALIAS(get_required_files, get_included_files, NULL)
729 ZEND_FE(is_subclass_of, NULL)
730@@ -805,6 +811,19 @@
731
732 #endif /* ZEND_DEBUG */
733
734+
735+#if HARDENED_PHP_MM_PROTECT_DEBUG
736+ZEND_FUNCTION(heap_overflow)
737+{
738+ char *nowhere = emalloc(10);
739+
740+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
741+
742+ efree(nowhere);
743+}
744+#endif
745+
746+
747 /* {{{ proto array get_included_files(void)
748 Returns an array with the file names that were include_once()'d */
749 ZEND_FUNCTION(get_included_files)
750diff -Nur php-4.3.10/Zend/zend_canary.c hardened-php-4.3.10-0.2.6/Zend/zend_canary.c
751--- php-4.3.10/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
752+++ hardened-php-4.3.10-0.2.6/Zend/zend_canary.c 2004-12-22 16:16:30.000000000 +0100
753@@ -0,0 +1,58 @@
754+/*
755+ +----------------------------------------------------------------------+
756+ | Hardened-PHP |
757+ +----------------------------------------------------------------------+
758+ | Copyright (c) 2004 Stefan Esser |
759+ +----------------------------------------------------------------------+
760+ | This source file is subject to version 2.02 of the PHP license, |
761+ | that is bundled with this package in the file LICENSE, and is |
762+ | available at through the world-wide-web at |
763+ | http://www.php.net/license/2_02.txt. |
764+ | If you did not receive a copy of the PHP license and are unable to |
765+ | obtain it through the world-wide-web, please send a note to |
766+ | license@php.net so we can mail you a copy immediately. |
767+ +----------------------------------------------------------------------+
768+ | Author: Stefan Esser <sesser@php.net> |
769+ +----------------------------------------------------------------------+
770+ */
771+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
772+
773+#include "zend.h"
774+
775+#include <stdio.h>
776+#include <stdlib.h>
777+
778+
779+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT
780+
781+/* will be replaced later with more compatible method */
782+ZEND_API unsigned int zend_canary()
783+{
784+ time_t t;
785+ unsigned int canary;
786+ int fd;
787+
788+ fd = open("/dev/urandom", 0);
789+ if (fd != -1) {
790+ int r = read(fd, &canary, sizeof(canary));
791+ close(fd);
792+ if (r == sizeof(canary)) {
793+ return (canary);
794+ }
795+ }
796+ /* not good but we never want to do this */
797+ time(&t);
798+ canary = *(unsigned int *)&t + getpid() << 16;
799+ return (canary);
800+}
801+#endif
802+
803+
804+/*
805+ * Local variables:
806+ * tab-width: 4
807+ * c-basic-offset: 4
808+ * End:
809+ * vim600: sw=4 ts=4 fdm=marker
810+ * vim<600: sw=4 ts=4
811+ */
812diff -Nur php-4.3.10/Zend/zend_execute.c hardened-php-4.3.10-0.2.6/Zend/zend_execute.c
813--- php-4.3.10/Zend/zend_execute.c 2004-11-03 12:23:59.000000000 +0100
814+++ hardened-php-4.3.10-0.2.6/Zend/zend_execute.c 2004-12-22 16:16:30.000000000 +0100
815@@ -2149,7 +2149,12 @@
816 int dummy = 1;
817 zend_file_handle file_handle = {0};
818
819+#if HARDENED_PHP_INC_PROTECT
820+ if (zend_is_valid_include(inc_filename)
821+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
822+#else
823 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
824+#endif
825 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
826
827 file_handle.filename = inc_filename->value.str.val;
828@@ -2178,6 +2183,11 @@
829 break;
830 case ZEND_INCLUDE:
831 case ZEND_REQUIRE:
832+#if HARDENED_PHP_INC_PROTECT
833+ if (!zend_is_valid_include(inc_filename)) {
834+ break;
835+ }
836+#endif
837 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
838 break;
839 case ZEND_EVAL: {
840diff -Nur php-4.3.10/Zend/zend_extensions.h hardened-php-4.3.10-0.2.6/Zend/zend_extensions.h
841--- php-4.3.10/Zend/zend_extensions.h 2002-12-31 17:23:02.000000000 +0100
842+++ hardened-php-4.3.10-0.2.6/Zend/zend_extensions.h 2004-12-22 16:32:29.000000000 +0100
843@@ -23,7 +23,9 @@
844
845 #include "zend_compile.h"
846
847-#define ZEND_EXTENSION_API_NO 20021010
848+/* Create own API version number for Hardened-PHP */
849+
850+#define ZEND_EXTENSION_API_NO 1020041222
851
852 typedef struct _zend_extension_version_info {
853 int zend_extension_api_no;
854diff -Nur php-4.3.10/Zend/zend_hash.c hardened-php-4.3.10-0.2.6/Zend/zend_hash.c
855--- php-4.3.10/Zend/zend_hash.c 2004-07-12 23:26:46.000000000 +0200
856+++ hardened-php-4.3.10-0.2.6/Zend/zend_hash.c 2004-12-22 16:16:30.000000000 +0100
857@@ -26,6 +26,17 @@
858 # include <stdlib.h>
859 #endif
860
861+#if HARDENED_PHP_HASH_PROTECT
862+ unsigned int zend_hash_canary = 0x1234567;
863+ zend_bool zend_hash_canary_inited = 0;
864+#endif
865+
866+#define CHECK_HASH_CANARY(hash) \
867+ if (zend_hash_canary != (hash)->canary) { \
868+ zend_security_log("Zend HashTable canary was overwritten"); \
869+ exit(1); \
870+ }
871+
872 #define HANDLE_NUMERIC(key, length, func) { \
873 register char *tmp=key; \
874 \
875@@ -175,6 +186,9 @@
876 {
877 uint i = 3;
878 Bucket **tmp;
879+#if HARDENED_PHP_HASH_PROTECT
880+ TSRMLS_FETCH();
881+#endif
882
883 SET_INCONSISTENT(HT_OK);
884
885@@ -184,6 +198,13 @@
886
887 ht->nTableSize = 1 << i;
888 ht->nTableMask = ht->nTableSize - 1;
889+#if HARDENED_PHP_HASH_PROTECT
890+ if (zend_hash_canary_inited) {
891+ zend_hash_canary = zend_canary();
892+ zend_hash_canary_inited = 1;
893+ }
894+ ht->canary = zend_hash_canary;
895+#endif
896 ht->pDestructor = pDestructor;
897 ht->pListHead = NULL;
898 ht->pListTail = NULL;
899@@ -259,6 +280,9 @@
900 }
901 #endif
902 if (ht->pDestructor) {
903+#if HARDENED_PHP_HASH_PROTECT
904+ CHECK_HASH_CANARY(ht);
905+#endif
906 ht->pDestructor(p->pData);
907 }
908 UPDATE_DATA(ht, p, pData, nDataSize);
909@@ -327,6 +351,9 @@
910 }
911 #endif
912 if (ht->pDestructor) {
913+#if HARDENED_PHP_HASH_PROTECT
914+ CHECK_HASH_CANARY(ht);
915+#endif
916 ht->pDestructor(p->pData);
917 }
918 UPDATE_DATA(ht, p, pData, nDataSize);
919@@ -402,6 +429,9 @@
920 }
921 #endif
922 if (ht->pDestructor) {
923+#if HARDENED_PHP_HASH_PROTECT
924+ CHECK_HASH_CANARY(ht);
925+#endif
926 ht->pDestructor(p->pData);
927 }
928 UPDATE_DATA(ht, p, pData, nDataSize);
929@@ -450,7 +480,7 @@
930 IS_CONSISTENT(ht);
931
932 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
933- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
934+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
935 if (t) {
936 HANDLE_BLOCK_INTERRUPTIONS();
937 ht->arBuckets = t;
938@@ -460,6 +490,7 @@
939 HANDLE_UNBLOCK_INTERRUPTIONS();
940 return SUCCESS;
941 }
942+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
943 return FAILURE;
944 }
945 return SUCCESS;
946@@ -524,6 +555,9 @@
947 ht->pInternalPointer = p->pListNext;
948 }
949 if (ht->pDestructor) {
950+#if HARDENED_PHP_HASH_PROTECT
951+ CHECK_HASH_CANARY(ht);
952+#endif
953 ht->pDestructor(p->pData);
954 }
955 if (!p->pDataPtr) {
956@@ -553,6 +587,9 @@
957 q = p;
958 p = p->pListNext;
959 if (ht->pDestructor) {
960+#if HARDENED_PHP_HASH_PROTECT
961+ CHECK_HASH_CANARY(ht);
962+#endif
963 ht->pDestructor(q->pData);
964 }
965 if (!q->pDataPtr && q->pData) {
966@@ -579,6 +616,9 @@
967 q = p;
968 p = p->pListNext;
969 if (ht->pDestructor) {
970+#if HARDENED_PHP_HASH_PROTECT
971+ CHECK_HASH_CANARY(ht);
972+#endif
973 ht->pDestructor(q->pData);
974 }
975 if (!q->pDataPtr && q->pData) {
976@@ -608,6 +648,9 @@
977 HANDLE_BLOCK_INTERRUPTIONS();
978
979 if (ht->pDestructor) {
980+#if HARDENED_PHP_HASH_PROTECT
981+ CHECK_HASH_CANARY(ht);
982+#endif
983 ht->pDestructor(p->pData);
984 }
985 if (!p->pDataPtr) {
986diff -Nur php-4.3.10/Zend/zend_hash.h hardened-php-4.3.10-0.2.6/Zend/zend_hash.h
987--- php-4.3.10/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
988+++ hardened-php-4.3.10-0.2.6/Zend/zend_hash.h 2004-12-22 16:16:30.000000000 +0100
989@@ -54,6 +54,9 @@
990 } Bucket;
991
992 typedef struct _hashtable {
993+#if HARDENED_PHP_HASH_PROTECT
994+ unsigned int canary;
995+#endif
996 uint nTableSize;
997 uint nTableMask;
998 uint nNumOfElements;
999diff -Nur php-4.3.10/Zend/zend_llist.c hardened-php-4.3.10-0.2.6/Zend/zend_llist.c
1000--- php-4.3.10/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
1001+++ hardened-php-4.3.10-0.2.6/Zend/zend_llist.c 2004-12-22 16:16:30.000000000 +0100
1002@@ -21,9 +21,34 @@
1003 #include "zend.h"
1004 #include "zend_llist.h"
1005 #include "zend_qsort.h"
1006+#include "zend_globals.h"
1007+
1008+#define CHECK_LIST_CANARY(list) \
1009+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
1010+ zend_security_log("linked list canary was overwritten"); \
1011+ exit(1); \
1012+ }
1013+
1014+#define CHECK_LISTELEMENT_CANARY(elem) \
1015+ if (HG(canary_3) != (elem)->canary) { \
1016+ zend_security_log("linked list element canary was overwritten"); \
1017+ exit(1); \
1018+ }
1019+
1020
1021 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
1022 {
1023+#if HARDENED_PHP_LL_PROTECT
1024+ TSRMLS_FETCH();
1025+
1026+ if (!HG(ll_canary_inited)) {
1027+ HG(canary_3) = zend_canary();
1028+ HG(canary_4) = zend_canary();
1029+ HG(ll_canary_inited) = 1;
1030+ }
1031+ l->canary_h = HG(canary_3);
1032+ l->canary_t = HG(canary_4);
1033+#endif
1034 l->head = NULL;
1035 l->tail = NULL;
1036 l->count = 0;
1037@@ -37,6 +62,11 @@
1038 {
1039 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1040
1041+#if HARDENED_PHP_LL_PROTECT
1042+ TSRMLS_FETCH();
1043+ CHECK_LIST_CANARY(l)
1044+ tmp->canary = HG(canary_3);
1045+#endif
1046 tmp->prev = l->tail;
1047 tmp->next = NULL;
1048 if (l->tail) {
1049@@ -55,6 +85,11 @@
1050 {
1051 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
1052
1053+#if HARDENED_PHP_LL_PROTECT
1054+ TSRMLS_FETCH();
1055+ CHECK_LIST_CANARY(l)
1056+ tmp->canary = HG(canary_3);
1057+#endif
1058 tmp->next = l->head;
1059 tmp->prev = NULL;
1060 if (l->head) {
1061@@ -91,10 +126,20 @@
1062 zend_llist_element *current=l->head;
1063 zend_llist_element *next;
1064
1065+#if HARDENED_PHP_LL_PROTECT
1066+ TSRMLS_FETCH();
1067+ CHECK_LIST_CANARY(l)
1068+#endif
1069 while (current) {
1070+#if HARDENED_PHP_LL_PROTECT
1071+ CHECK_LISTELEMENT_CANARY(current)
1072+#endif
1073 next = current->next;
1074 if (compare(current->data, element)) {
1075 DEL_LLIST_ELEMENT(current, l);
1076+#if HARDENED_PHP_LL_PROTECT
1077+ current->canary = 0;
1078+#endif
1079 break;
1080 }
1081 current = next;
1082@@ -106,7 +151,14 @@
1083 {
1084 zend_llist_element *current=l->head, *next;
1085
1086+#if HARDENED_PHP_LL_PROTECT
1087+ TSRMLS_FETCH();
1088+ CHECK_LIST_CANARY(l)
1089+#endif
1090 while (current) {
1091+#if HARDENED_PHP_LL_PROTECT
1092+ CHECK_LISTELEMENT_CANARY(current)
1093+#endif
1094 next = current->next;
1095 if (l->dtor) {
1096 l->dtor(current->data);
1097@@ -131,7 +183,14 @@
1098 zend_llist_element *old_tail;
1099 void *data;
1100
1101+#if HARDENED_PHP_LL_PROTECT
1102+ TSRMLS_FETCH();
1103+ CHECK_LIST_CANARY(l)
1104+#endif
1105 if ((old_tail = l->tail)) {
1106+#if HARDENED_PHP_LL_PROTECT
1107+ CHECK_LISTELEMENT_CANARY(old_tail)
1108+#endif
1109 if (l->tail->prev) {
1110 l->tail->prev->next = NULL;
1111 }
1112@@ -157,9 +216,16 @@
1113 {
1114 zend_llist_element *ptr;
1115
1116+#if HARDENED_PHP_LL_PROTECT
1117+ TSRMLS_FETCH();
1118+ CHECK_LIST_CANARY(src)
1119+#endif
1120 zend_llist_init(dst, src->size, src->dtor, src->persistent);
1121 ptr = src->head;
1122 while (ptr) {
1123+#if HARDENED_PHP_LL_PROTECT
1124+ CHECK_LISTELEMENT_CANARY(ptr)
1125+#endif
1126 zend_llist_add_element(dst, ptr->data);
1127 ptr = ptr->next;
1128 }
1129@@ -170,11 +236,21 @@
1130 {
1131 zend_llist_element *element, *next;
1132
1133+#if HARDENED_PHP_LL_PROTECT
1134+ TSRMLS_FETCH();
1135+ CHECK_LIST_CANARY(l)
1136+#endif
1137 element=l->head;
1138 while (element) {
1139+#if HARDENED_PHP_LL_PROTECT
1140+ CHECK_LISTELEMENT_CANARY(element)
1141+#endif
1142 next = element->next;
1143 if (func(element->data)) {
1144 DEL_LLIST_ELEMENT(element, l);
1145+#if HARDENED_PHP_LL_PROTECT
1146+ element->canary = 0;
1147+#endif
1148 }
1149 element = next;
1150 }
1151@@ -185,7 +261,13 @@
1152 {
1153 zend_llist_element *element;
1154
1155+#if HARDENED_PHP_LL_PROTECT
1156+ CHECK_LIST_CANARY(l)
1157+#endif
1158 for (element=l->head; element; element=element->next) {
1159+#if HARDENED_PHP_LL_PROTECT
1160+ CHECK_LISTELEMENT_CANARY(element)
1161+#endif
1162 func(element->data TSRMLS_CC);
1163 }
1164 }
1165@@ -197,6 +279,9 @@
1166 zend_llist_element **elements;
1167 zend_llist_element *element, **ptr;
1168
1169+#if HARDENED_PHP_LL_PROTECT
1170+ CHECK_LIST_CANARY(l)
1171+#endif
1172 if (l->count <= 0) {
1173 return;
1174 }
1175@@ -206,6 +291,9 @@
1176 ptr = &elements[0];
1177
1178 for (element=l->head; element; element=element->next) {
1179+#if HARDENED_PHP_LL_PROTECT
1180+ CHECK_LISTELEMENT_CANARY(element)
1181+#endif
1182 *ptr++ = element;
1183 }
1184
1185@@ -228,7 +316,13 @@
1186 {
1187 zend_llist_element *element;
1188
1189+#if HARDENED_PHP_LL_PROTECT
1190+ CHECK_LIST_CANARY(l)
1191+#endif
1192 for (element=l->head; element; element=element->next) {
1193+#if HARDENED_PHP_LL_PROTECT
1194+ CHECK_LISTELEMENT_CANARY(element)
1195+#endif
1196 func(element->data, arg TSRMLS_CC);
1197 }
1198 }
1199@@ -239,8 +333,14 @@
1200 zend_llist_element *element;
1201 va_list args;
1202
1203+#if HARDENED_PHP_LL_PROTECT
1204+ CHECK_LIST_CANARY(l)
1205+#endif
1206 va_start(args, num_args);
1207 for (element=l->head; element; element=element->next) {
1208+#if HARDENED_PHP_LL_PROTECT
1209+ CHECK_LISTELEMENT_CANARY(element)
1210+#endif
1211 func(element->data, num_args, args TSRMLS_CC);
1212 }
1213 va_end(args);
1214@@ -249,6 +349,10 @@
1215
1216 ZEND_API int zend_llist_count(zend_llist *l)
1217 {
1218+#if HARDENED_PHP_LL_PROTECT
1219+ TSRMLS_FETCH();
1220+ CHECK_LIST_CANARY(l)
1221+#endif
1222 return l->count;
1223 }
1224
1225@@ -256,8 +360,15 @@
1226 {
1227 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1228
1229+#if HARDENED_PHP_LL_PROTECT
1230+ TSRMLS_FETCH();
1231+ CHECK_LIST_CANARY(l)
1232+#endif
1233 *current = l->head;
1234 if (*current) {
1235+#if HARDENED_PHP_LL_PROTECT
1236+ CHECK_LISTELEMENT_CANARY(*current)
1237+#endif
1238 return (*current)->data;
1239 } else {
1240 return NULL;
1241@@ -269,8 +380,15 @@
1242 {
1243 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1244
1245+#if HARDENED_PHP_LL_PROTECT
1246+ TSRMLS_FETCH();
1247+ CHECK_LIST_CANARY(l)
1248+#endif
1249 *current = l->tail;
1250 if (*current) {
1251+#if HARDENED_PHP_LL_PROTECT
1252+ CHECK_LISTELEMENT_CANARY(*current)
1253+#endif
1254 return (*current)->data;
1255 } else {
1256 return NULL;
1257@@ -282,9 +400,19 @@
1258 {
1259 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1260
1261+#if HARDENED_PHP_LL_PROTECT
1262+ TSRMLS_FETCH();
1263+ CHECK_LIST_CANARY(l)
1264+#endif
1265 if (*current) {
1266+#if HARDENED_PHP_LL_PROTECT
1267+ CHECK_LISTELEMENT_CANARY(*current)
1268+#endif
1269 *current = (*current)->next;
1270 if (*current) {
1271+#if HARDENED_PHP_LL_PROTECT
1272+ CHECK_LISTELEMENT_CANARY(*current)
1273+#endif
1274 return (*current)->data;
1275 }
1276 }
1277@@ -296,9 +424,19 @@
1278 {
1279 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
1280
1281+#if HARDENED_PHP_LL_PROTECT
1282+ TSRMLS_FETCH();
1283+ CHECK_LIST_CANARY(l)
1284+#endif
1285 if (*current) {
1286+#if HARDENED_PHP_LL_PROTECT
1287+ CHECK_LISTELEMENT_CANARY(*current)
1288+#endif
1289 *current = (*current)->prev;
1290 if (*current) {
1291+#if HARDENED_PHP_LL_PROTECT
1292+ CHECK_LISTELEMENT_CANARY(*current)
1293+#endif
1294 return (*current)->data;
1295 }
1296 }
1297diff -Nur php-4.3.10/Zend/zend_llist.h hardened-php-4.3.10-0.2.6/Zend/zend_llist.h
1298--- php-4.3.10/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
1299+++ hardened-php-4.3.10-0.2.6/Zend/zend_llist.h 2004-12-22 16:16:30.000000000 +0100
1300@@ -24,6 +24,9 @@
1301 #include <stdlib.h>
1302
1303 typedef struct _zend_llist_element {
1304+#if HARDENED_PHP_LL_PROTECT
1305+ unsigned int canary;
1306+#endif
1307 struct _zend_llist_element *next;
1308 struct _zend_llist_element *prev;
1309 char data[1]; /* Needs to always be last in the struct */
1310@@ -36,6 +39,9 @@
1311 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
1312
1313 typedef struct _zend_llist {
1314+#if HARDENED_PHP_LL_PROTECT
1315+ unsigned int canary_h; /* head */
1316+#endif
1317 zend_llist_element *head;
1318 zend_llist_element *tail;
1319 size_t size;
1320@@ -43,6 +49,9 @@
1321 llist_dtor_func_t dtor;
1322 unsigned char persistent;
1323 zend_llist_element *traverse_ptr;
1324+#if HARDENED_PHP_LL_PROTECT
1325+ unsigned int canary_t; /* tail */
1326+#endif
1327 } zend_llist;
1328
1329 typedef zend_llist_element* zend_llist_position;
1330diff -Nur php-4.3.10/Zend/zend_modules.h hardened-php-4.3.10-0.2.6/Zend/zend_modules.h
1331--- php-4.3.10/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
1332+++ hardened-php-4.3.10-0.2.6/Zend/zend_modules.h 2004-12-22 17:33:47.000000000 +0100
1333@@ -34,7 +34,7 @@
1334 ZEND_API extern unsigned char second_arg_force_ref[];
1335 ZEND_API extern unsigned char third_arg_force_ref[];
1336
1337-#define ZEND_MODULE_API_NO 20020429
1338+#define ZEND_MODULE_API_NO 1020041222
1339 #ifdef ZTS
1340 #define USING_ZTS 1
1341 #else
1342diff -Nur php-4.3.10/acinclude.m4 hardened-php-4.3.10-0.2.6/acinclude.m4
1343--- php-4.3.10/acinclude.m4 2004-12-11 12:17:21.000000000 +0100
1344+++ hardened-php-4.3.10-0.2.6/acinclude.m4 2004-12-22 16:16:30.000000000 +0100
1345@@ -1153,6 +1153,36 @@
1346 fi
1347 ])
1348
1349+dnl
1350+dnl Check for broken realpath()
1351+dnl
1352+dnl realpath("/etc/hosts/../passwd",XXX) should not return
1353+dnl "/etc/passwd"
1354+dnl
1355+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
1356+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
1357+ AC_TRY_RUN([
1358+main() {
1359+ char buf[4096+1];
1360+ buf[0] = 0;
1361+ realpath("/etc/hosts/../passwd", buf);
1362+ exit(strcmp(buf, "/etc/passwd")==0);
1363+}
1364+ ],[
1365+ ac_cv_broken_realpath=no
1366+ ],[
1367+ ac_cv_broken_realpath=yes
1368+ ],[
1369+ ac_cv_broken_realpath=no
1370+ ])
1371+ ])
1372+ if test "$ac_cv_broken_realpath" = "yes"; then
1373+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
1374+ else
1375+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
1376+ fi
1377+])
1378+
1379 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
1380 dnl
1381 dnl Basically sets up the link-stage for building module-name
1382diff -Nur php-4.3.10/configure hardened-php-4.3.10-0.2.6/configure
1383--- php-4.3.10/configure 2004-12-14 18:55:18.000000000 +0100
1384+++ hardened-php-4.3.10-0.2.6/configure 2004-12-22 16:16:31.000000000 +0100
1385@@ -389,6 +389,16 @@
1386 ac_default_prefix=/usr/local
1387 # Any additions from configure.in:
1388 ac_help="$ac_help
1389+ --disable-hardened-php-mm-protect Disable the Memory Manager protection."
1390+ac_help="$ac_help
1391+ --disable-hardened-php-ll-protect Disable the Linked List protection."
1392+ac_help="$ac_help
1393+ --disable-hardened-php-inc-protect Disable include/require protection."
1394+ac_help="$ac_help
1395+ --disable-hardened-php-fmt-protect Disable format string protection."
1396+ac_help="$ac_help
1397+ --disable-hardened-php-hash-protect Disable Zend HashTable DTOR protection."
1398+ac_help="$ac_help
1399
1400 SAPI modules:
1401 "
1402@@ -831,6 +841,8 @@
1403 ac_help="$ac_help
1404 --disable-tokenizer Disable tokenizer support"
1405 ac_help="$ac_help
1406+ --disable-varfilter Disable Hardened-PHP's variable filter"
1407+ac_help="$ac_help
1408 --enable-wddx Enable WDDX support."
1409 ac_help="$ac_help
1410 --disable-xml Disable XML support using bundled expat lib"
1411@@ -2643,6 +2655,157 @@
1412
1413
1414
1415+# Check whether --enable-hardened-php-mm-protect or --disable-hardened-php-mm-protect was given.
1416+if test "${enable_hardened_php_mm_protect+set}" = set; then
1417+ enableval="$enable_hardened_php_mm_protect"
1418+
1419+ DO_HARDENED_PHP_MM_PROTECT=$enableval
1420+
1421+else
1422+
1423+ DO_HARDENED_PHP_MM_PROTECT=yes
1424+
1425+fi
1426+
1427+
1428+# Check whether --enable-hardened-php-ll-protect or --disable-hardened-php-ll-protect was given.
1429+if test "${enable_hardened_php_ll_protect+set}" = set; then
1430+ enableval="$enable_hardened_php_ll_protect"
1431+
1432+ DO_HARDENED_PHP_LL_PROTECT=$enableval
1433+
1434+else
1435+
1436+ DO_HARDENED_PHP_LL_PROTECT=yes
1437+
1438+fi
1439+
1440+
1441+# Check whether --enable-hardened-php-inc-protect or --disable-hardened-php-inc-protect was given.
1442+if test "${enable_hardened_php_inc_protect+set}" = set; then
1443+ enableval="$enable_hardened_php_inc_protect"
1444+
1445+ DO_HARDENED_PHP_INC_PROTECT=$enableval
1446+
1447+else
1448+
1449+ DO_HARDENED_PHP_INC_PROTECT=yes
1450+
1451+fi
1452+
1453+
1454+# Check whether --enable-hardened-php-fmt-protect or --disable-hardened-php-fmt-protect was given.
1455+if test "${enable_hardened_php_fmt_protect+set}" = set; then
1456+ enableval="$enable_hardened_php_fmt_protect"
1457+
1458+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
1459+
1460+else
1461+
1462+ DO_HARDENED_PHP_FMT_PROTECT=yes
1463+
1464+fi
1465+
1466+
1467+# Check whether --enable-hardened-php-hash-protect or --disable-hardened-php-hash-protect was given.
1468+if test "${enable_hardened_php_hash_protect+set}" = set; then
1469+ enableval="$enable_hardened_php_hash_protect"
1470+
1471+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
1472+
1473+else
1474+
1475+ DO_HARDENED_PHP_HASH_PROTECT=yes
1476+
1477+fi
1478+
1479+
1480+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
1481+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
1482+echo "$ac_t""$DO_HARDENED_PHP_MM_PROTECT" 1>&6
1483+
1484+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
1485+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
1486+echo "$ac_t""$DO_HARDENED_PHP_LL_PROTECT" 1>&6
1487+
1488+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
1489+echo "configure:2733: checking whether to protect include/require statements" >&5
1490+echo "$ac_t""$DO_HARDENED_PHP_INC_PROTECT" 1>&6
1491+
1492+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
1493+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
1494+echo "$ac_t""$DO_HARDENED_PHP_FMT_PROTECT" 1>&6
1495+
1496+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
1497+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
1498+echo "$ac_t""$DO_HARDENED_PHP_HASH_PROTECT" 1>&6
1499+
1500+
1501+cat >> confdefs.h <<\EOF
1502+#define HARDENED_PHP 1
1503+EOF
1504+
1505+
1506+
1507+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
1508+ cat >> confdefs.h <<\EOF
1509+#define HARDENED_PHP_MM_PROTECT 1
1510+EOF
1511+
1512+else
1513+ cat >> confdefs.h <<\EOF
1514+#define HARDENED_PHP_MM_PROTECT 0
1515+EOF
1516+
1517+fi
1518+
1519+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
1520+ cat >> confdefs.h <<\EOF
1521+#define HARDENED_PHP_LL_PROTECT 1
1522+EOF
1523+
1524+else
1525+ cat >> confdefs.h <<\EOF
1526+#define HARDENED_PHP_LL_PROTECT 0
1527+EOF
1528+
1529+fi
1530+
1531+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
1532+ cat >> confdefs.h <<\EOF
1533+#define HARDENED_PHP_INC_PROTECT 1
1534+EOF
1535+
1536+else
1537+ cat >> confdefs.h <<\EOF
1538+#define HARDENED_PHP_INC_PROTECT 0
1539+EOF
1540+
1541+fi
1542+
1543+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
1544+ cat >> confdefs.h <<\EOF
1545+#define HARDENED_PHP_FMT_PROTECT 1
1546+EOF
1547+
1548+else
1549+ cat >> confdefs.h <<\EOF
1550+#define HARDENED_PHP_FMT_PROTECT 0
1551+EOF
1552+
1553+fi
1554+
1555+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
1556+ cat >> confdefs.h <<\EOF
1557+#define HARDENED_PHP_HASH_PROTECT 1
1558+EOF
1559+
1560+else
1561+ cat >> confdefs.h <<\EOF
1562+#define HARDENED_PHP_HASH_PROTECT 0
1563+EOF
1564+
1565+fi
1566
1567
1568
1569@@ -14890,6 +15053,62 @@
1570 fi
1571
1572
1573+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
1574+echo "configure:14928: checking whether realpath is broken" >&5
1575+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
1576+ echo $ac_n "(cached) $ac_c" 1>&6
1577+else
1578+
1579+ if test "$cross_compiling" = yes; then
1580+
1581+ ac_cv_broken_realpath=no
1582+
1583+else
1584+ cat > conftest.$ac_ext <<EOF
1585+#line 14939 "configure"
1586+#include "confdefs.h"
1587+
1588+main() {
1589+ char buf[4096+1];
1590+ buf[0] = 0;
1591+ realpath("/etc/hosts/../passwd", buf);
1592+ exit(strcmp(buf, "/etc/passwd")==0);
1593+}
1594+
1595+EOF
1596+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
1597+then
1598+
1599+ ac_cv_broken_realpath=no
1600+
1601+else
1602+ echo "configure: failed program was:" >&5
1603+ cat conftest.$ac_ext >&5
1604+ rm -fr conftest*
1605+
1606+ ac_cv_broken_realpath=yes
1607+
1608+fi
1609+rm -fr conftest*
1610+fi
1611+
1612+
1613+fi
1614+
1615+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
1616+ if test "$ac_cv_broken_realpath" = "yes"; then
1617+ cat >> confdefs.h <<\EOF
1618+#define PHP_BROKEN_REALPATH 1
1619+EOF
1620+
1621+ else
1622+ cat >> confdefs.h <<\EOF
1623+#define PHP_BROKEN_REALPATH 0
1624+EOF
1625+
1626+ fi
1627+
1628+
1629 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
1630 echo "configure:14895: checking for declared timezone" >&5
1631 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
1632@@ -82014,6 +82233,265 @@
1633 fi
1634
1635
1636+echo $ac_n "checking whether to enable Hardened-PHP's variable filter""... $ac_c" 1>&6
1637+echo "configure:82041: checking whether to enable Hardened-PHP's variable filter" >&5
1638+# Check whether --enable-varfilter or --disable-varfilter was given.
1639+if test "${enable_varfilter+set}" = set; then
1640+ enableval="$enable_varfilter"
1641+ PHP_VARFILTER=$enableval
1642+else
1643+
1644+ PHP_VARFILTER=yes
1645+
1646+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
1647+ PHP_VARFILTER=$PHP_ENABLE_ALL
1648+ fi
1649+
1650+fi
1651+
1652+
1653+
1654+ext_output="yes, shared"
1655+ext_shared=yes
1656+case $PHP_VARFILTER in
1657+shared,*)
1658+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
1659+ ;;
1660+shared)
1661+ PHP_VARFILTER=yes
1662+ ;;
1663+no)
1664+ ext_output=no
1665+ ext_shared=no
1666+ ;;
1667+*)
1668+ ext_output=yes
1669+ ext_shared=no
1670+ ;;
1671+esac
1672+
1673+
1674+
1675+echo "$ac_t""$ext_output" 1>&6
1676+
1677+
1678+
1679+
1680+if test "$PHP_VARFILTER" != "no"; then
1681+ cat >> confdefs.h <<\EOF
1682+#define HAVE_VARFILTER 1
1683+EOF
1684+
1685+
1686+ ext_builddir=ext/varfilter
1687+ ext_srcdir=$abs_srcdir/ext/varfilter
1688+
1689+ ac_extra=
1690+
1691+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
1692+
1693+
1694+
1695+ case ext/varfilter in
1696+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1697+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1698+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1699+ esac
1700+
1701+
1702+
1703+ b_c_pre=$php_c_pre
1704+ b_cxx_pre=$php_cxx_pre
1705+ b_c_meta=$php_c_meta
1706+ b_cxx_meta=$php_cxx_meta
1707+ b_c_post=$php_c_post
1708+ b_cxx_post=$php_cxx_post
1709+ b_lo=$php_lo
1710+
1711+
1712+ old_IFS=$IFS
1713+ for ac_src in varfilter.c; do
1714+
1715+ IFS=.
1716+ set $ac_src
1717+ ac_obj=$1
1718+ IFS=$old_IFS
1719+
1720+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1721+
1722+ case $ac_src in
1723+ *.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" ;;
1724+ *.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" ;;
1725+ esac
1726+
1727+ cat >>Makefile.objects<<EOF
1728+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1729+ $ac_comp
1730+EOF
1731+ done
1732+
1733+
1734+ EXT_STATIC="$EXT_STATIC varfilter"
1735+ if test "$ext_shared" != "nocli"; then
1736+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1737+ fi
1738+ else
1739+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
1740+
1741+ case ext/varfilter in
1742+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1743+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1744+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1745+ esac
1746+
1747+
1748+
1749+ b_c_pre=$shared_c_pre
1750+ b_cxx_pre=$shared_cxx_pre
1751+ b_c_meta=$shared_c_meta
1752+ b_cxx_meta=$shared_cxx_meta
1753+ b_c_post=$shared_c_post
1754+ b_cxx_post=$shared_cxx_post
1755+ b_lo=$shared_lo
1756+
1757+
1758+ old_IFS=$IFS
1759+ for ac_src in varfilter.c; do
1760+
1761+ IFS=.
1762+ set $ac_src
1763+ ac_obj=$1
1764+ IFS=$old_IFS
1765+
1766+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
1767+
1768+ case $ac_src in
1769+ *.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" ;;
1770+ *.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" ;;
1771+ esac
1772+
1773+ cat >>Makefile.objects<<EOF
1774+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1775+ $ac_comp
1776+EOF
1777+ done
1778+
1779+
1780+ install_modules="install-modules"
1781+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
1782+
1783+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
1784+
1785+ cat >>Makefile.objects<<EOF
1786+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
1787+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
1788+
1789+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
1790+ \$(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)
1791+
1792+EOF
1793+
1794+ cat >> confdefs.h <<EOF
1795+#define COMPILE_DL_VARFILTER 1
1796+EOF
1797+
1798+ fi
1799+ fi
1800+
1801+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
1802+ if test "$PHP_SAPI" = "cgi"; then
1803+
1804+
1805+ case ext/varfilter in
1806+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1807+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1808+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1809+ esac
1810+
1811+
1812+
1813+ b_c_pre=$php_c_pre
1814+ b_cxx_pre=$php_cxx_pre
1815+ b_c_meta=$php_c_meta
1816+ b_cxx_meta=$php_cxx_meta
1817+ b_c_post=$php_c_post
1818+ b_cxx_post=$php_cxx_post
1819+ b_lo=$php_lo
1820+
1821+
1822+ old_IFS=$IFS
1823+ for ac_src in varfilter.c; do
1824+
1825+ IFS=.
1826+ set $ac_src
1827+ ac_obj=$1
1828+ IFS=$old_IFS
1829+
1830+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
1831+
1832+ case $ac_src in
1833+ *.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" ;;
1834+ *.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" ;;
1835+ esac
1836+
1837+ cat >>Makefile.objects<<EOF
1838+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1839+ $ac_comp
1840+EOF
1841+ done
1842+
1843+
1844+ EXT_STATIC="$EXT_STATIC varfilter"
1845+ else
1846+
1847+
1848+ case ext/varfilter in
1849+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
1850+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
1851+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
1852+ esac
1853+
1854+
1855+
1856+ b_c_pre=$php_c_pre
1857+ b_cxx_pre=$php_cxx_pre
1858+ b_c_meta=$php_c_meta
1859+ b_cxx_meta=$php_cxx_meta
1860+ b_c_post=$php_c_post
1861+ b_cxx_post=$php_cxx_post
1862+ b_lo=$php_lo
1863+
1864+
1865+ old_IFS=$IFS
1866+ for ac_src in varfilter.c; do
1867+
1868+ IFS=.
1869+ set $ac_src
1870+ ac_obj=$1
1871+ IFS=$old_IFS
1872+
1873+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
1874+
1875+ case $ac_src in
1876+ *.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" ;;
1877+ *.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" ;;
1878+ esac
1879+
1880+ cat >>Makefile.objects<<EOF
1881+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
1882+ $ac_comp
1883+EOF
1884+ done
1885+
1886+
1887+ fi
1888+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
1889+ fi
1890+
1891+ BUILD_DIR="$BUILD_DIR $ext_builddir"
1892+
1893+
1894+fi
1895
1896
1897 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
1898@@ -94503,7 +94981,7 @@
1899 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1900 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1901 streams.c network.c php_open_temporary_file.c php_logos.c \
1902- output.c memory_streams.c user_streams.c; do
1903+ output.c memory_streams.c user_streams.c hardened_php.c; do
1904
1905 IFS=.
1906 set $ac_src
1907@@ -94676,7 +95154,7 @@
1908 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1909 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1910 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1911- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
1912+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
1913
1914 IFS=.
1915 set $ac_src
1916diff -Nur php-4.3.10/configure.in hardened-php-4.3.10-0.2.6/configure.in
1917--- php-4.3.10/configure.in 2004-12-14 17:07:49.000000000 +0100
1918+++ hardened-php-4.3.10-0.2.6/configure.in 2004-12-22 16:16:31.000000000 +0100
1919@@ -205,7 +205,7 @@
1920 sinclude(Zend/acinclude.m4)
1921 sinclude(Zend/Zend.m4)
1922 sinclude(TSRM/tsrm.m4)
1923-
1924+sinclude(main/hardened_php.m4)
1925
1926
1927 divert(2)
1928@@ -573,6 +573,7 @@
1929 AC_FUNC_ALLOCA
1930 dnl PHP_AC_BROKEN_SPRINTF
1931 dnl PHP_AC_BROKEN_SNPRINTF
1932+PHP_AC_BROKEN_REALPATH
1933 PHP_DECLARED_TIMEZONE
1934 PHP_TIME_R_TYPE
1935 PHP_READDIR_R_TYPE
1936@@ -1201,7 +1202,7 @@
1937 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
1938 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
1939 streams.c network.c php_open_temporary_file.c php_logos.c \
1940- output.c memory_streams.c user_streams.c)
1941+ output.c memory_streams.c user_streams.c hardened_php.c)
1942 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
1943 PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
1944
1945@@ -1214,7 +1215,7 @@
1946 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
1947 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
1948 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
1949- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
1950+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
1951
1952 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
1953 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
1954diff -Nur php-4.3.10/ext/mbstring/mbstring.c hardened-php-4.3.10-0.2.6/ext/mbstring/mbstring.c
1955--- php-4.3.10/ext/mbstring/mbstring.c 2004-06-24 00:07:01.000000000 +0200
1956+++ hardened-php-4.3.10-0.2.6/ext/mbstring/mbstring.c 2004-12-22 16:16:31.000000000 +0100
1957@@ -1467,12 +1467,13 @@
1958
1959 /* {{{ static void php_mbstr_encoding_handler() */
1960 static void
1961-php_mbstr_encoding_handler(zval *arg, char *res, char *separator TSRMLS_DC)
1962+php_mbstr_encoding_handler(zval *arg, int parse_type, char *res, char *separator TSRMLS_DC)
1963 {
1964 char *var, *val, *s1, *s2;
1965 char *strtok_buf = NULL, **val_list;
1966 zval *array_ptr = (zval *) arg;
1967 int n, num, val_len, *len_list, elistsz;
1968+ unsigned int new_val_len;
1969 enum mbfl_no_encoding from_encoding, to_encoding, *elist;
1970 mbfl_string string, resvar, resval;
1971 mbfl_encoding_detector *identd = NULL;
1972@@ -1593,8 +1594,14 @@
1973 val_len = len_list[n];
1974 }
1975 n++;
1976- /* add variable to symbol table */
1977- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
1978+ /* we need val to be emalloc()ed */
1979+ val = estrndup(val, val_len);
1980+ if (sapi_module.input_filter(parse_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
1981+ /* add variable to symbol table */
1982+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
1983+ }
1984+ efree(val);
1985+
1986 if (convd != NULL){
1987 mbfl_string_clear(&resvar);
1988 mbfl_string_clear(&resval);
1989@@ -1620,7 +1627,7 @@
1990 {
1991 MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
1992
1993- php_mbstr_encoding_handler(arg, SG(request_info).post_data, "&" TSRMLS_CC);
1994+ php_mbstr_encoding_handler(arg, PARSE_POST, SG(request_info).post_data, "&" TSRMLS_CC);
1995
1996 if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid) {
1997 MBSTRG(http_input_identify_post) = MBSTRG(http_input_identify);
1998@@ -1720,7 +1727,7 @@
1999 break;
2000 }
2001
2002- php_mbstr_encoding_handler(array_ptr, res, separator TSRMLS_CC);
2003+ php_mbstr_encoding_handler(array_ptr, arg, res, separator TSRMLS_CC);
2004
2005 if (MBSTRG(http_input_identify) != mbfl_no_encoding_invalid) {
2006 switch(arg){
2007diff -Nur php-4.3.10/ext/standard/array.c hardened-php-4.3.10-0.2.6/ext/standard/array.c
2008--- php-4.3.10/ext/standard/array.c 2004-12-02 17:36:41.000000000 +0100
2009+++ hardened-php-4.3.10-0.2.6/ext/standard/array.c 2004-12-22 16:16:31.000000000 +0100
2010@@ -1153,6 +1153,31 @@
2011 }
2012 }
2013 }
2014+
2015+ if (var_name[0] == 'H') {
2016+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
2017+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
2018+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
2019+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
2020+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
2021+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
2022+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)) {
2023+ return 0;
2024+ }
2025+ } else if (var_name[0] == '_') {
2026+ if ((strcmp(var_name, "_COOKIE")==0)||
2027+ (strcmp(var_name, "_ENV")==0)||
2028+ (strcmp(var_name, "_FILES")==0)||
2029+ (strcmp(var_name, "_GET")==0)||
2030+ (strcmp(var_name, "_POST")==0)||
2031+ (strcmp(var_name, "_REQUEST")==0)||
2032+ (strcmp(var_name, "_SESSION")==0)||
2033+ (strcmp(var_name, "_SERVER")==0)) {
2034+ return 0;
2035+ }
2036+ } else if (strcmp(var_name, "GLOBALS")==0) {
2037+ return 0;
2038+ }
2039
2040 return 1;
2041 }
2042diff -Nur php-4.3.10/ext/standard/basic_functions.c hardened-php-4.3.10-0.2.6/ext/standard/basic_functions.c
2043--- php-4.3.10/ext/standard/basic_functions.c 2004-11-16 00:26:40.000000000 +0100
2044+++ hardened-php-4.3.10-0.2.6/ext/standard/basic_functions.c 2004-12-22 16:16:31.000000000 +0100
2045@@ -687,7 +687,7 @@
2046 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
2047
2048 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2049- PHP_FE(realpath, NULL)
2050+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
2051 #endif
2052
2053 #ifdef HAVE_FNMATCH
2054@@ -3008,6 +3008,34 @@
2055 memcpy(new_key, prefix, prefix_len);
2056 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
2057
2058+ if (new_key[0] == 'H') {
2059+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
2060+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
2061+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
2062+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
2063+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
2064+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
2065+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)) {
2066+ efree(new_key);
2067+ return 0;
2068+ }
2069+ } else if (new_key[0] == '_') {
2070+ if ((strcmp(new_key, "_COOKIE")==0)||
2071+ (strcmp(new_key, "_ENV")==0)||
2072+ (strcmp(new_key, "_FILES")==0)||
2073+ (strcmp(new_key, "_GET")==0)||
2074+ (strcmp(new_key, "_POST")==0)||
2075+ (strcmp(new_key, "_REQUEST")==0)||
2076+ (strcmp(new_key, "_SESSION")==0)||
2077+ (strcmp(new_key, "_SERVER")==0)) {
2078+ efree(new_key);
2079+ return 0;
2080+ }
2081+ } else if (strcmp(new_key, "GLOBALS")==0) {
2082+ efree(new_key);
2083+ return 0;
2084+ }
2085+
2086 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
2087 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
2088
2089diff -Nur php-4.3.10/ext/standard/file.c hardened-php-4.3.10-0.2.6/ext/standard/file.c
2090--- php-4.3.10/ext/standard/file.c 2004-12-08 22:15:02.000000000 +0100
2091+++ hardened-php-4.3.10-0.2.6/ext/standard/file.c 2004-12-22 16:16:31.000000000 +0100
2092@@ -2472,7 +2472,7 @@
2093 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2094 /* {{{ proto string realpath(string path)
2095 Return the resolved path */
2096-PHP_FUNCTION(realpath)
2097+PHP_FUNCTION(real_path)
2098 {
2099 zval **path;
2100 char resolved_path_buff[MAXPATHLEN];
2101diff -Nur php-4.3.10/ext/standard/file.h hardened-php-4.3.10-0.2.6/ext/standard/file.h
2102--- php-4.3.10/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
2103+++ hardened-php-4.3.10-0.2.6/ext/standard/file.h 2004-12-22 16:16:31.000000000 +0100
2104@@ -64,7 +64,7 @@
2105 PHP_FUNCTION(fd_set);
2106 PHP_FUNCTION(fd_isset);
2107 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2108-PHP_FUNCTION(realpath);
2109+PHP_FUNCTION(real_path);
2110 #endif
2111 #ifdef HAVE_FNMATCH
2112 PHP_FUNCTION(fnmatch);
2113diff -Nur php-4.3.10/ext/standard/info.c hardened-php-4.3.10-0.2.6/ext/standard/info.c
2114--- php-4.3.10/ext/standard/info.c 2004-06-09 17:10:19.000000000 +0200
2115+++ hardened-php-4.3.10-0.2.6/ext/standard/info.c 2004-12-22 17:33:18.000000000 +0100
2116@@ -397,7 +397,7 @@
2117
2118 if (flag & PHP_INFO_GENERAL) {
2119 char *zend_version = get_zend_version();
2120- char temp_api[9];
2121+ char temp_api[11];
2122
2123 php_uname = php_get_uname('a');
2124
2125@@ -417,11 +417,22 @@
2126 }
2127 }
2128
2129+#if HARDENED_PHP
2130+ if (!sapi_module.phpinfo_as_text) {
2131+ php_printf("<h1 class=\"p\">Hardened-PHP Version %s/%s</h1>\n", PHP_VERSION, HARDENED_PHP_VERSION);
2132+ } else {
2133+ char temp_ver[40];
2134+
2135+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENED_PHP_VERSION);
2136+ php_info_print_table_row(2, "Hardened-PHP Version", temp_ver);
2137+ }
2138+#else
2139 if (!sapi_module.phpinfo_as_text) {
2140 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2141 } else {
2142 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2143 }
2144+#endif
2145 php_info_print_box_end();
2146 php_info_print_table_start();
2147 php_info_print_table_row(2, "System", php_uname );
2148diff -Nur php-4.3.10/ext/varfilter/CREDITS hardened-php-4.3.10-0.2.6/ext/varfilter/CREDITS
2149--- php-4.3.10/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2150+++ hardened-php-4.3.10-0.2.6/ext/varfilter/CREDITS 2004-12-22 16:16:31.000000000 +0100
2151@@ -0,0 +1,2 @@
2152+varfilter
2153+Stefan Esser
2154\ No newline at end of file
2155diff -Nur php-4.3.10/ext/varfilter/config.m4 hardened-php-4.3.10-0.2.6/ext/varfilter/config.m4
2156--- php-4.3.10/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2157+++ hardened-php-4.3.10-0.2.6/ext/varfilter/config.m4 2004-12-22 16:16:31.000000000 +0100
2158@@ -0,0 +1,11 @@
2159+dnl
2160+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2161+dnl
2162+
2163+PHP_ARG_ENABLE(varfilter, whether to enable Hardened-PHP's variable filter,
2164+[ --disable-varfilter Disable Hardened-PHP's variable filter], yes)
2165+
2166+if test "$PHP_VARFILTER" != "no"; then
2167+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2168+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2169+fi
2170diff -Nur php-4.3.10/ext/varfilter/php_varfilter.h hardened-php-4.3.10-0.2.6/ext/varfilter/php_varfilter.h
2171--- php-4.3.10/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2172+++ hardened-php-4.3.10-0.2.6/ext/varfilter/php_varfilter.h 2004-12-22 16:16:31.000000000 +0100
2173@@ -0,0 +1,72 @@
2174+/*
2175+ +----------------------------------------------------------------------+
2176+ | PHP Version 4 |
2177+ +----------------------------------------------------------------------+
2178+ | Copyright (c) 1997-2003 The PHP Group |
2179+ +----------------------------------------------------------------------+
2180+ | This source file is subject to version 2.02 of the PHP license, |
2181+ | that is bundled with this package in the file LICENSE, and is |
2182+ | available at through the world-wide-web at |
2183+ | http://www.php.net/license/2_02.txt. |
2184+ | If you did not receive a copy of the PHP license and are unable to |
2185+ | obtain it through the world-wide-web, please send a note to |
2186+ | license@php.net so we can mail you a copy immediately. |
2187+ +----------------------------------------------------------------------+
2188+ | Author: Stefan Esser |
2189+ +----------------------------------------------------------------------+
2190+
2191+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2192+*/
2193+
2194+#ifndef PHP_VARFILTER_H
2195+#define PHP_VARFILTER_H
2196+
2197+extern zend_module_entry varfilter_module_entry;
2198+#define phpext_varfilter_ptr &varfilter_module_entry
2199+
2200+#ifdef PHP_WIN32
2201+#define PHP_VARFILTER_API __declspec(dllexport)
2202+#else
2203+#define PHP_VARFILTER_API
2204+#endif
2205+
2206+#ifdef ZTS
2207+#include "TSRM.h"
2208+#endif
2209+
2210+#include "SAPI.h"
2211+
2212+PHP_MINIT_FUNCTION(varfilter);
2213+PHP_MSHUTDOWN_FUNCTION(varfilter);
2214+PHP_RINIT_FUNCTION(varfilter);
2215+PHP_RSHUTDOWN_FUNCTION(varfilter);
2216+PHP_MINFO_FUNCTION(varfilter);
2217+
2218+
2219+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2220+ long max_request_variables;
2221+ long cur_request_variables;
2222+ long max_varname_length;
2223+ long max_value_length;
2224+ long max_array_depth;
2225+ZEND_END_MODULE_GLOBALS(varfilter)
2226+
2227+
2228+#ifdef ZTS
2229+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2230+#else
2231+#define VARFILTER_G(v) (varfilter_globals.v)
2232+#endif
2233+
2234+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2235+
2236+#endif /* PHP_VARFILTER_H */
2237+
2238+
2239+/*
2240+ * Local variables:
2241+ * tab-width: 4
2242+ * c-basic-offset: 4
2243+ * indent-tabs-mode: t
2244+ * End:
2245+ */
2246diff -Nur php-4.3.10/ext/varfilter/varfilter.c hardened-php-4.3.10-0.2.6/ext/varfilter/varfilter.c
2247--- php-4.3.10/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2248+++ hardened-php-4.3.10-0.2.6/ext/varfilter/varfilter.c 2004-12-22 16:16:31.000000000 +0100
2249@@ -0,0 +1,196 @@
2250+/*
2251+ +----------------------------------------------------------------------+
2252+ | PHP Version 4 |
2253+ +----------------------------------------------------------------------+
2254+ | Copyright (c) 1997-2003 The PHP Group |
2255+ +----------------------------------------------------------------------+
2256+ | This source file is subject to version 2.02 of the PHP license, |
2257+ | that is bundled with this package in the file LICENSE, and is |
2258+ | available at through the world-wide-web at |
2259+ | http://www.php.net/license/2_02.txt. |
2260+ | If you did not receive a copy of the PHP license and are unable to |
2261+ | obtain it through the world-wide-web, please send a note to |
2262+ | license@php.net so we can mail you a copy immediately. |
2263+ +----------------------------------------------------------------------+
2264+ | Author: |
2265+ +----------------------------------------------------------------------+
2266+
2267+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2268+*/
2269+
2270+#ifdef HAVE_CONFIG_H
2271+#include "config.h"
2272+#endif
2273+
2274+#include "php.h"
2275+#include "php_ini.h"
2276+#include "ext/standard/info.h"
2277+#include "php_varfilter.h"
2278+#include "hardened_php.h"
2279+
2280+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2281+
2282+/* True global resources - no need for thread safety here */
2283+static int le_varfilter;
2284+
2285+/* {{{ varfilter_module_entry
2286+ */
2287+zend_module_entry varfilter_module_entry = {
2288+#if ZEND_MODULE_API_NO >= 20010901
2289+ STANDARD_MODULE_HEADER,
2290+#endif
2291+ "varfilter",
2292+ NULL,
2293+ PHP_MINIT(varfilter),
2294+ PHP_MSHUTDOWN(varfilter),
2295+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2296+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2297+ PHP_MINFO(varfilter),
2298+#if ZEND_MODULE_API_NO >= 20010901
2299+ "0.2.0", /* Replace with version number for your extension */
2300+#endif
2301+ STANDARD_MODULE_PROPERTIES
2302+};
2303+/* }}} */
2304+
2305+#ifdef COMPILE_DL_VARFILTER
2306+ZEND_GET_MODULE(varfilter)
2307+#endif
2308+
2309+/* {{{ PHP_INI
2310+ */
2311+PHP_INI_BEGIN()
2312+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_SYSTEM, OnUpdateInt, max_request_variables, zend_varfilter_globals, varfilter_globals)
2313+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_SYSTEM, OnUpdateInt, max_varname_length, zend_varfilter_globals, varfilter_globals)
2314+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "10000", PHP_INI_SYSTEM, OnUpdateInt, max_value_length, zend_varfilter_globals, varfilter_globals)
2315+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_SYSTEM, OnUpdateInt, max_array_depth, zend_varfilter_globals, varfilter_globals)
2316+PHP_INI_END()
2317+/* }}} */
2318+
2319+/* {{{ php_varfilter_init_globals
2320+ */
2321+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2322+{
2323+ varfilter_globals->max_request_variables = 200;
2324+ varfilter_globals->cur_request_variables = 0;
2325+ varfilter_globals->max_varname_length = 64;
2326+ varfilter_globals->max_value_length = 10000;
2327+ varfilter_globals->max_array_depth = 100;
2328+}
2329+/* }}} */
2330+
2331+/* {{{ PHP_MINIT_FUNCTION
2332+ */
2333+PHP_MINIT_FUNCTION(varfilter)
2334+{
2335+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2336+ REGISTER_INI_ENTRIES();
2337+
2338+ sapi_register_input_filter(varfilter_input_filter);
2339+ return SUCCESS;
2340+}
2341+/* }}} */
2342+
2343+/* {{{ PHP_MSHUTDOWN_FUNCTION
2344+ */
2345+PHP_MSHUTDOWN_FUNCTION(varfilter)
2346+{
2347+ UNREGISTER_INI_ENTRIES();
2348+
2349+ return SUCCESS;
2350+}
2351+/* }}} */
2352+
2353+/* Remove if there's nothing to do at request start */
2354+/* {{{ PHP_RINIT_FUNCTION
2355+ */
2356+PHP_RINIT_FUNCTION(varfilter)
2357+{
2358+ VARFILTER_G(cur_request_variables) = 0;
2359+
2360+ return SUCCESS;
2361+}
2362+/* }}} */
2363+
2364+/* Remove if there's nothing to do at request end */
2365+/* {{{ PHP_RSHUTDOWN_FUNCTION
2366+ */
2367+PHP_RSHUTDOWN_FUNCTION(varfilter)
2368+{
2369+ return SUCCESS;
2370+}
2371+/* }}} */
2372+
2373+/* {{{ PHP_MINFO_FUNCTION
2374+ */
2375+PHP_MINFO_FUNCTION(varfilter)
2376+{
2377+ php_info_print_table_start();
2378+ php_info_print_table_header(2, "Hardened-PHP's variable filter support", "enabled");
2379+ php_info_print_table_end();
2380+
2381+ DISPLAY_INI_ENTRIES();
2382+}
2383+/* }}} */
2384+
2385+/* {{{ SAPI_INPUT_FILTER_FUNC
2386+ */
2387+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
2388+{
2389+ char *index;
2390+ unsigned int var_len, depth = 0;
2391+
2392+ /* Drop this variable if the limit is reached */
2393+ if (VARFILTER_G(max_request_variables) == VARFILTER_G(cur_request_variables)) {
2394+ php_security_log("tried to register too many variables");
2395+ return 0;
2396+ }
2397+
2398+ /* Drop this variable if it exceeds the value length limit */
2399+ if (VARFILTER_G(max_value_length) < val_len) {
2400+ php_security_log("tried to register a variable with a too long value");
2401+ return 0;
2402+ }
2403+
2404+ /* Find length of variable name */
2405+ index = strchr(var, '[');
2406+ var_len = index ? index-var : strlen(var);
2407+
2408+ /* Drop this variable if it exceeds the varname length limit */
2409+ if (VARFILTER_G(max_varname_length) < var_len) {
2410+ php_security_log("tried to register a variable with a too long variable name");
2411+ return 0;
2412+ }
2413+
2414+ /* Find out array depth */
2415+ while (index) {
2416+ depth++;
2417+ index = strchr(index+1, '[');
2418+ }
2419+
2420+ /* Drop this variable if it exceeds the array depth limit */
2421+ if (VARFILTER_G(max_array_depth) < depth) {
2422+ php_security_log("tried to register a too deep array variable");
2423+ return 0;
2424+ }
2425+
2426+ /* Okay let PHP register this variable */
2427+ VARFILTER_G(cur_request_variables)++;
2428+
2429+ if (new_val_len) {
2430+ *new_val_len = val_len;
2431+ }
2432+
2433+ return 1;
2434+}
2435+/* }}} */
2436+
2437+
2438+/*
2439+ * Local variables:
2440+ * tab-width: 4
2441+ * c-basic-offset: 4
2442+ * End:
2443+ * vim600: noet sw=4 ts=4 fdm=marker
2444+ * vim<600: noet sw=4 ts=4
2445+ */
2446diff -Nur php-4.3.10/main/SAPI.c hardened-php-4.3.10-0.2.6/main/SAPI.c
2447--- php-4.3.10/main/SAPI.c 2004-08-19 22:35:36.000000000 +0200
2448+++ hardened-php-4.3.10-0.2.6/main/SAPI.c 2004-12-22 16:16:31.000000000 +0100
2449@@ -823,6 +823,12 @@
2450 return SUCCESS;
2451 }
2452
2453+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))
2454+{
2455+ sapi_module.input_filter = input_filter;
2456+ return SUCCESS;
2457+}
2458+
2459
2460 SAPI_API int sapi_flush(TSRMLS_D)
2461 {
2462diff -Nur php-4.3.10/main/SAPI.h hardened-php-4.3.10-0.2.6/main/SAPI.h
2463--- php-4.3.10/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
2464+++ hardened-php-4.3.10-0.2.6/main/SAPI.h 2004-12-22 16:16:31.000000000 +0100
2465@@ -101,9 +101,14 @@
2466 char *current_user;
2467 int current_user_length;
2468
2469- /* this is necessary for CLI module */
2470- int argc;
2471- char **argv;
2472+ /* this is necessary for CLI module */
2473+ int argc;
2474+ char **argv;
2475+
2476+#if HARDENED_PHP
2477+ /* this is necessary for IP logging */
2478+ char ip_address[64];
2479+#endif
2480 } sapi_request_info;
2481
2482
2483@@ -177,6 +182,7 @@
2484 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
2485 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
2486 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
2487+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));
2488
2489 SAPI_API int sapi_flush(TSRMLS_D);
2490 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
2491@@ -238,8 +244,11 @@
2492 int (*get_target_uid)(uid_t * TSRMLS_DC);
2493 int (*get_target_gid)(gid_t * TSRMLS_DC);
2494
2495+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
2496+
2497 void (*ini_defaults)(HashTable *configuration_hash);
2498 int phpinfo_as_text;
2499+
2500 };
2501
2502
2503@@ -262,16 +271,23 @@
2504
2505 #define SAPI_DEFAULT_MIMETYPE "text/html"
2506 #define SAPI_DEFAULT_CHARSET ""
2507+
2508+#if HARDENED_PHP
2509+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: Hardened-PHP/" PHP_VERSION
2510+#else
2511 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
2512+#endif
2513
2514 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
2515 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
2516
2517 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
2518+#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)
2519
2520 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
2521 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
2522 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
2523+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
2524
2525 #define STANDARD_SAPI_MODULE_PROPERTIES
2526
2527diff -Nur php-4.3.10/main/hardened_globals.h hardened-php-4.3.10-0.2.6/main/hardened_globals.h
2528--- php-4.3.10/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
2529+++ hardened-php-4.3.10-0.2.6/main/hardened_globals.h 2004-12-22 16:16:31.000000000 +0100
2530@@ -0,0 +1,54 @@
2531+/*
2532+ +----------------------------------------------------------------------+
2533+ | Hardened-PHP |
2534+ +----------------------------------------------------------------------+
2535+ | Copyright (c) 2004 Stefan Esser |
2536+ +----------------------------------------------------------------------+
2537+ | This source file is subject to version 2.02 of the PHP license, |
2538+ | that is bundled with this package in the file LICENSE, and is |
2539+ | available at through the world-wide-web at |
2540+ | http://www.php.net/license/2_02.txt. |
2541+ | If you did not receive a copy of the PHP license and are unable to |
2542+ | obtain it through the world-wide-web, please send a note to |
2543+ | license@php.net so we can mail you a copy immediately. |
2544+ +----------------------------------------------------------------------+
2545+ | Author: Stefan Esser <sesser@php.net> |
2546+ +----------------------------------------------------------------------+
2547+ */
2548+
2549+#ifndef HARDENED_GLOBALS_H
2550+#define HARDENED_GLOBALS_H
2551+
2552+typedef struct _hardened_globals hardened_globals_struct;
2553+
2554+#ifdef ZTS
2555+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
2556+extern int hardened_globals_id;
2557+#else
2558+# define HG(v) (hardened_globals.v)
2559+extern struct _hardened_globals hardened_globals;
2560+#endif
2561+
2562+
2563+struct _hardened_globals {
2564+#if HARDENED_PHP_MM_PROTECT
2565+ unsigned int canary_1;
2566+ unsigned int canary_2;
2567+#endif
2568+#if HARDENED_PHP_LL_PROTECT
2569+ unsigned int canary_3;
2570+ unsigned int canary_4;
2571+ unsigned int ll_canary_inited;
2572+#endif
2573+ unsigned int dummy;
2574+};
2575+
2576+
2577+#endif /* HARDENED_GLOBALS_H */
2578+
2579+/*
2580+ * Local variables:
2581+ * tab-width: 4
2582+ * c-basic-offset: 4
2583+ * End:
2584+ */
2585diff -Nur php-4.3.10/main/hardened_php.c hardened-php-4.3.10-0.2.6/main/hardened_php.c
2586--- php-4.3.10/main/hardened_php.c 1970-01-01 01:00:00.000000000 +0100
2587+++ hardened-php-4.3.10-0.2.6/main/hardened_php.c 2004-12-22 16:33:57.000000000 +0100
2588@@ -0,0 +1,205 @@
2589+/*
2590+ +----------------------------------------------------------------------+
2591+ | Hardened-PHP |
2592+ +----------------------------------------------------------------------+
2593+ | Copyright (c) 2004 Stefan Esser |
2594+ +----------------------------------------------------------------------+
2595+ | This source file is subject to version 2.02 of the PHP license, |
2596+ | that is bundled with this package in the file LICENSE, and is |
2597+ | available at through the world-wide-web at |
2598+ | http://www.php.net/license/2_02.txt. |
2599+ | If you did not receive a copy of the PHP license and are unable to |
2600+ | obtain it through the world-wide-web, please send a note to |
2601+ | license@php.net so we can mail you a copy immediately. |
2602+ +----------------------------------------------------------------------+
2603+ | Author: Stefan Esser <sesser@php.net> |
2604+ +----------------------------------------------------------------------+
2605+ */
2606+/* $Id: hardened_php.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
2607+
2608+#include "php.h"
2609+
2610+#include <stdio.h>
2611+#include <stdlib.h>
2612+
2613+#if HAVE_UNISTD_H
2614+#include <unistd.h>
2615+#endif
2616+#include "SAPI.h"
2617+#include "php_globals.h"
2618+
2619+#if HARDENED_PHP
2620+
2621+#ifdef HAVE_SYS_SOCKET_H
2622+#include <sys/socket.h>
2623+#endif
2624+
2625+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
2626+#undef AF_UNIX
2627+#endif
2628+
2629+#if defined(AF_UNIX)
2630+#include <sys/un.h>
2631+#endif
2632+
2633+#define SYSLOG_PATH "/dev/log"
2634+
2635+#include "snprintf.h"
2636+
2637+#ifdef ZTS
2638+#include "hardened_globals.h"
2639+int hardened_globals_id;
2640+#else
2641+struct _hardened_globals hardened_globals;
2642+#endif
2643+
2644+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
2645+{
2646+ memset(hardened_globals, 0, sizeof(*hardened_globals));
2647+}
2648+
2649+PHPAPI void hardened_startup()
2650+{
2651+#ifdef ZTS
2652+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
2653+#else
2654+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
2655+#endif
2656+}
2657+
2658+PHPAPI void php_security_log(char *str)
2659+{
2660+#if defined(AF_UNIX)
2661+ int s, r;
2662+ struct sockaddr_un saun;
2663+ char buf[1024];
2664+ char *ip_address;
2665+ char *fname;
2666+ TSRMLS_FETCH();
2667+
2668+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
2669+ if (ip_address == NULL) {
2670+ ip_address = "REMOTE_ADDR not set";
2671+ }
2672+
2673+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
2674+
2675+ ap_php_snprintf(buf, 1024, "php security-alert: %s (attacker '%s', file '%s')\n", str, ip_address, fname);
2676+
2677+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
2678+ if (s == -1) {
2679+ return;
2680+ }
2681+
2682+ memset(&saun, 0, sizeof(saun));
2683+ saun.sun_family = AF_UNIX;
2684+ strcpy(saun.sun_path, SYSLOG_PATH);
2685+ /*saun.sun_len = sizeof(saun);*/
2686+
2687+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2688+ if (r) {
2689+ close(s);
2690+ s = socket(AF_UNIX, SOCK_STREAM, 0);
2691+ if (s == -1) {
2692+ return;
2693+ }
2694+
2695+ memset(&saun, 0, sizeof(saun));
2696+ saun.sun_family = AF_UNIX;
2697+ strcpy(saun.sun_path, SYSLOG_PATH);
2698+ /*saun.sun_len = sizeof(saun);*/
2699+
2700+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
2701+ if (r) {
2702+ close(s);
2703+ return;
2704+ }
2705+ }
2706+ send(s, buf, strlen(buf), 0);
2707+
2708+ close(s);
2709+#endif
2710+}
2711+#endif
2712+
2713+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2714+
2715+/* will be replaced later with more compatible method */
2716+PHPAPI unsigned int php_canary()
2717+{
2718+ time_t t;
2719+ unsigned int canary;
2720+ int fd;
2721+
2722+ fd = open("/dev/urandom", 0);
2723+ if (fd != -1) {
2724+ int r = read(fd, &canary, sizeof(canary));
2725+ close(fd);
2726+ if (r == sizeof(canary)) {
2727+ return (canary);
2728+ }
2729+ }
2730+ /* not good but we never want to do this */
2731+ time(&t);
2732+ canary = *(unsigned int *)&t + getpid() << 16;
2733+ return (canary);
2734+}
2735+#endif
2736+
2737+#if HARDENED_PHP_INC_PROTECT
2738+
2739+PHPAPI int php_is_valid_include(zval *z)
2740+{
2741+ char *filename;
2742+ int len;
2743+ TSRMLS_FETCH();
2744+
2745+ /* must be of type string */
2746+ if (z->type != IS_STRING || z->value.str.val == NULL) {
2747+ return (0);
2748+ }
2749+
2750+ /* short cut */
2751+ filename = z->value.str.val;
2752+ len = z->value.str.len;
2753+
2754+ /* 1. must be shorter than MAXPATHLEN */
2755+ if (len > MAXPATHLEN) {
2756+ php_security_log("Include filename longer than MAXPATHLEN chars");
2757+ return (0);
2758+ }
2759+
2760+ /* 2. must not be cutted */
2761+ if (len != strlen(filename)) {
2762+ php_security_log("Include filename has a \\0 cut");
2763+ return (0);
2764+ }
2765+
2766+ /* 3. must not be a URL */
2767+ if (strstr(filename, "://")) {
2768+ php_security_log("Include filename is an URL");
2769+ return (0);
2770+ }
2771+
2772+ /* 4. must not be an uploaded file */
2773+ if (SG(rfc1867_uploaded_files)) {
2774+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
2775+ php_security_log("Include filename is an uploaded file");
2776+ return (0);
2777+ }
2778+ }
2779+
2780+ /* passed all tests */
2781+ return (1);
2782+}
2783+
2784+#endif
2785+
2786+/*
2787+ * Local variables:
2788+ * tab-width: 4
2789+ * c-basic-offset: 4
2790+ * End:
2791+ * vim600: sw=4 ts=4 fdm=marker
2792+ * vim<600: sw=4 ts=4
2793+ */
2794diff -Nur php-4.3.10/main/hardened_php.h hardened-php-4.3.10-0.2.6/main/hardened_php.h
2795--- php-4.3.10/main/hardened_php.h 1970-01-01 01:00:00.000000000 +0100
2796+++ hardened-php-4.3.10-0.2.6/main/hardened_php.h 2004-12-22 16:32:48.000000000 +0100
2797@@ -0,0 +1,45 @@
2798+/*
2799+ +----------------------------------------------------------------------+
2800+ | Hardened-PHP |
2801+ +----------------------------------------------------------------------+
2802+ | Copyright (c) 2004 Stefan Esser |
2803+ +----------------------------------------------------------------------+
2804+ | This source file is subject to version 2.02 of the PHP license, |
2805+ | that is bundled with this package in the file LICENSE, and is |
2806+ | available at through the world-wide-web at |
2807+ | http://www.php.net/license/2_02.txt. |
2808+ | If you did not receive a copy of the PHP license and are unable to |
2809+ | obtain it through the world-wide-web, please send a note to |
2810+ | license@php.net so we can mail you a copy immediately. |
2811+ +----------------------------------------------------------------------+
2812+ | Author: Stefan Esser <sesser@php.net> |
2813+ +----------------------------------------------------------------------+
2814+ */
2815+
2816+#ifndef HARDENED_PHP_H
2817+#define HARDENED_PHP_H
2818+
2819+#include "zend.h"
2820+
2821+#if HARDENED_PHP
2822+PHPAPI void php_security_log(char *str);
2823+PHPAPI void hardened_startup();
2824+#define HARDENED_PHP_VERSION "0.2.6"
2825+#endif
2826+
2827+#if HARDENED_PHP_MM_PROTECT || HARDENED_PHP_LL_PROTECT || HARDENED_PHP_HASH_PROTECT
2828+PHPAPI unsigned int php_canary();
2829+#endif
2830+
2831+#if HARDENED_PHP_INC_PROTECT
2832+PHPAPI int php_is_valid_include(zval *z);
2833+#endif
2834+
2835+#endif /* HARDENED_PHP_H */
2836+
2837+/*
2838+ * Local variables:
2839+ * tab-width: 4
2840+ * c-basic-offset: 4
2841+ * End:
2842+ */
2843diff -Nur php-4.3.10/main/hardened_php.m4 hardened-php-4.3.10-0.2.6/main/hardened_php.m4
2844--- php-4.3.10/main/hardened_php.m4 1970-01-01 01:00:00.000000000 +0100
2845+++ hardened-php-4.3.10-0.2.6/main/hardened_php.m4 2004-12-22 16:16:31.000000000 +0100
2846@@ -0,0 +1,95 @@
2847+dnl
2848+dnl $Id: hardened_php.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
2849+dnl
2850+dnl This file contains Hardened-PHP specific autoconf functions.
2851+dnl
2852+
2853+AC_ARG_ENABLE(hardened-php-mm-protect,
2854+[ --disable-hardened-php-mm-protect Disable the Memory Manager protection.],[
2855+ DO_HARDENED_PHP_MM_PROTECT=$enableval
2856+],[
2857+ DO_HARDENED_PHP_MM_PROTECT=yes
2858+])
2859+
2860+AC_ARG_ENABLE(hardened-php-ll-protect,
2861+[ --disable-hardened-php-ll-protect Disable the Linked List protection.],[
2862+ DO_HARDENED_PHP_LL_PROTECT=$enableval
2863+],[
2864+ DO_HARDENED_PHP_LL_PROTECT=yes
2865+])
2866+
2867+AC_ARG_ENABLE(hardened-php-inc-protect,
2868+[ --disable-hardened-php-inc-protect Disable include/require protection.],[
2869+ DO_HARDENED_PHP_INC_PROTECT=$enableval
2870+],[
2871+ DO_HARDENED_PHP_INC_PROTECT=yes
2872+])
2873+
2874+AC_ARG_ENABLE(hardened-php-fmt-protect,
2875+[ --disable-hardened-php-fmt-protect Disable format string protection.],[
2876+ DO_HARDENED_PHP_FMT_PROTECT=$enableval
2877+],[
2878+ DO_HARDENED_PHP_FMT_PROTECT=yes
2879+])
2880+
2881+AC_ARG_ENABLE(hardened-php-hash-protect,
2882+[ --disable-hardened-php-hash-protect Disable HashTable destructor protection.],[
2883+ DO_HARDENED_PHP_HASH_PROTECT=$enableval
2884+],[
2885+ DO_HARDENED_PHP_HASH_PROTECT=yes
2886+])
2887+
2888+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
2889+AC_MSG_RESULT($DO_HARDENED_PHP_MM_PROTECT)
2890+
2891+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
2892+AC_MSG_RESULT($DO_HARDENED_PHP_LL_PROTECT)
2893+
2894+AC_MSG_CHECKING(whether to protect include/require statements)
2895+AC_MSG_RESULT($DO_HARDENED_PHP_INC_PROTECT)
2896+
2897+AC_MSG_CHECKING(whether to protect PHP Format String functions)
2898+AC_MSG_RESULT($DO_HARDENED_PHP_FMT_PROTECT)
2899+
2900+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
2901+AC_MSG_RESULT($DO_HARDENED_PHP_HASH_PROTECT)
2902+
2903+
2904+AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2905+
2906+
2907+if test "$DO_HARDENED_PHP_MM_PROTECT" = "yes"; then
2908+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2909+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 1, [Memory Manager Protection])
2910+else
2911+ AC_DEFINE(HARDENED_PHP_MM_PROTECT, 0, [Memory Manager Protection])
2912+fi
2913+
2914+if test "$DO_HARDENED_PHP_LL_PROTECT" = "yes"; then
2915+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2916+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 1, [Linked List Protection])
2917+else
2918+ AC_DEFINE(HARDENED_PHP_LL_PROTECT, 0, [Linked List Protection])
2919+fi
2920+
2921+if test "$DO_HARDENED_PHP_INC_PROTECT" = "yes"; then
2922+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2923+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 1, [Include/Require Protection])
2924+else
2925+ AC_DEFINE(HARDENED_PHP_INC_PROTECT, 0, [Include/Require Protection])
2926+fi
2927+
2928+if test "$DO_HARDENED_PHP_FMT_PROTECT" = "yes"; then
2929+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2930+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 1, [Fmt String Protection])
2931+else
2932+ AC_DEFINE(HARDENED_PHP_FMT_PROTECT, 0, [Fmt String Protection])
2933+fi
2934+
2935+if test "$DO_HARDENED_PHP_HASH_PROTECT" = "yes"; then
2936+dnl AC_DEFINE(HARDENED_PHP, 1, [Hardened-PHP])
2937+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 1, [HashTable DTOR Protection])
2938+else
2939+ AC_DEFINE(HARDENED_PHP_HASH_PROTECT, 0, [HashTable DTOR Protection])
2940+fi
2941+
2942diff -Nur php-4.3.10/main/main.c hardened-php-4.3.10-0.2.6/main/main.c
2943--- php-4.3.10/main/main.c 2004-10-01 16:27:13.000000000 +0200
2944+++ hardened-php-4.3.10-0.2.6/main/main.c 2004-12-22 16:16:31.000000000 +0100
2945@@ -100,6 +100,10 @@
2946 PHPAPI int core_globals_id;
2947 #endif
2948
2949+#if HARDENED_PHP
2950+#include "hardened_globals.h"
2951+#endif
2952+
2953 #define ERROR_BUF_LEN 1024
2954
2955 typedef struct {
2956@@ -150,10 +154,33 @@
2957 */
2958 static PHP_INI_MH(OnChangeMemoryLimit)
2959 {
2960+#if HARDENED_PHP
2961+ long orig_memory_limit;
2962+
2963+ if (entry->modified) {
2964+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
2965+ } else {
2966+ orig_memory_limit = 1<<30;
2967+ }
2968+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
2969+ orig_memory_limit = 1<<30;
2970+ }
2971+#endif
2972 if (new_value) {
2973 PG(memory_limit) = zend_atoi(new_value, new_value_length);
2974+#if HARDENED_PHP
2975+ if (PG(memory_limit) > orig_memory_limit) {
2976+ PG(memory_limit) = orig_memory_limit;
2977+ php_security_log("script tried to increase memory_limit above allowed value");
2978+ return FAILURE;
2979+ }
2980+#endif
2981 } else {
2982+#if HARDENED_PHP
2983+ PG(memory_limit) = orig_memory_limit;
2984+#else
2985 PG(memory_limit) = 1<<30; /* effectively, no limit */
2986+#endif
2987 }
2988 return zend_set_memory_limit(PG(memory_limit));
2989 }
2990@@ -1091,6 +1118,10 @@
2991 tsrm_ls = ts_resource(0);
2992 #endif
2993
2994+#if HARDENED_PHP
2995+ hardened_startup();
2996+#endif
2997+
2998 sapi_initialize_empty_request(TSRMLS_C);
2999 sapi_activate(TSRMLS_C);
3000
3001@@ -1103,6 +1134,12 @@
3002 php_output_startup();
3003 php_output_activate(TSRMLS_C);
3004
3005+#if HARDENED_PHP_INC_PROTECT
3006+ zuf.is_valid_include = php_is_valid_include;
3007+#endif
3008+#if HARDENED_PHP
3009+ zuf.security_log_function = php_security_log;
3010+#endif
3011 zuf.error_function = php_error_cb;
3012 zuf.printf_function = php_printf;
3013 zuf.write_function = php_body_write_wrapper;
3014@@ -1204,6 +1241,10 @@
3015 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
3016 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);
3017 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
3018+#if HARDENED_PHP
3019+ REGISTER_MAIN_LONG_CONSTANT("HARDENED_PHP", 1, CONST_PERSISTENT | CONST_CS);
3020+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENED_PHP_VERSION", HARDENED_PHP_VERSION, sizeof(HARDENED_PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
3021+#endif
3022 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
3023 php_output_register_constants(TSRMLS_C);
3024 php_rfc1867_register_constants(TSRMLS_C);
3025diff -Nur php-4.3.10/main/php.h hardened-php-4.3.10-0.2.6/main/php.h
3026--- php-4.3.10/main/php.h 2004-11-28 13:44:56.000000000 +0100
3027+++ hardened-php-4.3.10-0.2.6/main/php.h 2004-12-22 16:16:31.000000000 +0100
3028@@ -35,11 +35,19 @@
3029 #include "zend_qsort.h"
3030 #include "php_compat.h"
3031
3032+
3033 #include "zend_API.h"
3034
3035 #undef sprintf
3036 #define sprintf php_sprintf
3037
3038+#if HARDENED_PHP
3039+#if HAVE_REALPATH
3040+#undef realpath
3041+#define realpath php_realpath
3042+#endif
3043+#endif
3044+
3045 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
3046 #undef PHP_DEBUG
3047 #define PHP_DEBUG ZEND_DEBUG
3048@@ -436,6 +444,10 @@
3049 #endif
3050 #endif /* !XtOffsetOf */
3051
3052+#if HARDENED_PHP
3053+#include "hardened_php.h"
3054+#endif
3055+
3056 #endif
3057
3058 /*
3059diff -Nur php-4.3.10/main/php_config.h.in hardened-php-4.3.10-0.2.6/main/php_config.h.in
3060--- php-4.3.10/main/php_config.h.in 2004-12-14 18:55:22.000000000 +0100
3061+++ hardened-php-4.3.10-0.2.6/main/php_config.h.in 2004-12-22 16:16:31.000000000 +0100
3062@@ -834,6 +834,39 @@
3063 /* Enabling BIND8 compatibility for Panther */
3064 #undef BIND_8_COMPAT
3065
3066+/* Hardened-PHP */
3067+#undef HARDENED_PHP
3068+
3069+/* Memory Manager Protection */
3070+#undef HARDENED_PHP_MM_PROTECT
3071+
3072+/* Memory Manager Protection */
3073+#undef HARDENED_PHP_MM_PROTECT
3074+
3075+/* Linked List Protection */
3076+#undef HARDENED_PHP_LL_PROTECT
3077+
3078+/* Linked List Protection */
3079+#undef HARDENED_PHP_LL_PROTECT
3080+
3081+/* Include/Require Protection */
3082+#undef HARDENED_PHP_INC_PROTECT
3083+
3084+/* Include/Require Protection */
3085+#undef HARDENED_PHP_INC_PROTECT
3086+
3087+/* Fmt String Protection */
3088+#undef HARDENED_PHP_FMT_PROTECT
3089+
3090+/* Fmt String Protection */
3091+#undef HARDENED_PHP_FMT_PROTECT
3092+
3093+/* HashTable DTOR Protection */
3094+#undef HARDENED_PHP_HASH_PROTECT
3095+
3096+/* HashTable DTOR Protection */
3097+#undef HARDENED_PHP_HASH_PROTECT
3098+
3099 /* Whether you have AOLserver */
3100 #undef HAVE_AOLSERVER
3101
3102@@ -1117,6 +1150,12 @@
3103 /* Define if you have the getaddrinfo function */
3104 #undef HAVE_GETADDRINFO
3105
3106+/* Whether realpath is broken */
3107+#undef PHP_BROKEN_REALPATH
3108+
3109+/* Whether realpath is broken */
3110+#undef PHP_BROKEN_REALPATH
3111+
3112 /* Whether system headers declare timezone */
3113 #undef HAVE_DECLARED_TIMEZONE
3114
3115diff -Nur php-4.3.10/main/php_content_types.c hardened-php-4.3.10-0.2.6/main/php_content_types.c
3116--- php-4.3.10/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
3117+++ hardened-php-4.3.10-0.2.6/main/php_content_types.c 2004-12-22 16:16:31.000000000 +0100
3118@@ -77,6 +77,7 @@
3119 sapi_register_post_entries(php_post_entries);
3120 sapi_register_default_post_reader(php_default_post_reader);
3121 sapi_register_treat_data(php_default_treat_data);
3122+ sapi_register_input_filter(php_default_input_filter);
3123 return SUCCESS;
3124 }
3125 /* }}} */
3126diff -Nur php-4.3.10/main/php_variables.c hardened-php-4.3.10-0.2.6/main/php_variables.c
3127--- php-4.3.10/main/php_variables.c 2004-10-18 17:08:46.000000000 +0200
3128+++ hardened-php-4.3.10-0.2.6/main/php_variables.c 2004-12-22 16:16:31.000000000 +0100
3129@@ -211,17 +211,28 @@
3130 while (var) {
3131 val = strchr(var, '=');
3132 if (val) { /* have a value */
3133- int val_len;
3134+ unsigned int val_len, new_val_len;
3135
3136 *val++ = '\0';
3137 php_url_decode(var, strlen(var));
3138 val_len = php_url_decode(val, strlen(val));
3139- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3140+ val = estrndup(val, val_len);
3141+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3142+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3143+ }
3144+ efree(val);
3145 }
3146 var = php_strtok_r(NULL, "&", &strtok_buf);
3147 }
3148 }
3149
3150+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
3151+{
3152+ /* TODO: check .ini setting here and apply user-defined input filter */
3153+ *new_val_len = val_len;
3154+ return 1;
3155+}
3156+
3157 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
3158 {
3159 char *res = NULL, *var, *val, *separator=NULL;
3160@@ -299,15 +310,26 @@
3161 while (var) {
3162 val = strchr(var, '=');
3163 if (val) { /* have a value */
3164- int val_len;
3165+ unsigned int val_len, new_val_len;
3166
3167 *val++ = '\0';
3168 php_url_decode(var, strlen(var));
3169 val_len = php_url_decode(val, strlen(val));
3170- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
3171+ val = estrndup(val, val_len);
3172+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3173+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3174+ }
3175+ efree(val);
3176 } else {
3177+ unsigned int val_len, new_val_len;
3178+
3179 php_url_decode(var, strlen(var));
3180- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
3181+ val_len = 0;
3182+ val = estrndup("", 0);
3183+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
3184+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
3185+ }
3186+ efree(val);
3187 }
3188 var = php_strtok_r(NULL, separator, &strtok_buf);
3189 }
3190diff -Nur php-4.3.10/main/rfc1867.c hardened-php-4.3.10-0.2.6/main/rfc1867.c
3191--- php-4.3.10/main/rfc1867.c 2004-11-20 21:16:44.000000000 +0100
3192+++ hardened-php-4.3.10-0.2.6/main/rfc1867.c 2004-12-22 16:16:31.000000000 +0100
3193@@ -891,21 +891,24 @@
3194 if (!filename && param) {
3195
3196 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
3197+ unsigned int new_val_len; /* Dummy variable */
3198
3199 if (!value) {
3200 value = estrdup("");
3201 }
3202
3203+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
3204 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
3205- if (php_mb_encoding_translation(TSRMLS_C)) {
3206- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
3207- &num_vars, &num_vars_max TSRMLS_CC);
3208- } else {
3209- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3210- }
3211+ if (php_mb_encoding_translation(TSRMLS_C)) {
3212+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
3213+ &num_vars, &num_vars_max TSRMLS_CC);
3214+ } else {
3215+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3216+ }
3217 #else
3218- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3219+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
3220 #endif
3221+ }
3222 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
3223 max_file_size = atol(value);
3224 }
3225diff -Nur php-4.3.10/main/snprintf.c hardened-php-4.3.10-0.2.6/main/snprintf.c
3226--- php-4.3.10/main/snprintf.c 2004-11-16 00:27:26.000000000 +0100
3227+++ hardened-php-4.3.10-0.2.6/main/snprintf.c 2004-12-22 16:16:31.000000000 +0100
3228@@ -850,7 +850,11 @@
3229
3230
3231 case 'n':
3232+#if HARDENED_PHP_FMT_PROTECT
3233+ php_security_log("'n' specifier within format string");
3234+#else
3235 *(va_arg(ap, int *)) = cc;
3236+#endif
3237 break;
3238
3239 /*
3240diff -Nur php-4.3.10/main/spprintf.c hardened-php-4.3.10-0.2.6/main/spprintf.c
3241--- php-4.3.10/main/spprintf.c 2003-09-29 03:09:36.000000000 +0200
3242+++ hardened-php-4.3.10-0.2.6/main/spprintf.c 2004-12-22 16:16:31.000000000 +0100
3243@@ -531,7 +531,11 @@
3244
3245
3246 case 'n':
3247+#if HARDENED_PHP_FMT_PROTECT
3248+ php_security_log("'n' specifier within format string");
3249+#else
3250 *(va_arg(ap, int *)) = cc;
3251+#endif
3252 break;
3253
3254 /*
3255diff -Nur php-4.3.10/php.ini-dist hardened-php-4.3.10-0.2.6/php.ini-dist
3256--- php-4.3.10/php.ini-dist 2004-08-18 07:05:23.000000000 +0200
3257+++ hardened-php-4.3.10-0.2.6/php.ini-dist 2004-12-22 16:16:31.000000000 +0100
3258@@ -1113,6 +1113,23 @@
3259 ;exif.decode_jis_motorola = JIS
3260 ;exif.decode_jis_intel = JIS
3261
3262+[varfilter]
3263+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3264+; Hardened-PHP's variable filter
3265+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3266+
3267+; Maximum number of input variables per request
3268+varfilter.max_request_variables = 200
3269+
3270+; Maximum characters in input variable names
3271+varfilter.max_varname_length = 64
3272+
3273+; Maximum length of input variable values
3274+varfilter.max_value_length = 10000
3275+
3276+; Maximum depth of input variable arrays
3277+varfilter.max_array_depth = 100
3278+
3279 ; Local Variables:
3280 ; tab-width: 4
3281 ; End:
3282diff -Nur php-4.3.10/php.ini-recommended hardened-php-4.3.10-0.2.6/php.ini-recommended
3283--- php-4.3.10/php.ini-recommended 2004-08-18 07:05:23.000000000 +0200
3284+++ hardened-php-4.3.10-0.2.6/php.ini-recommended 2004-12-22 16:16:31.000000000 +0100
3285@@ -1111,6 +1111,23 @@
3286 ;exif.decode_jis_motorola = JIS
3287 ;exif.decode_jis_intel = JIS
3288
3289+[varfilter]
3290+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3291+; Hardened-PHP's variable filter
3292+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3293+
3294+; Maximum number of input variables per request
3295+varfilter.max_request_variables = 200
3296+
3297+; Maximum characters in input variable names
3298+varfilter.max_varname_length = 64
3299+
3300+; Maximum length of input variable values
3301+varfilter.max_value_length = 10000
3302+
3303+; Maximum depth of input variable arrays
3304+varfilter.max_array_depth = 100
3305+
3306 ; Local Variables:
3307 ; tab-width: 4
3308 ; End:
3309diff -Nur php-4.3.10/sapi/apache/mod_php4.c hardened-php-4.3.10-0.2.6/sapi/apache/mod_php4.c
3310--- php-4.3.10/sapi/apache/mod_php4.c 2004-07-21 18:25:28.000000000 +0200
3311+++ hardened-php-4.3.10-0.2.6/sapi/apache/mod_php4.c 2004-12-22 16:16:31.000000000 +0100
3312@@ -446,7 +446,7 @@
3313 sapi_apache_get_fd,
3314 sapi_apache_force_http_10,
3315 sapi_apache_get_target_uid,
3316- sapi_apache_get_target_gid
3317+ sapi_apache_get_target_gid,
3318 };
3319 /* }}} */
3320
3321@@ -892,7 +892,11 @@
3322 {
3323 TSRMLS_FETCH();
3324 if (PG(expose_php)) {
3325+#if HARDENED_PHP
3326+ ap_add_version_component("Hardened-PHP/" PHP_VERSION);
3327+#else
3328 ap_add_version_component("PHP/" PHP_VERSION);
3329+#endif
3330 }
3331 }
3332 #endif
3333diff -Nur php-4.3.10/sapi/apache2filter/sapi_apache2.c hardened-php-4.3.10-0.2.6/sapi/apache2filter/sapi_apache2.c
3334--- php-4.3.10/sapi/apache2filter/sapi_apache2.c 2004-06-18 02:37:02.000000000 +0200
3335+++ hardened-php-4.3.10-0.2.6/sapi/apache2filter/sapi_apache2.c 2004-12-22 16:16:31.000000000 +0100
3336@@ -560,7 +560,11 @@
3337 {
3338 TSRMLS_FETCH();
3339 if (PG(expose_php)) {
3340+#if HARDENED_PHP
3341+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3342+#else
3343 ap_add_version_component(p, "PHP/" PHP_VERSION);
3344+#endif
3345 }
3346 }
3347
3348diff -Nur php-4.3.10/sapi/apache2handler/sapi_apache2.c hardened-php-4.3.10-0.2.6/sapi/apache2handler/sapi_apache2.c
3349--- php-4.3.10/sapi/apache2handler/sapi_apache2.c 2004-12-06 19:55:16.000000000 +0100
3350+++ hardened-php-4.3.10-0.2.6/sapi/apache2handler/sapi_apache2.c 2004-12-22 16:16:31.000000000 +0100
3351@@ -337,7 +337,11 @@
3352 {
3353 TSRMLS_FETCH();
3354 if (PG(expose_php)) {
3355+#if HARDENED_PHP
3356+ ap_add_version_component(p, "Hardened-PHP/" PHP_VERSION);
3357+#else
3358 ap_add_version_component(p, "PHP/" PHP_VERSION);
3359+#endif
3360 }
3361 }
3362
3363diff -Nur php-4.3.10/sapi/cgi/cgi_main.c hardened-php-4.3.10-0.2.6/sapi/cgi/cgi_main.c
3364--- php-4.3.10/sapi/cgi/cgi_main.c 2004-07-15 00:38:18.000000000 +0200
3365+++ hardened-php-4.3.10-0.2.6/sapi/cgi/cgi_main.c 2004-12-22 17:09:47.000000000 +0100
3366@@ -1426,11 +1426,19 @@
3367 SG(headers_sent) = 1;
3368 SG(request_info).no_headers = 1;
3369 }
3370+#if HARDENED_PHP
3371+#if ZEND_DEBUG
3372+ 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());
3373+#else
3374+ 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());
3375+#endif
3376+#else
3377 #if ZEND_DEBUG
3378 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());
3379 #else
3380 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());
3381 #endif
3382+#endif
3383 php_end_ob_buffers(1 TSRMLS_CC);
3384 exit(1);
3385 break;
3386diff -Nur php-4.3.10/sapi/cli/php_cli.c hardened-php-4.3.10-0.2.6/sapi/cli/php_cli.c
3387--- php-4.3.10/sapi/cli/php_cli.c 2004-07-15 00:38:18.000000000 +0200
3388+++ hardened-php-4.3.10-0.2.6/sapi/cli/php_cli.c 2004-12-22 17:09:18.000000000 +0100
3389@@ -646,11 +646,19 @@
3390 if (php_request_startup(TSRMLS_C)==FAILURE) {
3391 goto err;
3392 }
3393+#if HARDENED_PHP
3394+#if ZEND_DEBUG
3395+ 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());
3396+#else
3397+ 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());
3398+#endif
3399+#else
3400 #if ZEND_DEBUG
3401 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());
3402 #else
3403 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());
3404 #endif
3405+#endif
3406 php_end_ob_buffers(1 TSRMLS_CC);
3407 exit_status=1;
3408 goto out;
diff --git a/0.4.10/hardening-patch-4.4.2-0.4.10.patch b/0.4.10/hardening-patch-4.4.2-0.4.10.patch
new file mode 100644
index 0000000..ddeca58
--- /dev/null
+++ b/0.4.10/hardening-patch-4.4.2-0.4.10.patch
@@ -0,0 +1,8393 @@
1diff -Nura php-4.4.2/acinclude.m4 hardening-patch-4.4.2-0.4.10/acinclude.m4
2--- php-4.4.2/acinclude.m4 2005-12-19 23:29:11.000000000 +0100
3+++ hardening-patch-4.4.2-0.4.10/acinclude.m4 2006-05-11 10:36:02.000000000 +0200
4@@ -1186,6 +1186,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.4.2/Changelog.hphp hardening-patch-4.4.2-0.4.10/Changelog.hphp
42--- php-4.4.2/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100
43+++ hardening-patch-4.4.2-0.4.10/Changelog.hphp 2006-05-11 10:42:30.000000000 +0200
44@@ -0,0 +1,11 @@
45+Changelog of the Hardening-Patch
46+--------------------------------
47+
48+0.4.10 - 11. May 2006
49+
50+ PHP4:
51+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
52+
53+ PHP4+5:
54+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
55+
56diff -Nura php-4.4.2/configure hardening-patch-4.4.2-0.4.10/configure
57--- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100
58+++ hardening-patch-4.4.2-0.4.10/configure 2006-05-11 10:36:02.000000000 +0200
59@@ -402,6 +402,16 @@
60 ac_default_prefix=/usr/local
61 # Any additions from configure.in:
62 ac_help="$ac_help
63+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
64+ac_help="$ac_help
65+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
66+ac_help="$ac_help
67+ --disable-hardening-patch-inc-protect Disable include/require protection."
68+ac_help="$ac_help
69+ --disable-hardening-patch-fmt-protect Disable format string protection."
70+ac_help="$ac_help
71+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
72+ac_help="$ac_help
73
74 SAPI modules:
75 "
76@@ -854,6 +864,8 @@
77 ac_help="$ac_help
78 --disable-tokenizer Disable tokenizer support"
79 ac_help="$ac_help
80+ --disable-varfilter Disable Hardening-Patch's variable filter"
81+ac_help="$ac_help
82 --enable-wddx Enable WDDX support."
83 ac_help="$ac_help
84 --disable-xml Disable XML support using bundled expat lib"
85@@ -2942,6 +2954,157 @@
86
87
88
89+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
90+if test "${enable_hardening_patch_mm_protect+set}" = set; then
91+ enableval="$enable_hardening_patch_mm_protect"
92+
93+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
94+
95+else
96+
97+ DO_HARDENING_PATCH_MM_PROTECT=yes
98+
99+fi
100+
101+
102+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
103+if test "${enable_hardening_patch_ll_protect+set}" = set; then
104+ enableval="$enable_hardening_patch_ll_protect"
105+
106+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
107+
108+else
109+
110+ DO_HARDENING_PATCH_LL_PROTECT=yes
111+
112+fi
113+
114+
115+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
116+if test "${enable_hardening_patch_inc_protect+set}" = set; then
117+ enableval="$enable_hardening_patch_inc_protect"
118+
119+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
120+
121+else
122+
123+ DO_HARDENING_PATCH_INC_PROTECT=yes
124+
125+fi
126+
127+
128+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
129+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
130+ enableval="$enable_hardening_patch_fmt_protect"
131+
132+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
133+
134+else
135+
136+ DO_HARDENING_PATCH_FMT_PROTECT=yes
137+
138+fi
139+
140+
141+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
142+if test "${enable_hardening_patch_hash_protect+set}" = set; then
143+ enableval="$enable_hardening_patch_hash_protect"
144+
145+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
146+
147+else
148+
149+ DO_HARDENING_PATCH_HASH_PROTECT=yes
150+
151+fi
152+
153+
154+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
155+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
156+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
157+
158+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
159+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
160+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
161+
162+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
163+echo "configure:2733: checking whether to protect include/require statements" >&5
164+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
165+
166+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
167+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
168+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
169+
170+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
171+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
172+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
173+
174+
175+cat >> confdefs.h <<\EOF
176+#define HARDENING_PATCH 1
177+EOF
178+
179+
180+
181+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
182+ cat >> confdefs.h <<\EOF
183+#define HARDENING_PATCH_MM_PROTECT 1
184+EOF
185+
186+else
187+ cat >> confdefs.h <<\EOF
188+#define HARDENING_PATCH_MM_PROTECT 0
189+EOF
190+
191+fi
192+
193+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
194+ cat >> confdefs.h <<\EOF
195+#define HARDENING_PATCH_LL_PROTECT 1
196+EOF
197+
198+else
199+ cat >> confdefs.h <<\EOF
200+#define HARDENING_PATCH_LL_PROTECT 0
201+EOF
202+
203+fi
204+
205+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
206+ cat >> confdefs.h <<\EOF
207+#define HARDENING_PATCH_INC_PROTECT 1
208+EOF
209+
210+else
211+ cat >> confdefs.h <<\EOF
212+#define HARDENING_PATCH_INC_PROTECT 0
213+EOF
214+
215+fi
216+
217+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
218+ cat >> confdefs.h <<\EOF
219+#define HARDENING_PATCH_FMT_PROTECT 1
220+EOF
221+
222+else
223+ cat >> confdefs.h <<\EOF
224+#define HARDENING_PATCH_FMT_PROTECT 0
225+EOF
226+
227+fi
228+
229+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
230+ cat >> confdefs.h <<\EOF
231+#define HARDENING_PATCH_HASH_PROTECT 1
232+EOF
233+
234+else
235+ cat >> confdefs.h <<\EOF
236+#define HARDENING_PATCH_HASH_PROTECT 0
237+EOF
238+
239+fi
240
241
242
243@@ -16017,6 +16180,62 @@
244 fi
245
246
247+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
248+echo "configure:14928: checking whether realpath is broken" >&5
249+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
250+ echo $ac_n "(cached) $ac_c" 1>&6
251+else
252+
253+ if test "$cross_compiling" = yes; then
254+
255+ ac_cv_broken_realpath=no
256+
257+else
258+ cat > conftest.$ac_ext <<EOF
259+#line 14939 "configure"
260+#include "confdefs.h"
261+
262+main() {
263+ char buf[4096+1];
264+ buf[0] = 0;
265+ realpath("/etc/hosts/../passwd", buf);
266+ exit(strcmp(buf, "/etc/passwd")==0);
267+}
268+
269+EOF
270+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
271+then
272+
273+ ac_cv_broken_realpath=no
274+
275+else
276+ echo "configure: failed program was:" >&5
277+ cat conftest.$ac_ext >&5
278+ rm -fr conftest*
279+
280+ ac_cv_broken_realpath=yes
281+
282+fi
283+rm -fr conftest*
284+fi
285+
286+
287+fi
288+
289+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
290+ if test "$ac_cv_broken_realpath" = "yes"; then
291+ cat >> confdefs.h <<\EOF
292+#define PHP_BROKEN_REALPATH 1
293+EOF
294+
295+ else
296+ cat >> confdefs.h <<\EOF
297+#define PHP_BROKEN_REALPATH 0
298+EOF
299+
300+ fi
301+
302+
303 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
304 echo "configure:16022: checking for declared timezone" >&5
305 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
306@@ -86718,7 +86937,7 @@
307 if test "$ac_cv_crypt_blowfish" = "yes"; then
308 ac_result=1
309 else
310- ac_result=0
311+ ac_result=1
312 fi
313 cat >> confdefs.h <<EOF
314 #define PHP_BLOWFISH_CRYPT $ac_result
315@@ -87420,7 +87639,7 @@
316 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
317 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
318 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
319- var_unserializer.c ftok.c aggregation.c sha1.c ; do
320+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
321
322 IFS=.
323 set $ac_src
324@@ -87475,7 +87694,7 @@
325 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
326 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
327 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
328- var_unserializer.c ftok.c aggregation.c sha1.c ; do
329+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
330
331 IFS=.
332 set $ac_src
333@@ -87601,7 +87820,7 @@
334 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
335 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
336 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
337- var_unserializer.c ftok.c aggregation.c sha1.c ; do
338+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
339
340 IFS=.
341 set $ac_src
342@@ -87653,7 +87872,7 @@
343 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
344 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
345 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
346- var_unserializer.c ftok.c aggregation.c sha1.c ; do
347+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
348
349 IFS=.
350 set $ac_src
351@@ -91124,6 +91343,265 @@
352 fi
353
354
355+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
356+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
357+# Check whether --enable-varfilter or --disable-varfilter was given.
358+if test "${enable_varfilter+set}" = set; then
359+ enableval="$enable_varfilter"
360+ PHP_VARFILTER=$enableval
361+else
362+
363+ PHP_VARFILTER=yes
364+
365+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
366+ PHP_VARFILTER=$PHP_ENABLE_ALL
367+ fi
368+
369+fi
370+
371+
372+
373+ext_output="yes, shared"
374+ext_shared=yes
375+case $PHP_VARFILTER in
376+shared,*)
377+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
378+ ;;
379+shared)
380+ PHP_VARFILTER=yes
381+ ;;
382+no)
383+ ext_output=no
384+ ext_shared=no
385+ ;;
386+*)
387+ ext_output=yes
388+ ext_shared=no
389+ ;;
390+esac
391+
392+
393+
394+echo "$ac_t""$ext_output" 1>&6
395+
396+
397+
398+
399+if test "$PHP_VARFILTER" != "no"; then
400+ cat >> confdefs.h <<\EOF
401+#define HAVE_VARFILTER 1
402+EOF
403+
404+
405+ ext_builddir=ext/varfilter
406+ ext_srcdir=$abs_srcdir/ext/varfilter
407+
408+ ac_extra=
409+
410+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
411+
412+
413+
414+ case ext/varfilter in
415+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
416+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
417+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
418+ esac
419+
420+
421+
422+ b_c_pre=$php_c_pre
423+ b_cxx_pre=$php_cxx_pre
424+ b_c_meta=$php_c_meta
425+ b_cxx_meta=$php_cxx_meta
426+ b_c_post=$php_c_post
427+ b_cxx_post=$php_cxx_post
428+ b_lo=$php_lo
429+
430+
431+ old_IFS=$IFS
432+ for ac_src in varfilter.c; do
433+
434+ IFS=.
435+ set $ac_src
436+ ac_obj=$1
437+ IFS=$old_IFS
438+
439+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
440+
441+ case $ac_src in
442+ *.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" ;;
443+ *.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" ;;
444+ esac
445+
446+ cat >>Makefile.objects<<EOF
447+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
448+ $ac_comp
449+EOF
450+ done
451+
452+
453+ EXT_STATIC="$EXT_STATIC varfilter"
454+ if test "$ext_shared" != "nocli"; then
455+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
456+ fi
457+ else
458+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
459+
460+ case ext/varfilter in
461+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
462+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
463+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
464+ esac
465+
466+
467+
468+ b_c_pre=$shared_c_pre
469+ b_cxx_pre=$shared_cxx_pre
470+ b_c_meta=$shared_c_meta
471+ b_cxx_meta=$shared_cxx_meta
472+ b_c_post=$shared_c_post
473+ b_cxx_post=$shared_cxx_post
474+ b_lo=$shared_lo
475+
476+
477+ old_IFS=$IFS
478+ for ac_src in varfilter.c; do
479+
480+ IFS=.
481+ set $ac_src
482+ ac_obj=$1
483+ IFS=$old_IFS
484+
485+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
486+
487+ case $ac_src in
488+ *.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" ;;
489+ *.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" ;;
490+ esac
491+
492+ cat >>Makefile.objects<<EOF
493+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
494+ $ac_comp
495+EOF
496+ done
497+
498+
499+ install_modules="install-modules"
500+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
501+
502+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
503+
504+ cat >>Makefile.objects<<EOF
505+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
506+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
507+
508+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
509+ \$(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)
510+
511+EOF
512+
513+ cat >> confdefs.h <<EOF
514+#define COMPILE_DL_VARFILTER 1
515+EOF
516+
517+ fi
518+ fi
519+
520+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
521+ if test "$PHP_SAPI" = "cgi"; then
522+
523+
524+ case ext/varfilter in
525+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
526+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
527+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
528+ esac
529+
530+
531+
532+ b_c_pre=$php_c_pre
533+ b_cxx_pre=$php_cxx_pre
534+ b_c_meta=$php_c_meta
535+ b_cxx_meta=$php_cxx_meta
536+ b_c_post=$php_c_post
537+ b_cxx_post=$php_cxx_post
538+ b_lo=$php_lo
539+
540+
541+ old_IFS=$IFS
542+ for ac_src in varfilter.c; do
543+
544+ IFS=.
545+ set $ac_src
546+ ac_obj=$1
547+ IFS=$old_IFS
548+
549+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
550+
551+ case $ac_src in
552+ *.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" ;;
553+ *.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" ;;
554+ esac
555+
556+ cat >>Makefile.objects<<EOF
557+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
558+ $ac_comp
559+EOF
560+ done
561+
562+
563+ EXT_STATIC="$EXT_STATIC varfilter"
564+ else
565+
566+
567+ case ext/varfilter in
568+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
569+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
570+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
571+ esac
572+
573+
574+
575+ b_c_pre=$php_c_pre
576+ b_cxx_pre=$php_cxx_pre
577+ b_c_meta=$php_c_meta
578+ b_cxx_meta=$php_cxx_meta
579+ b_c_post=$php_c_post
580+ b_cxx_post=$php_cxx_post
581+ b_lo=$php_lo
582+
583+
584+ old_IFS=$IFS
585+ for ac_src in varfilter.c; do
586+
587+ IFS=.
588+ set $ac_src
589+ ac_obj=$1
590+ IFS=$old_IFS
591+
592+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
593+
594+ case $ac_src in
595+ *.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" ;;
596+ *.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" ;;
597+ esac
598+
599+ cat >>Makefile.objects<<EOF
600+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
601+ $ac_comp
602+EOF
603+ done
604+
605+
606+ fi
607+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
608+ fi
609+
610+ BUILD_DIR="$BUILD_DIR $ext_builddir"
611+
612+
613+fi
614
615
616 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
617@@ -104088,7 +104566,7 @@
618 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
619 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
620 streams.c network.c php_open_temporary_file.c php_logos.c \
621- output.c memory_streams.c user_streams.c; do
622+ output.c memory_streams.c user_streams.c hardening_patch.c; do
623
624 IFS=.
625 set $ac_src
626@@ -104273,7 +104751,7 @@
627 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
628 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
629 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
630- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
631+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
632
633 IFS=.
634 set $ac_src
635diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.10/configure.in
636--- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100
637+++ hardening-patch-4.4.2-0.4.10/configure.in 2006-05-11 10:36:02.000000000 +0200
638@@ -247,7 +247,7 @@
639 sinclude(Zend/acinclude.m4)
640 sinclude(Zend/Zend.m4)
641 sinclude(TSRM/tsrm.m4)
642-
643+sinclude(main/hardening_patch.m4)
644
645
646 divert(2)
647@@ -621,6 +621,7 @@
648 AC_FUNC_ALLOCA
649 dnl PHP_AC_BROKEN_SPRINTF
650 dnl PHP_AC_BROKEN_SNPRINTF
651+PHP_AC_BROKEN_REALPATH
652 PHP_DECLARED_TIMEZONE
653 PHP_TIME_R_TYPE
654 PHP_READDIR_R_TYPE
655@@ -1260,7 +1261,7 @@
656 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
657 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
658 streams.c network.c php_open_temporary_file.c php_logos.c \
659- output.c memory_streams.c user_streams.c)
660+ output.c memory_streams.c user_streams.c hardening_patch.c)
661 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
662 case $host_alias in
663 *netware*)
664@@ -1281,7 +1282,7 @@
665 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
666 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
667 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
668- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
669+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
670
671 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
672 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
673diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.10/ext/curl/curl.c
674--- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100
675+++ hardening-patch-4.4.2-0.4.10/ext/curl/curl.c 2006-05-11 10:36:02.000000000 +0200
676@@ -111,7 +111,7 @@
677
678 #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
679 if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
680- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
681+ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \
682 { \
683 php_url *tmp_url; \
684 \
685diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.10/ext/fbsql/php_fbsql.c
686--- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100
687+++ hardening-patch-4.4.2-0.4.10/ext/fbsql/php_fbsql.c 2006-05-11 10:36:02.000000000 +0200
688@@ -1797,8 +1797,24 @@
689 }
690 else if (fbcmdErrorsFound(md))
691 {
692+#if HARDENING_PATCH
693+ char* query_copy;
694+ int i;
695+#endif
696 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
697 char* emg = fbcemdAllErrorMessages(emd);
698+#if HARDENING_PATCH
699+ query_copy=estrdup(query_copy);
700+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
701+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
702+ efree(query_copy);
703+ if (HG(hphp_sql_bailout_on_error)) {
704+ free(emg);
705+ fbcemdRelease(emd);
706+ result = 0;
707+ zend_bailout();
708+ }
709+#endif
710 if (FB_SQL_G(generateWarnings))
711 {
712 if (emg)
713diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.10/ext/mbstring/mbstring.c
714--- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100
715+++ hardening-patch-4.4.2-0.4.10/ext/mbstring/mbstring.c 2006-05-11 10:36:02.000000000 +0200
716@@ -1488,6 +1488,7 @@
717 char *strtok_buf = NULL, **val_list;
718 zval *array_ptr = (zval *) arg;
719 int n, num, val_len, *len_list;
720+ unsigned int new_val_len;
721 enum mbfl_no_encoding from_encoding;
722 mbfl_string string, resvar, resval;
723 mbfl_encoding_detector *identd = NULL;
724@@ -1610,8 +1611,14 @@
725 val_len = len_list[n];
726 }
727 n++;
728- /* add variable to symbol table */
729- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
730+ /* we need val to be emalloc()ed */
731+ val = estrndup(val, val_len);
732+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
733+ /* add variable to symbol table */
734+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
735+ }
736+ efree(val);
737+
738 if (convd != NULL){
739 mbfl_string_clear(&resvar);
740 mbfl_string_clear(&resval);
741diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.10/ext/mysql/php_mysql.c
742--- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100
743+++ hardening-patch-4.4.2-0.4.10/ext/mysql/php_mysql.c 2006-05-11 10:36:02.000000000 +0200
744@@ -1218,6 +1218,8 @@
745 {
746 php_mysql_conn *mysql;
747 MYSQL_RES *mysql_result;
748+ char *copy_query;
749+ int i;
750
751 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
752
753@@ -1268,6 +1270,13 @@
754 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
755 }
756 }
757+ copy_query = estrdup(Z_STRVAL_PP(query));
758+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
759+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
760+ efree(copy_query);
761+ if (HG(hphp_sql_bailout_on_error)) {
762+ zend_bailout();
763+ }
764 RETURN_FALSE;
765 }
766 #else
767@@ -1275,12 +1284,20 @@
768 /* check possible error */
769 if (MySG(trace_mode)){
770 if (mysql_errno(&mysql->conn)){
771- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
772+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
773 }
774 }
775+ copy_query = estrdup(Z_STRVAL_PP(query));
776+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
777+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
778+ efree(copy_query);
779+ if (HG(hphp_sql_bailout_on_error)) {
780+ zend_bailout();
781+ }
782 RETURN_FALSE;
783 }
784 #endif
785+
786 if(use_store == MYSQL_USE_RESULT) {
787 mysql_result=mysql_use_result(&mysql->conn);
788 } else {
789diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.10/ext/pgsql/pgsql.c
790--- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100
791+++ hardening-patch-4.4.2-0.4.10/ext/pgsql/pgsql.c 2006-05-11 10:36:02.000000000 +0200
792@@ -1001,10 +1001,28 @@
793 case PGRES_EMPTY_QUERY:
794 case PGRES_BAD_RESPONSE:
795 case PGRES_NONFATAL_ERROR:
796- case PGRES_FATAL_ERROR:
797- PHP_PQ_ERROR("Query failed: %s", pgsql);
798- PQclear(pgsql_result);
799- RETURN_FALSE;
800+ case PGRES_FATAL_ERROR:
801+ {
802+#if HARDENING_PATCH
803+ int i;
804+ char *query_copy;
805+#endif
806+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
807+ PQclear(pgsql_result);
808+#if HARDENING_PATCH
809+ query_copy = estrdup(Z_STRVAL_PP(query));
810+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
811+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
812+ efree(query_copy);
813+ if (HG(hphp_sql_bailout_on_error)) {
814+ efree(msgbuf);
815+ zend_bailout();
816+ }
817+#endif
818+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
819+ efree(msgbuf);
820+ RETURN_FALSE;
821+ }
822 break;
823 case PGRES_COMMAND_OK: /* successful command that did not return rows */
824 default:
825diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.10/ext/session/mod_files.c
826--- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100
827+++ hardening-patch-4.4.2-0.4.10/ext/session/mod_files.c 2006-05-11 10:36:02.000000000 +0200
828@@ -16,7 +16,7 @@
829 +----------------------------------------------------------------------+
830 */
831
832-/* $Id: mod_files.c,v 1.83.2.9.2.2 2006/01/01 13:46:56 sniper Exp $ */
833+/* $Id: mod_files.c,v 1.83.2.9.2.3 2006/04/17 23:29:37 iliaa Exp $ */
834
835 #include "php.h"
836
837@@ -364,10 +364,12 @@
838 if (!ps_files_path_create(buf, sizeof(buf), data, key))
839 return FAILURE;
840
841- ps_files_close(data);
842+ if (data->fd != -1) {
843+ ps_files_close(data);
844
845- if (VCWD_UNLINK(buf) == -1) {
846- return FAILURE;
847+ if (VCWD_UNLINK(buf) == -1) {
848+ return FAILURE;
849+ }
850 }
851
852 return SUCCESS;
853@@ -389,6 +391,34 @@
854 return SUCCESS;
855 }
856
857+PS_VALIDATE_SID_FUNC(files)
858+{
859+ char buf[MAXPATHLEN];
860+ int fd;
861+ PS_FILES_DATA;
862+
863+ if (!ps_files_valid_key(key)) {
864+ return FAILURE;
865+ }
866+
867+ if (!PS(use_strict_mode)) {
868+ return SUCCESS;
869+ }
870+
871+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
872+ return FAILURE;
873+ }
874+
875+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
876+
877+ if (fd != -1) {
878+ close(fd);
879+ return SUCCESS;
880+ }
881+
882+ return FAILURE;
883+}
884+
885 /*
886 * Local variables:
887 * tab-width: 4
888diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.10/ext/session/mod_mm.c
889--- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100
890+++ hardening-patch-4.4.2-0.4.10/ext/session/mod_mm.c 2006-05-11 10:36:02.000000000 +0200
891@@ -425,6 +425,42 @@
892 return SUCCESS;
893 }
894
895+PS_VALIDATE_SID_FUNC(mm)
896+{
897+ PS_MM_DATA;
898+ ps_sd *sd;
899+ const char *p;
900+ char c;
901+ int ret = SUCCESS;
902+
903+ for (p = key; (c = *p); p++) {
904+ /* valid characters are a..z,A..Z,0..9 */
905+ if (!((c >= 'a' && c <= 'z')
906+ || (c >= 'A' && c <= 'Z')
907+ || (c >= '0' && c <= '9')
908+ || c == ','
909+ || c == '-')) {
910+ return FAILURE;
911+ }
912+ }
913+
914+ if (!PS(use_strict_mode)) {
915+ return SUCCESS;
916+ }
917+
918+ mm_lock(data->mm, MM_LOCK_RD);
919+
920+ sd = ps_sd_lookup(data, key, 0);
921+ if (sd) {
922+ mm_unlock(data->mm);
923+ return SUCCESS;
924+ }
925+
926+ mm_unlock(data->mm);
927+
928+ return FAILURE;
929+}
930+
931 #endif
932
933 /*
934diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.10/ext/session/mod_user.c
935--- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100
936+++ hardening-patch-4.4.2-0.4.10/ext/session/mod_user.c 2006-05-11 10:36:02.000000000 +0200
937@@ -23,7 +23,7 @@
938 #include "mod_user.h"
939
940 ps_module ps_mod_user = {
941- PS_MOD(user)
942+ PS_MOD_SID(user)
943 };
944
945 #define SESS_ZVAL_LONG(val, a) \
946@@ -174,6 +174,83 @@
947 FINISH;
948 }
949
950+PS_CREATE_SID_FUNC(user)
951+{
952+ int i;
953+ char *val = NULL;
954+ zval *retval;
955+ ps_user *mdata = PS_GET_MOD_DATA();
956+
957+ if (!mdata)
958+ return estrndup("", 0);
959+
960+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
961+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
962+ }
963+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
964+
965+ if (retval) {
966+ if (Z_TYPE_P(retval) == IS_STRING) {
967+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
968+ } else {
969+ val = estrndup("", 0);
970+ }
971+ zval_ptr_dtor(&retval);
972+ } else {
973+ val = estrndup("", 0);
974+ }
975+
976+ return val;
977+}
978+
979+static int ps_user_valid_key(const char *key TSRMLS_DC)
980+{
981+ size_t len;
982+ const char *p;
983+ char c;
984+ int ret = SUCCESS;
985+
986+ for (p = key; (c = *p); p++) {
987+ /* valid characters are a..z,A..Z,0..9 */
988+ if (!((c >= 'a' && c <= 'z')
989+ || (c >= 'A' && c <= 'Z')
990+ || (c >= '0' && c <= '9')
991+ || c == ','
992+ || c == '-')) {
993+ ret = FAILURE;
994+ break;
995+ }
996+ }
997+
998+ len = p - key;
999+
1000+ if (len == 0)
1001+ ret = FAILURE;
1002+
1003+ return ret;
1004+}
1005+
1006+PS_VALIDATE_SID_FUNC(user)
1007+{
1008+ zval *args[1];
1009+ STDVARS;
1010+
1011+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
1012+ return ps_user_valid_key(key TSRMLS_CC);
1013+ }
1014+ SESS_ZVAL_STRING(key, args[0]);
1015+
1016+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1017+
1018+ if (retval) {
1019+ convert_to_long(retval);
1020+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1021+ zval_ptr_dtor(&retval);
1022+ }
1023+
1024+ return ret;
1025+}
1026+
1027 /*
1028 * Local variables:
1029 * tab-width: 4
1030diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.10/ext/session/mod_user.h
1031--- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100
1032+++ hardening-patch-4.4.2-0.4.10/ext/session/mod_user.h 2006-05-11 10:36:02.000000000 +0200
1033@@ -22,7 +22,7 @@
1034 #define MOD_USER_H
1035
1036 typedef union {
1037- zval *names[6];
1038+ zval *names[8];
1039 struct {
1040 zval *ps_open;
1041 zval *ps_close;
1042@@ -30,6 +30,8 @@
1043 zval *ps_write;
1044 zval *ps_destroy;
1045 zval *ps_gc;
1046+ zval *ps_create;
1047+ zval *ps_validate;
1048 } name;
1049 } ps_user;
1050
1051diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.10/ext/session/php_session.h
1052--- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100
1053+++ hardening-patch-4.4.2-0.4.10/ext/session/php_session.h 2006-05-11 10:36:02.000000000 +0200
1054@@ -23,7 +23,7 @@
1055
1056 #include "ext/standard/php_var.h"
1057
1058-#define PHP_SESSION_API 20020330
1059+#define PHP_SESSION_API 20051121
1060
1061 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1062 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1063@@ -32,6 +32,7 @@
1064 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1065 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1066 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1067+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1068
1069 /* default create id function */
1070 char *php_session_create_id(PS_CREATE_SID_ARGS);
1071@@ -45,6 +46,7 @@
1072 int (*s_destroy)(PS_DESTROY_ARGS);
1073 int (*s_gc)(PS_GC_ARGS);
1074 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1075+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1076 } ps_module;
1077
1078 #define PS_GET_MOD_DATA() *mod_data
1079@@ -57,6 +59,7 @@
1080 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1081 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1082 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1083+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1084
1085 #define PS_FUNCS(x) \
1086 PS_OPEN_FUNC(x); \
1087@@ -65,11 +68,12 @@
1088 PS_WRITE_FUNC(x); \
1089 PS_DESTROY_FUNC(x); \
1090 PS_GC_FUNC(x); \
1091- PS_CREATE_SID_FUNC(x)
1092+ PS_CREATE_SID_FUNC(x); \
1093+ PS_VALIDATE_SID_FUNC(x)
1094
1095 #define PS_MOD(x) \
1096 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1097- ps_delete_##x, ps_gc_##x, php_session_create_id
1098+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1099
1100 /* SID enabled module handler definitions */
1101 #define PS_FUNCS_SID(x) \
1102@@ -79,11 +83,12 @@
1103 PS_WRITE_FUNC(x); \
1104 PS_DESTROY_FUNC(x); \
1105 PS_GC_FUNC(x); \
1106- PS_CREATE_SID_FUNC(x)
1107+ PS_CREATE_SID_FUNC(x); \
1108+ PS_VALIDATE_SID(x)
1109
1110 #define PS_MOD_SID(x) \
1111 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1112- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1113+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1114
1115 typedef enum {
1116 php_session_disabled,
1117@@ -120,6 +125,7 @@
1118 zend_bool use_only_cookies;
1119 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1120 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1121+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1122 int send_cookie;
1123 int define_sid;
1124 } php_ps_globals;
1125diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.10/ext/session/session.c
1126--- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100
1127+++ hardening-patch-4.4.2-0.4.10/ext/session/session.c 2006-05-11 10:36:02.000000000 +0200
1128@@ -17,7 +17,7 @@
1129 +----------------------------------------------------------------------+
1130 */
1131
1132-/* $Id: session.c,v 1.336.2.53.2.4 2006/01/01 13:46:56 sniper Exp $ */
1133+/* $Id: session.c,v 1.336.2.53.2.5 2006/01/15 16:52:10 iliaa Exp $ */
1134
1135 #ifdef HAVE_CONFIG_H
1136 #include "config.h"
1137@@ -155,6 +155,7 @@
1138 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1139 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1140 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1141+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1142 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1143 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1144 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1145@@ -626,6 +627,12 @@
1146 char *val;
1147 int vallen;
1148
1149+ /* check session name for invalid characters */
1150+ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
1151+ efree(PS(id));
1152+ PS(id) = NULL;
1153+ }
1154+
1155 if (!PS(mod)) {
1156 php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session.");
1157 return;
1158@@ -637,6 +644,15 @@
1159 return;
1160 }
1161
1162+ /* If there is an ID, use session module to verify it */
1163+ if (PS(id)) {
1164+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1165+ efree(PS(id));
1166+ PS(id) = NULL;
1167+ PS(send_cookie) = 1;
1168+ }
1169+ }
1170+
1171 /* If there is no ID, use session module to create one */
1172 if (!PS(id))
1173 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1174@@ -1256,22 +1272,31 @@
1175 }
1176 /* }}} */
1177
1178-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1179+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1180 Sets user-level functions */
1181 PHP_FUNCTION(session_set_save_handler)
1182 {
1183- zval **args[6];
1184- int i;
1185+ zval **args[8];
1186+ int i, numargs;
1187 ps_user *mdata;
1188 char *name;
1189
1190+ numargs = ZEND_NUM_ARGS();
1191+ args[6] = NULL;
1192+ args[7] = NULL;
1193+
1194+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1195+ WRONG_PARAM_COUNT;
1196 if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1197 WRONG_PARAM_COUNT;
1198
1199 if (PS(session_status) != php_session_none)
1200 RETURN_FALSE;
1201
1202- for (i = 0; i < 6; i++) {
1203+ for (i = 0; i < 8; i++) {
1204+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1205+ continue;
1206+ }
1207 if (!zend_is_callable(*args[i], 0, &name)) {
1208 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1209 efree(name);
1210@@ -1284,7 +1309,11 @@
1211
1212 mdata = emalloc(sizeof(*mdata));
1213
1214- for (i = 0; i < 6; i++) {
1215+ for (i = 0; i < 8; i++) {
1216+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1217+ mdata->names[i] = NULL;
1218+ continue;
1219+ }
1220 ZVAL_ADDREF(*args[i]);
1221 mdata->names[i] = *args[i];
1222 }
1223@@ -1345,8 +1374,20 @@
1224 Update the current session id with a newly generated one. */
1225 PHP_FUNCTION(session_regenerate_id)
1226 {
1227+ zend_bool del_ses = 0;
1228+
1229+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1230+ WRONG_PARAM_COUNT;
1231+ }
1232+
1233 if (PS(session_status) == php_session_active) {
1234- if (PS(id)) efree(PS(id));
1235+ if (PS(id)) {
1236+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1237+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1238+ RETURN_FALSE;
1239+ }
1240+ efree(PS(id));
1241+ }
1242
1243 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1244
1245diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.10/ext/session/tests/014.phpt
1246--- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1247+++ hardening-patch-4.4.2-0.4.10/ext/session/tests/014.phpt 2006-05-11 10:36:02.000000000 +0200
1248@@ -5,6 +5,7 @@
1249 --INI--
1250 session.use_trans_sid=1
1251 session.use_cookies=0
1252+session.use_strict_mode=0
1253 session.cache_limiter=
1254 register_globals=1
1255 session.bug_compat_42=1
1256diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.10/ext/session/tests/015.phpt
1257--- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1258+++ hardening-patch-4.4.2-0.4.10/ext/session/tests/015.phpt 2006-05-11 10:36:02.000000000 +0200
1259@@ -5,6 +5,7 @@
1260 --INI--
1261 session.use_trans_sid=1
1262 session.use_cookies=0
1263+session.use_strict_mode=0
1264 session.cache_limiter=
1265 arg_separator.output=&
1266 session.name=PHPSESSID
1267diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.10/ext/session/tests/018.phpt
1268--- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1269+++ hardening-patch-4.4.2-0.4.10/ext/session/tests/018.phpt 2006-05-11 10:36:02.000000000 +0200
1270@@ -4,6 +4,7 @@
1271 <?php include('skipif.inc'); ?>
1272 --INI--
1273 session.use_cookies=0
1274+session.use_strict_mode=0
1275 session.cache_limiter=
1276 session.use_trans_sid=1
1277 session.name=PHPSESSID
1278diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.10/ext/session/tests/020.phpt
1279--- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1280+++ hardening-patch-4.4.2-0.4.10/ext/session/tests/020.phpt 2006-05-11 10:36:02.000000000 +0200
1281@@ -4,6 +4,7 @@
1282 <?php include('skipif.inc'); ?>
1283 --INI--
1284 session.use_cookies=0
1285+session.use_strict_mode=0
1286 session.cache_limiter=
1287 session.use_trans_sid=1
1288 arg_separator.output=&amp;
1289diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.10/ext/session/tests/021.phpt
1290--- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1291+++ hardening-patch-4.4.2-0.4.10/ext/session/tests/021.phpt 2006-05-11 10:36:02.000000000 +0200
1292@@ -4,6 +4,7 @@
1293 <?php include('skipif.inc'); ?>
1294 --INI--
1295 session.use_cookies=0
1296+session.use_strict_mode=0
1297 session.cache_limiter=
1298 session.use_trans_sid=1
1299 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1300diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.10/ext/standard/array.c
1301--- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100
1302+++ hardening-patch-4.4.2-0.4.10/ext/standard/array.c 2006-05-11 10:36:02.000000000 +0200
1303@@ -1162,6 +1162,32 @@
1304 }
1305 }
1306 }
1307+
1308+ if (var_name[0] == 'H') {
1309+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1310+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1311+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1312+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1313+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1314+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1315+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1316+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1317+ return 0;
1318+ }
1319+ } else if (var_name[0] == '_') {
1320+ if ((strcmp(var_name, "_COOKIE")==0)||
1321+ (strcmp(var_name, "_ENV")==0)||
1322+ (strcmp(var_name, "_FILES")==0)||
1323+ (strcmp(var_name, "_GET")==0)||
1324+ (strcmp(var_name, "_POST")==0)||
1325+ (strcmp(var_name, "_REQUEST")==0)||
1326+ (strcmp(var_name, "_SESSION")==0)||
1327+ (strcmp(var_name, "_SERVER")==0)) {
1328+ return 0;
1329+ }
1330+ } else if (strcmp(var_name, "GLOBALS")==0) {
1331+ return 0;
1332+ }
1333
1334 return 1;
1335 }
1336diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.10/ext/standard/basic_functions.c
1337--- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100
1338+++ hardening-patch-4.4.2-0.4.10/ext/standard/basic_functions.c 2006-05-11 10:36:02.000000000 +0200
1339@@ -107,12 +107,14 @@
1340 typedef struct _php_shutdown_function_entry {
1341 zval **arguments;
1342 int arg_count;
1343+ zend_bool created_by_eval;
1344 } php_shutdown_function_entry;
1345
1346 typedef struct _user_tick_function_entry {
1347 zval **arguments;
1348 int arg_count;
1349 int calling;
1350+ zend_bool created_by_eval;
1351 } user_tick_function_entry;
1352
1353 /* some prototypes for local functions */
1354@@ -295,6 +297,8 @@
1355 PHP_FE(get_html_translation_table, NULL)
1356 PHP_FE(sha1, NULL)
1357 PHP_FE(sha1_file, NULL)
1358+ PHP_FE(sha256, NULL)
1359+ PHP_FE(sha256_file, NULL)
1360 PHP_NAMED_FE(md5,php_if_md5, NULL)
1361 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1362 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1363@@ -676,7 +680,7 @@
1364 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1365
1366 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1367- PHP_FE(realpath, NULL)
1368+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1369 #endif
1370
1371 #ifdef HAVE_FNMATCH
1372@@ -2096,6 +2100,13 @@
1373 {
1374 zval retval;
1375 char *function_name = NULL;
1376+#if HARDENING_PATCH
1377+ zend_uint orig_code_type = EG(in_code_type);
1378+
1379+ if (shutdown_function_entry->created_by_eval) {
1380+ EG(in_code_type) = ZEND_EVAL_CODE;
1381+ }
1382+#endif
1383
1384 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1385 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1386@@ -2111,6 +2122,9 @@
1387 if (function_name) {
1388 efree(function_name);
1389 }
1390+#if HARDENING_PATCH
1391+ EG(in_code_type) = orig_code_type;
1392+#endif
1393 return 0;
1394 }
1395
1396@@ -2118,6 +2132,13 @@
1397 {
1398 zval retval;
1399 zval *function = tick_fe->arguments[0];
1400+#if HARDENING_PATCH
1401+ zend_uint orig_code_type = EG(in_code_type);
1402+
1403+ if (tick_fe->created_by_eval) {
1404+ EG(in_code_type) = ZEND_EVAL_CODE;
1405+ }
1406+#endif
1407
1408 /* Prevent reentrant calls to the same user ticks function */
1409 if (! tick_fe->calling) {
1410@@ -2149,6 +2170,9 @@
1411
1412 tick_fe->calling = 0;
1413 }
1414+#if HARDENING_PATCH
1415+ EG(in_code_type) = orig_code_type;
1416+#endif
1417 }
1418
1419 static void run_user_tick_functions(int tick_count)
1420@@ -2216,6 +2240,13 @@
1421 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1422 RETURN_FALSE;
1423 }
1424+#if HARDENING_PATCH
1425+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1426+ shutdown_function_entry.created_by_eval = 1;
1427+ } else {
1428+ shutdown_function_entry.created_by_eval = 0;
1429+ }
1430+#endif
1431
1432 /* Prevent entering of anything but valid callback (syntax check only!) */
1433 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1434@@ -2753,6 +2784,13 @@
1435 }
1436
1437 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1438+#if HARDENING_PATCH
1439+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1440+ tick_fe.created_by_eval = 1;
1441+ } else {
1442+ tick_fe.created_by_eval = 0;
1443+ }
1444+#endif
1445
1446 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1447 RETURN_FALSE;
1448@@ -3050,6 +3088,35 @@
1449 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1450 }
1451
1452+ if (new_key[0] == 'H') {
1453+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1454+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1455+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1456+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1457+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1458+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1459+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1460+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1461+ efree(new_key);
1462+ return 0;
1463+ }
1464+ } else if (new_key[0] == '_') {
1465+ if ((strcmp(new_key, "_COOKIE")==0)||
1466+ (strcmp(new_key, "_ENV")==0)||
1467+ (strcmp(new_key, "_FILES")==0)||
1468+ (strcmp(new_key, "_GET")==0)||
1469+ (strcmp(new_key, "_POST")==0)||
1470+ (strcmp(new_key, "_REQUEST")==0)||
1471+ (strcmp(new_key, "_SESSION")==0)||
1472+ (strcmp(new_key, "_SERVER")==0)) {
1473+ efree(new_key);
1474+ return 0;
1475+ }
1476+ } else if (strcmp(new_key, "GLOBALS")==0) {
1477+ efree(new_key);
1478+ return 0;
1479+ }
1480+
1481 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1482 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1483
1484diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.10/ext/standard/config.m4
1485--- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1486+++ hardening-patch-4.4.2-0.4.10/ext/standard/config.m4 2006-05-11 10:36:02.000000000 +0200
1487@@ -203,7 +203,7 @@
1488 if test "$ac_cv_crypt_blowfish" = "yes"; then
1489 ac_result=1
1490 else
1491- ac_result=0
1492+ ac_result=1
1493 fi
1494 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1495 ])
1496@@ -419,6 +419,6 @@
1497 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1498 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1499 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1500- var_unserializer.c ftok.c aggregation.c sha1.c )
1501+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1502
1503 PHP_ADD_MAKEFILE_FRAGMENT
1504diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.10/ext/standard/crypt_blowfish.c
1505--- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1506+++ hardening-patch-4.4.2-0.4.10/ext/standard/crypt_blowfish.c 2006-05-11 10:36:02.000000000 +0200
1507@@ -0,0 +1,748 @@
1508+/*
1509+ * This code comes from John the Ripper password cracker, with reentrant
1510+ * and crypt(3) interfaces added, but optimizations specific to password
1511+ * cracking removed.
1512+ *
1513+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1514+ * placed in the public domain.
1515+ *
1516+ * There's absolutely no warranty.
1517+ *
1518+ * It is my intent that you should be able to use this on your system,
1519+ * as a part of a software package, or anywhere else to improve security,
1520+ * ensure compatibility, or for any other purpose. I would appreciate
1521+ * it if you give credit where it is due and keep your modifications in
1522+ * the public domain as well, but I don't require that in order to let
1523+ * you place this code and any modifications you make under a license
1524+ * of your choice.
1525+ *
1526+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1527+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1528+ * ideas. The password hashing algorithm was designed by David Mazieres
1529+ * <dm at lcs.mit.edu>.
1530+ *
1531+ * There's a paper on the algorithm that explains its design decisions:
1532+ *
1533+ * http://www.usenix.org/events/usenix99/provos.html
1534+ *
1535+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1536+ * Blowfish library (I can't be sure if I would think of something if I
1537+ * hadn't seen his code).
1538+ */
1539+
1540+#include <string.h>
1541+
1542+#include <errno.h>
1543+#ifndef __set_errno
1544+#define __set_errno(val) errno = (val)
1545+#endif
1546+
1547+#undef __CONST
1548+#ifdef __GNUC__
1549+#define __CONST __const
1550+#else
1551+#define __CONST
1552+#endif
1553+
1554+#ifdef __i386__
1555+#define BF_ASM 0
1556+#define BF_SCALE 1
1557+#elif defined(__alpha__) || defined(__hppa__)
1558+#define BF_ASM 0
1559+#define BF_SCALE 1
1560+#else
1561+#define BF_ASM 0
1562+#define BF_SCALE 0
1563+#endif
1564+
1565+typedef unsigned int BF_word;
1566+
1567+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1568+#define BF_N 16
1569+
1570+typedef BF_word BF_key[BF_N + 2];
1571+
1572+typedef struct {
1573+ BF_word S[4][0x100];
1574+ BF_key P;
1575+} BF_ctx;
1576+
1577+/*
1578+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1579+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1580+ */
1581+static BF_word BF_magic_w[6] = {
1582+ 0x4F727068, 0x65616E42, 0x65686F6C,
1583+ 0x64657253, 0x63727944, 0x6F756274
1584+};
1585+
1586+/*
1587+ * P-box and S-box tables initialized with digits of Pi.
1588+ */
1589+static BF_ctx BF_init_state = {
1590+ {
1591+ {
1592+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1593+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1594+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1595+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1596+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1597+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1598+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1599+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1600+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1601+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1602+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1603+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1604+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1605+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1606+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1607+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1608+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1609+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1610+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1611+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1612+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1613+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1614+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1615+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1616+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1617+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1618+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1619+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1620+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1621+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1622+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1623+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1624+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1625+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1626+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1627+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1628+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1629+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1630+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1631+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1632+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1633+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1634+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1635+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1636+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1637+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1638+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1639+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1640+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1641+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1642+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1643+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1644+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1645+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1646+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1647+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1648+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1649+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1650+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1651+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1652+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1653+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1654+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1655+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1656+ }, {
1657+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1658+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1659+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1660+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1661+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1662+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1663+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1664+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1665+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1666+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1667+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1668+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1669+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1670+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1671+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1672+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1673+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1674+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1675+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1676+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1677+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1678+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1679+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1680+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1681+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1682+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1683+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1684+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1685+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1686+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1687+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1688+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1689+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1690+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1691+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1692+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1693+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1694+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1695+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1696+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1697+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1698+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1699+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1700+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1701+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1702+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1703+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1704+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1705+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1706+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1707+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1708+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1709+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1710+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1711+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1712+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1713+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1714+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1715+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1716+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1717+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1718+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1719+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1720+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1721+ }, {
1722+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1723+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1724+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1725+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1726+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1727+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1728+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1729+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1730+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1731+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1732+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1733+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1734+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1735+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1736+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1737+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1738+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1739+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1740+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1741+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1742+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1743+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1744+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1745+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1746+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1747+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1748+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1749+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1750+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1751+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1752+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1753+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1754+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1755+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1756+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1757+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1758+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1759+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1760+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1761+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1762+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1763+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1764+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1765+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1766+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1767+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1768+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1769+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1770+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1771+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1772+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1773+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1774+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1775+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1776+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1777+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1778+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1779+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1780+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1781+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1782+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1783+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1784+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1785+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1786+ }, {
1787+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1788+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1789+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1790+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1791+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1792+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1793+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1794+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1795+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1796+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1797+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1798+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1799+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1800+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1801+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1802+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1803+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1804+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1805+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1806+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1807+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1808+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1809+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1810+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1811+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1812+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1813+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1814+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1815+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1816+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1817+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1818+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1819+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1820+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1821+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1822+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1823+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1824+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1825+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1826+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1827+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1828+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1829+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1830+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1831+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1832+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1833+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1834+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1835+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1836+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1837+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1838+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1839+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1840+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1841+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1842+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1843+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1844+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1845+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1846+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1847+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1848+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1849+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1850+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1851+ }
1852+ }, {
1853+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1854+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1855+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1856+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1857+ 0x9216d5d9, 0x8979fb1b
1858+ }
1859+};
1860+
1861+static unsigned char BF_itoa64[64 + 1] =
1862+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1863+
1864+static unsigned char BF_atoi64[0x60] = {
1865+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1866+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1867+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1868+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1869+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1870+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1871+};
1872+
1873+/*
1874+ * This may be optimized out if built with function inlining and no BF_ASM.
1875+ */
1876+static void clean(void *data, int size)
1877+{
1878+#if BF_ASM
1879+ extern void _BF_clean(void *data);
1880+#endif
1881+ memset(data, 0, size);
1882+#if BF_ASM
1883+ _BF_clean(data);
1884+#endif
1885+}
1886+
1887+#define BF_safe_atoi64(dst, src) \
1888+{ \
1889+ tmp = (unsigned char)(src); \
1890+ if (tmp == '$') break; \
1891+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1892+ tmp = BF_atoi64[tmp]; \
1893+ if (tmp > 63) return -1; \
1894+ (dst) = tmp; \
1895+}
1896+
1897+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1898+{
1899+ unsigned char *dptr = (unsigned char *)dst;
1900+ unsigned char *end = dptr + size;
1901+ unsigned char *sptr = (unsigned char *)src;
1902+ unsigned int tmp, c1, c2, c3, c4;
1903+
1904+ do {
1905+ BF_safe_atoi64(c1, *sptr++);
1906+ BF_safe_atoi64(c2, *sptr++);
1907+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1908+ if (dptr >= end) break;
1909+
1910+ BF_safe_atoi64(c3, *sptr++);
1911+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1912+ if (dptr >= end) break;
1913+
1914+ BF_safe_atoi64(c4, *sptr++);
1915+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1916+ } while (dptr < end);
1917+
1918+ while (dptr < end)
1919+ *dptr++ = 0;
1920+
1921+ return 0;
1922+}
1923+
1924+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1925+{
1926+ unsigned char *sptr = (unsigned char *)src;
1927+ unsigned char *end = sptr + size;
1928+ unsigned char *dptr = (unsigned char *)dst;
1929+ unsigned int c1, c2;
1930+
1931+ do {
1932+ c1 = *sptr++;
1933+ *dptr++ = BF_itoa64[c1 >> 2];
1934+ c1 = (c1 & 0x03) << 4;
1935+ if (sptr >= end) {
1936+ *dptr++ = BF_itoa64[c1];
1937+ break;
1938+ }
1939+
1940+ c2 = *sptr++;
1941+ c1 |= c2 >> 4;
1942+ *dptr++ = BF_itoa64[c1];
1943+ c1 = (c2 & 0x0f) << 2;
1944+ if (sptr >= end) {
1945+ *dptr++ = BF_itoa64[c1];
1946+ break;
1947+ }
1948+
1949+ c2 = *sptr++;
1950+ c1 |= c2 >> 6;
1951+ *dptr++ = BF_itoa64[c1];
1952+ *dptr++ = BF_itoa64[c2 & 0x3f];
1953+ } while (sptr < end);
1954+}
1955+
1956+static void BF_swap(BF_word *x, int count)
1957+{
1958+ static int endianness_check = 1;
1959+ char *is_little_endian = (char *)&endianness_check;
1960+ BF_word tmp;
1961+
1962+ if (*is_little_endian)
1963+ do {
1964+ tmp = *x;
1965+ tmp = (tmp << 16) | (tmp >> 16);
1966+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1967+ } while (--count);
1968+}
1969+
1970+#if BF_SCALE
1971+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1972+#define BF_ROUND(L, R, N) \
1973+ tmp1 = L & 0xFF; \
1974+ tmp2 = L >> 8; \
1975+ tmp2 &= 0xFF; \
1976+ tmp3 = L >> 16; \
1977+ tmp3 &= 0xFF; \
1978+ tmp4 = L >> 24; \
1979+ tmp1 = data.ctx.S[3][tmp1]; \
1980+ tmp2 = data.ctx.S[2][tmp2]; \
1981+ tmp3 = data.ctx.S[1][tmp3]; \
1982+ tmp3 += data.ctx.S[0][tmp4]; \
1983+ tmp3 ^= tmp2; \
1984+ R ^= data.ctx.P[N + 1]; \
1985+ tmp3 += tmp1; \
1986+ R ^= tmp3;
1987+#else
1988+/* Architectures with no complicated addressing modes supported */
1989+#define BF_INDEX(S, i) \
1990+ (*((BF_word *)(((unsigned char *)S) + (i))))
1991+#define BF_ROUND(L, R, N) \
1992+ tmp1 = L & 0xFF; \
1993+ tmp1 <<= 2; \
1994+ tmp2 = L >> 6; \
1995+ tmp2 &= 0x3FC; \
1996+ tmp3 = L >> 14; \
1997+ tmp3 &= 0x3FC; \
1998+ tmp4 = L >> 22; \
1999+ tmp4 &= 0x3FC; \
2000+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
2001+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
2002+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
2003+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
2004+ tmp3 ^= tmp2; \
2005+ R ^= data.ctx.P[N + 1]; \
2006+ tmp3 += tmp1; \
2007+ R ^= tmp3;
2008+#endif
2009+
2010+/*
2011+ * Encrypt one block, BF_N is hardcoded here.
2012+ */
2013+#define BF_ENCRYPT \
2014+ L ^= data.ctx.P[0]; \
2015+ BF_ROUND(L, R, 0); \
2016+ BF_ROUND(R, L, 1); \
2017+ BF_ROUND(L, R, 2); \
2018+ BF_ROUND(R, L, 3); \
2019+ BF_ROUND(L, R, 4); \
2020+ BF_ROUND(R, L, 5); \
2021+ BF_ROUND(L, R, 6); \
2022+ BF_ROUND(R, L, 7); \
2023+ BF_ROUND(L, R, 8); \
2024+ BF_ROUND(R, L, 9); \
2025+ BF_ROUND(L, R, 10); \
2026+ BF_ROUND(R, L, 11); \
2027+ BF_ROUND(L, R, 12); \
2028+ BF_ROUND(R, L, 13); \
2029+ BF_ROUND(L, R, 14); \
2030+ BF_ROUND(R, L, 15); \
2031+ tmp4 = R; \
2032+ R = L; \
2033+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2034+
2035+#if BF_ASM
2036+#define BF_body() \
2037+ _BF_body_r(&data.ctx);
2038+#else
2039+#define BF_body() \
2040+ L = R = 0; \
2041+ ptr = data.ctx.P; \
2042+ do { \
2043+ ptr += 2; \
2044+ BF_ENCRYPT; \
2045+ *(ptr - 2) = L; \
2046+ *(ptr - 1) = R; \
2047+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2048+\
2049+ ptr = data.ctx.S[0]; \
2050+ do { \
2051+ ptr += 2; \
2052+ BF_ENCRYPT; \
2053+ *(ptr - 2) = L; \
2054+ *(ptr - 1) = R; \
2055+ } while (ptr < &data.ctx.S[3][0xFF]);
2056+#endif
2057+
2058+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2059+{
2060+ __CONST char *ptr = key;
2061+ int i, j;
2062+ BF_word tmp;
2063+
2064+ for (i = 0; i < BF_N + 2; i++) {
2065+ tmp = 0;
2066+ for (j = 0; j < 4; j++) {
2067+ tmp <<= 8;
2068+ tmp |= *ptr;
2069+
2070+ if (!*ptr) ptr = key; else ptr++;
2071+ }
2072+
2073+ expanded[i] = tmp;
2074+ initial[i] = BF_init_state.P[i] ^ tmp;
2075+ }
2076+}
2077+
2078+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2079+ char *output, int size)
2080+{
2081+#if BF_ASM
2082+ extern void _BF_body_r(BF_ctx *ctx);
2083+#endif
2084+ struct {
2085+ BF_ctx ctx;
2086+ BF_key expanded_key;
2087+ union {
2088+ BF_word salt[4];
2089+ BF_word output[6];
2090+ } binary;
2091+ } data;
2092+ BF_word L, R;
2093+ BF_word tmp1, tmp2, tmp3, tmp4;
2094+ BF_word *ptr;
2095+ BF_word count;
2096+ int i;
2097+
2098+ if (size < 7 + 22 + 31 + 1) {
2099+ __set_errno(ERANGE);
2100+ return NULL;
2101+ }
2102+
2103+ if (setting[0] != '$' ||
2104+ setting[1] != '2' ||
2105+ setting[2] != 'a' ||
2106+ setting[3] != '$' ||
2107+ setting[4] < '0' || setting[4] > '3' ||
2108+ setting[5] < '0' || setting[5] > '9' ||
2109+ setting[6] != '$') {
2110+ __set_errno(EINVAL);
2111+ return NULL;
2112+ }
2113+
2114+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2115+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2116+ clean(data.binary.salt, sizeof(data.binary.salt));
2117+ __set_errno(EINVAL);
2118+ return NULL;
2119+ }
2120+
2121+ BF_swap(data.binary.salt, 4);
2122+
2123+ BF_set_key(key, data.expanded_key, data.ctx.P);
2124+
2125+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2126+
2127+ L = R = 0;
2128+ for (i = 0; i < BF_N + 2; i += 2) {
2129+ L ^= data.binary.salt[i & 2];
2130+ R ^= data.binary.salt[(i & 2) + 1];
2131+ BF_ENCRYPT;
2132+ data.ctx.P[i] = L;
2133+ data.ctx.P[i + 1] = R;
2134+ }
2135+
2136+ ptr = data.ctx.S[0];
2137+ do {
2138+ ptr += 4;
2139+ L ^= data.binary.salt[(BF_N + 2) & 3];
2140+ R ^= data.binary.salt[(BF_N + 3) & 3];
2141+ BF_ENCRYPT;
2142+ *(ptr - 4) = L;
2143+ *(ptr - 3) = R;
2144+
2145+ L ^= data.binary.salt[(BF_N + 4) & 3];
2146+ R ^= data.binary.salt[(BF_N + 5) & 3];
2147+ BF_ENCRYPT;
2148+ *(ptr - 2) = L;
2149+ *(ptr - 1) = R;
2150+ } while (ptr < &data.ctx.S[3][0xFF]);
2151+
2152+ do {
2153+ data.ctx.P[0] ^= data.expanded_key[0];
2154+ data.ctx.P[1] ^= data.expanded_key[1];
2155+ data.ctx.P[2] ^= data.expanded_key[2];
2156+ data.ctx.P[3] ^= data.expanded_key[3];
2157+ data.ctx.P[4] ^= data.expanded_key[4];
2158+ data.ctx.P[5] ^= data.expanded_key[5];
2159+ data.ctx.P[6] ^= data.expanded_key[6];
2160+ data.ctx.P[7] ^= data.expanded_key[7];
2161+ data.ctx.P[8] ^= data.expanded_key[8];
2162+ data.ctx.P[9] ^= data.expanded_key[9];
2163+ data.ctx.P[10] ^= data.expanded_key[10];
2164+ data.ctx.P[11] ^= data.expanded_key[11];
2165+ data.ctx.P[12] ^= data.expanded_key[12];
2166+ data.ctx.P[13] ^= data.expanded_key[13];
2167+ data.ctx.P[14] ^= data.expanded_key[14];
2168+ data.ctx.P[15] ^= data.expanded_key[15];
2169+ data.ctx.P[16] ^= data.expanded_key[16];
2170+ data.ctx.P[17] ^= data.expanded_key[17];
2171+
2172+ BF_body();
2173+
2174+ tmp1 = data.binary.salt[0];
2175+ tmp2 = data.binary.salt[1];
2176+ tmp3 = data.binary.salt[2];
2177+ tmp4 = data.binary.salt[3];
2178+ data.ctx.P[0] ^= tmp1;
2179+ data.ctx.P[1] ^= tmp2;
2180+ data.ctx.P[2] ^= tmp3;
2181+ data.ctx.P[3] ^= tmp4;
2182+ data.ctx.P[4] ^= tmp1;
2183+ data.ctx.P[5] ^= tmp2;
2184+ data.ctx.P[6] ^= tmp3;
2185+ data.ctx.P[7] ^= tmp4;
2186+ data.ctx.P[8] ^= tmp1;
2187+ data.ctx.P[9] ^= tmp2;
2188+ data.ctx.P[10] ^= tmp3;
2189+ data.ctx.P[11] ^= tmp4;
2190+ data.ctx.P[12] ^= tmp1;
2191+ data.ctx.P[13] ^= tmp2;
2192+ data.ctx.P[14] ^= tmp3;
2193+ data.ctx.P[15] ^= tmp4;
2194+ data.ctx.P[16] ^= tmp1;
2195+ data.ctx.P[17] ^= tmp2;
2196+
2197+ BF_body();
2198+ } while (--count);
2199+
2200+ for (i = 0; i < 6; i += 2) {
2201+ L = BF_magic_w[i];
2202+ R = BF_magic_w[i + 1];
2203+
2204+ count = 64;
2205+ do {
2206+ BF_ENCRYPT;
2207+ } while (--count);
2208+
2209+ data.binary.output[i] = L;
2210+ data.binary.output[i + 1] = R;
2211+ }
2212+
2213+ memcpy(output, setting, 7 + 22 - 1);
2214+ output[7 + 22 - 1] = BF_itoa64[(int)
2215+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2216+
2217+/* This has to be bug-compatible with the original implementation, so
2218+ * only encode 23 of the 24 bytes. :-) */
2219+ BF_swap(data.binary.output, 6);
2220+ BF_encode(&output[7 + 22], data.binary.output, 23);
2221+ output[7 + 22 + 31] = '\0';
2222+
2223+/* Overwrite the most obvious sensitive data we have on the stack. Note
2224+ * that this does not guarantee there's no sensitive data left on the
2225+ * stack and/or in registers; I'm not aware of portable code that does. */
2226+ clean(&data, sizeof(data));
2227+
2228+ return output;
2229+}
2230+
2231+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2232+ __CONST char *input, int size, char *output, int output_size)
2233+{
2234+ if (size < 16 || output_size < 7 + 22 + 1 ||
2235+ (count && (count < 4 || count > 31))) {
2236+ if (output_size > 0) output[0] = '\0';
2237+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2238+ return NULL;
2239+ }
2240+
2241+ if (!count) count = 5;
2242+
2243+ output[0] = '$';
2244+ output[1] = '2';
2245+ output[2] = 'a';
2246+ output[3] = '$';
2247+ output[4] = '0' + count / 10;
2248+ output[5] = '0' + count % 10;
2249+ output[6] = '$';
2250+
2251+ BF_encode(&output[7], (BF_word *)input, 16);
2252+ output[7 + 22] = '\0';
2253+
2254+ return output;
2255+}
2256diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.10/ext/standard/crypt.c
2257--- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100
2258+++ hardening-patch-4.4.2-0.4.10/ext/standard/crypt.c 2006-05-11 10:36:02.000000000 +0200
2259@@ -100,6 +100,8 @@
2260 return SUCCESS;
2261 }
2262
2263+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2264+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2265
2266 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2267
2268@@ -135,7 +137,14 @@
2269
2270 /* The automatic salt generation only covers standard DES and md5-crypt */
2271 if(!*salt) {
2272-#if PHP_MD5_CRYPT
2273+#if PHP_BLOWFISH_CRYPT
2274+ char randat[16];
2275+ int i;
2276+
2277+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2278+
2279+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2280+#elif PHP_MD5_CRYPT
2281 strcpy(salt, "$1$");
2282 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2283 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2284@@ -145,8 +154,24 @@
2285 salt[2] = '\0';
2286 #endif
2287 }
2288-
2289- RETVAL_STRING(crypt(str, salt), 1);
2290+
2291+ if (salt[0] == '$' &&
2292+ salt[1] == '2' &&
2293+ salt[2] == 'a' &&
2294+ salt[3] == '$' &&
2295+ salt[4] >= '0' && salt[4] <= '3' &&
2296+ salt[5] >= '0' && salt[5] <= '9' &&
2297+ salt[6] == '$') {
2298+
2299+ char output[PHP_MAX_SALT_LEN+1];
2300+
2301+ output[0] = 0;
2302+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2303+ RETVAL_STRING(output, 1);
2304+
2305+ } else {
2306+ RETVAL_STRING(crypt(str, salt), 1);
2307+ }
2308 }
2309 /* }}} */
2310 #endif
2311diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.10/ext/standard/dl.c
2312--- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100
2313+++ hardening-patch-4.4.2-0.4.10/ext/standard/dl.c 2006-05-11 10:36:02.000000000 +0200
2314@@ -160,8 +160,35 @@
2315 RETURN_FALSE;
2316 }
2317 module_entry = get_module();
2318+
2319+ /* check if Hardening-Patch is installed */
2320+ if (module_entry->zend_api < 1000000000) {
2321+ php_error_docref(NULL TSRMLS_CC, error_type,
2322+ "%s: Unable to initialize module\n"
2323+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2324+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2325+ "These options need to match\n",
2326+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2327+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2328+ DL_UNLOAD(handle);
2329+ RETURN_FALSE;
2330+ }
2331+
2332+ /* check if correct Hardening-Patch is installed */
2333+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2334+ php_error_docref(NULL TSRMLS_CC, error_type,
2335+ "%s: Unable to initialize module\n"
2336+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2337+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2338+ "These options need to match\n",
2339+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2340+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2341+ DL_UNLOAD(handle);
2342+ RETURN_FALSE;
2343+ }
2344+
2345 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2346- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2347+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2348 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2349 struct pre_4_1_0_module_entry {
2350 char *name;
2351@@ -195,7 +222,7 @@
2352 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2353 } else {
2354 name = module_entry->name;
2355- zend_api = module_entry->zend_api;
2356+ zend_api = module_entry->real_zend_api;
2357 zend_debug = module_entry->zend_debug;
2358 zts = module_entry->zts;
2359 }
2360diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.10/ext/standard/file.c
2361--- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100
2362+++ hardening-patch-4.4.2-0.4.10/ext/standard/file.c 2006-05-11 10:36:02.000000000 +0200
2363@@ -21,7 +21,7 @@
2364 +----------------------------------------------------------------------+
2365 */
2366
2367-/* $Id: file.c,v 1.279.2.70.2.3 2006/01/01 13:46:57 sniper Exp $ */
2368+/* $Id: file.c,v 1.279.2.70.2.7 2006/04/14 17:46:59 pollita Exp $ */
2369
2370 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
2371
2372@@ -552,7 +552,7 @@
2373 pval **arg1, **arg2;
2374 char *d;
2375 char *opened_path;
2376- char p[64];
2377+ char *p;
2378 FILE *fp;
2379
2380 if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
2381@@ -566,7 +566,11 @@
2382 }
2383
2384 d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1));
2385- strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p));
2386+
2387+ p = php_basename(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2), NULL, 0);
2388+ if (strlen(p) > 64) {
2389+ p[63] = '\0';
2390+ }
2391
2392 if ((fp = php_open_temporary_file(d, p, &opened_path TSRMLS_CC))) {
2393 fclose(fp);
2394@@ -574,6 +578,7 @@
2395 } else {
2396 RETVAL_FALSE;
2397 }
2398+ efree(p);
2399 efree(d);
2400 }
2401 /* }}} */
2402@@ -819,7 +824,7 @@
2403
2404 /* If seconds is not set to null, build the timeval, else we wait indefinitely */
2405 if (sec != NULL) {
2406- convert_to_long_ex(&sec);
2407+ convert_to_long(sec);
2408
2409 if (usec > 999999) {
2410 tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000);
2411@@ -2196,7 +2201,7 @@
2412 safe_to_copy:
2413
2414 srcstream = php_stream_open_wrapper(src, "rb",
2415- STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS,
2416+ ENFORCE_SAFE_MODE | REPORT_ERRORS,
2417 NULL);
2418
2419 if (!srcstream)
2420@@ -2522,7 +2527,7 @@
2421 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2422 /* {{{ proto string realpath(string path)
2423 Return the resolved path */
2424-PHP_FUNCTION(realpath)
2425+PHP_FUNCTION(real_path)
2426 {
2427 zval **path;
2428 char resolved_path_buff[MAXPATHLEN];
2429diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.10/ext/standard/file.h
2430--- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100
2431+++ hardening-patch-4.4.2-0.4.10/ext/standard/file.h 2006-05-11 10:36:02.000000000 +0200
2432@@ -64,7 +64,7 @@
2433 PHP_FUNCTION(fd_set);
2434 PHP_FUNCTION(fd_isset);
2435 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2436-PHP_FUNCTION(realpath);
2437+PHP_FUNCTION(real_path);
2438 #endif
2439 #ifdef HAVE_FNMATCH
2440 PHP_FUNCTION(fnmatch);
2441diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.10/ext/standard/head.c
2442--- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100
2443+++ hardening-patch-4.4.2-0.4.10/ext/standard/head.c 2006-05-11 10:36:02.000000000 +0200
2444@@ -44,7 +44,7 @@
2445 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2446 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2447 return;
2448-
2449+
2450 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2451 }
2452 /* }}} */
2453diff -Nura php-4.4.2/ext/standard/html.c hardening-patch-4.4.2-0.4.10/ext/standard/html.c
2454--- php-4.4.2/ext/standard/html.c 2006-01-01 14:46:57.000000000 +0100
2455+++ hardening-patch-4.4.2-0.4.10/ext/standard/html.c 2006-05-11 10:36:02.000000000 +0200
2456@@ -18,7 +18,7 @@
2457 +----------------------------------------------------------------------+
2458 */
2459
2460-/* $Id: html.c,v 1.63.2.23.2.1 2006/01/01 13:46:57 sniper Exp $ */
2461+/* $Id: html.c,v 1.63.2.23.2.2 2006/02/25 21:33:06 rasmus Exp $ */
2462
2463 /*
2464 * HTML entity resources:
2465@@ -793,7 +793,7 @@
2466 enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC);
2467 unsigned char replacement[15];
2468
2469- ret = estrdup(old);
2470+ ret = estrndup(old, oldlen);
2471 retlen = oldlen;
2472 if (!retlen) {
2473 goto empty_source;
2474diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.10/ext/standard/info.c
2475--- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100
2476+++ hardening-patch-4.4.2-0.4.10/ext/standard/info.c 2006-05-11 10:38:59.000000000 +0200
2477@@ -58,6 +58,23 @@
2478
2479 PHPAPI extern char *php_ini_opened_path;
2480 PHPAPI extern char *php_ini_scanned_files;
2481+
2482+static int php_info_write_wrapper(const char *str, uint str_length)
2483+{
2484+ int new_len, written;
2485+ char *elem_esc;
2486+
2487+ TSRMLS_FETCH();
2488+
2489+ elem_esc = php_escape_html_entities((char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
2490+
2491+ written = php_body_write(elem_esc, new_len TSRMLS_CC);
2492+
2493+ efree(elem_esc);
2494+
2495+ return written;
2496+}
2497+
2498
2499 /* {{{ _display_module_info
2500 */
2501@@ -133,23 +150,12 @@
2502 PUTS(" => ");
2503 }
2504 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
2505- zval *tmp3;
2506- MAKE_STD_ZVAL(tmp3);
2507 if (!sapi_module.phpinfo_as_text) {
2508 PUTS("<pre>");
2509- }
2510- php_start_ob_buffer(NULL, 4096, 1 TSRMLS_CC);
2511- zend_print_zval_r(*tmp, 0);
2512- php_ob_get_buffer(tmp3 TSRMLS_CC);
2513- php_end_ob_buffer(0, 0 TSRMLS_CC);
2514-
2515- elem_esc = php_info_html_esc(Z_STRVAL_P(tmp3) TSRMLS_CC);
2516- PUTS(elem_esc);
2517- efree(elem_esc);
2518- zval_ptr_dtor(&tmp3);
2519-
2520- if (!sapi_module.phpinfo_as_text) {
2521+ zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
2522 PUTS("</pre>");
2523+ } else {
2524+ zend_print_zval_r(*tmp, 0);
2525 }
2526 } else if (Z_TYPE_PP(tmp) != IS_STRING) {
2527 tmp2 = **tmp;
2528@@ -408,7 +414,7 @@
2529
2530 if (flag & PHP_INFO_GENERAL) {
2531 char *zend_version = get_zend_version();
2532- char temp_api[9];
2533+ char temp_api[11];
2534
2535 php_uname = php_get_uname('a');
2536
2537@@ -430,11 +436,22 @@
2538 }
2539 }
2540
2541+#if HARDENING_PATCH
2542+ if (!sapi_module.phpinfo_as_text) {
2543+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2544+ } else {
2545+ char temp_ver[40];
2546+
2547+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2548+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2549+ }
2550+#else
2551 if (!sapi_module.phpinfo_as_text) {
2552 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2553 } else {
2554 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2555 }
2556+#endif
2557 php_info_print_box_end();
2558 php_info_print_table_start();
2559 php_info_print_table_row(2, "System", php_uname );
2560diff -Nura php-4.4.2/ext/standard/pack.c hardening-patch-4.4.2-0.4.10/ext/standard/pack.c
2561--- php-4.4.2/ext/standard/pack.c 2006-01-01 14:46:57.000000000 +0100
2562+++ hardening-patch-4.4.2-0.4.10/ext/standard/pack.c 2006-05-11 10:36:02.000000000 +0200
2563@@ -15,7 +15,7 @@
2564 | Author: Chris Schneider <cschneid@relog.ch> |
2565 +----------------------------------------------------------------------+
2566 */
2567-/* $Id: pack.c,v 1.40.2.7.2.4 2006/01/01 13:46:57 sniper Exp $ */
2568+/* $Id: pack.c,v 1.40.2.7.2.5 2006/01/26 15:47:31 iliaa Exp $ */
2569
2570 #include "php.h"
2571
2572@@ -693,7 +693,9 @@
2573 len = size * 2;
2574 }
2575
2576- len -= argb % 2;
2577+ if (argb > 0) {
2578+ len -= argb % 2;
2579+ }
2580
2581 buf = emalloc(len + 1);
2582
2583diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.10/ext/standard/php_standard.h
2584--- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100
2585+++ hardening-patch-4.4.2-0.4.10/ext/standard/php_standard.h 2006-05-11 10:36:02.000000000 +0200
2586@@ -28,6 +28,7 @@
2587 #include "php_mail.h"
2588 #include "md5.h"
2589 #include "sha1.h"
2590+#include "sha256.h"
2591 #include "html.h"
2592 #include "exec.h"
2593 #include "file.h"
2594diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.10/ext/standard/sha256.c
2595--- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2596+++ hardening-patch-4.4.2-0.4.10/ext/standard/sha256.c 2006-05-11 10:36:02.000000000 +0200
2597@@ -0,0 +1,398 @@
2598+/*
2599+ +----------------------------------------------------------------------+
2600+ | PHP Version 5 |
2601+ +----------------------------------------------------------------------+
2602+ | Copyright (c) 1997-2004 The PHP Group |
2603+ +----------------------------------------------------------------------+
2604+ | This source file is subject to version 3.0 of the PHP license, |
2605+ | that is bundled with this package in the file LICENSE, and is |
2606+ | available through the world-wide-web at the following url: |
2607+ | http://www.php.net/license/3_0.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+
2616+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2617+
2618+#include <stdio.h>
2619+#include "php.h"
2620+
2621+/* This code is heavily based on the PHP md5/sha1 implementations */
2622+
2623+#include "sha256.h"
2624+
2625+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2626+{
2627+ int i;
2628+
2629+ for (i = 0; i < 32; i++) {
2630+ sprintf(sha256str, "%02x", digest[i]);
2631+ sha256str += 2;
2632+ }
2633+
2634+ *sha256str = '\0';
2635+}
2636+
2637+/* {{{ proto string sha256(string str [, bool raw_output])
2638+ Calculate the sha256 hash of a string */
2639+PHP_FUNCTION(sha256)
2640+{
2641+ char *arg;
2642+ int arg_len;
2643+ zend_bool raw_output = 0;
2644+ char sha256str[65];
2645+ PHP_SHA256_CTX context;
2646+ unsigned char digest[32];
2647+
2648+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2649+ return;
2650+ }
2651+
2652+ sha256str[0] = '\0';
2653+ PHP_SHA256Init(&context);
2654+ PHP_SHA256Update(&context, arg, arg_len);
2655+ PHP_SHA256Final(digest, &context);
2656+ if (raw_output) {
2657+ RETURN_STRINGL(digest, 32, 1);
2658+ } else {
2659+ make_sha256_digest(sha256str, digest);
2660+ RETVAL_STRING(sha256str, 1);
2661+ }
2662+
2663+}
2664+
2665+/* }}} */
2666+
2667+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2668+ Calculate the sha256 hash of given filename */
2669+PHP_FUNCTION(sha256_file)
2670+{
2671+ char *arg;
2672+ int arg_len;
2673+ zend_bool raw_output = 0;
2674+ char sha256str[65];
2675+ unsigned char buf[1024];
2676+ unsigned char digest[32];
2677+ PHP_SHA256_CTX context;
2678+ int n;
2679+ FILE *fp;
2680+
2681+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2682+ return;
2683+ }
2684+
2685+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2686+ RETURN_FALSE;
2687+ }
2688+
2689+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2690+ RETURN_FALSE;
2691+ }
2692+
2693+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2694+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2695+ RETURN_FALSE;
2696+ }
2697+
2698+ PHP_SHA256Init(&context);
2699+
2700+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2701+ PHP_SHA256Update(&context, buf, n);
2702+ }
2703+
2704+ PHP_SHA256Final(digest, &context);
2705+
2706+ if (ferror(fp)) {
2707+ fclose(fp);
2708+ RETURN_FALSE;
2709+ }
2710+
2711+ fclose(fp);
2712+
2713+ if (raw_output) {
2714+ RETURN_STRINGL(digest, 32, 1);
2715+ } else {
2716+ make_sha256_digest(sha256str, digest);
2717+ RETVAL_STRING(sha256str, 1);
2718+ }
2719+}
2720+/* }}} */
2721+
2722+
2723+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2724+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2725+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2726+
2727+static unsigned char PADDING[64] =
2728+{
2729+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2730+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2731+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2732+};
2733+
2734+/* F, G, H and I are basic SHA256 functions.
2735+ */
2736+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2737+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2738+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2739+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2740+
2741+/* ROTATE_RIGHT rotates x right n bits.
2742+ */
2743+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2744+
2745+/* W[i]
2746+ */
2747+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2748+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2749+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2750+
2751+/* ROUND function of sha256
2752+ */
2753+
2754+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2755+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2756+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2757+ (d) += t1; \
2758+ }
2759+
2760+
2761+/* {{{ PHP_SHA256Init
2762+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2763+ */
2764+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2765+{
2766+ context->count[0] = context->count[1] = 0;
2767+ /* Load magic initialization constants.
2768+ */
2769+ context->state[0] = 0x6a09e667;
2770+ context->state[1] = 0xbb67ae85;
2771+ context->state[2] = 0x3c6ef372;
2772+ context->state[3] = 0xa54ff53a;
2773+ context->state[4] = 0x510e527f;
2774+ context->state[5] = 0x9b05688c;
2775+ context->state[6] = 0x1f83d9ab;
2776+ context->state[7] = 0x5be0cd19;
2777+}
2778+/* }}} */
2779+
2780+/* {{{ PHP_SHA256Update
2781+ SHA256 block update operation. Continues an SHA256 message-digest
2782+ operation, processing another message block, and updating the
2783+ context.
2784+ */
2785+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2786+ unsigned int inputLen)
2787+{
2788+ unsigned int i, index, partLen;
2789+
2790+ /* Compute number of bytes mod 64 */
2791+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2792+
2793+ /* Update number of bits */
2794+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2795+ < ((php_uint32) inputLen << 3))
2796+ context->count[1]++;
2797+ context->count[1] += ((php_uint32) inputLen >> 29);
2798+
2799+ partLen = 64 - index;
2800+
2801+ /* Transform as many times as possible.
2802+ */
2803+ if (inputLen >= partLen) {
2804+ memcpy
2805+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2806+ SHA256Transform(context->state, context->buffer);
2807+
2808+ for (i = partLen; i + 63 < inputLen; i += 64)
2809+ SHA256Transform(context->state, &input[i]);
2810+
2811+ index = 0;
2812+ } else
2813+ i = 0;
2814+
2815+ /* Buffer remaining input */
2816+ memcpy
2817+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2818+ inputLen - i);
2819+}
2820+/* }}} */
2821+
2822+/* {{{ PHP_SHA256Final
2823+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2824+ the message digest and zeroizing the context.
2825+ */
2826+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2827+{
2828+ unsigned char bits[8];
2829+ unsigned int index, padLen;
2830+
2831+ /* Save number of bits */
2832+ bits[7] = context->count[0] & 0xFF;
2833+ bits[6] = (context->count[0] >> 8) & 0xFF;
2834+ bits[5] = (context->count[0] >> 16) & 0xFF;
2835+ bits[4] = (context->count[0] >> 24) & 0xFF;
2836+ bits[3] = context->count[1] & 0xFF;
2837+ bits[2] = (context->count[1] >> 8) & 0xFF;
2838+ bits[1] = (context->count[1] >> 16) & 0xFF;
2839+ bits[0] = (context->count[1] >> 24) & 0xFF;
2840+
2841+ /* Pad out to 56 mod 64.
2842+ */
2843+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2844+ padLen = (index < 56) ? (56 - index) : (120 - index);
2845+ PHP_SHA256Update(context, PADDING, padLen);
2846+
2847+ /* Append length (before padding) */
2848+ PHP_SHA256Update(context, bits, 8);
2849+
2850+ /* Store state in digest */
2851+ SHA256Encode(digest, context->state, 32);
2852+
2853+ /* Zeroize sensitive information.
2854+ */
2855+ memset((unsigned char*) context, 0, sizeof(*context));
2856+}
2857+/* }}} */
2858+
2859+/* {{{ SHA256Transform
2860+ * SHA256 basic transformation. Transforms state based on block.
2861+ */
2862+static void SHA256Transform(state, block)
2863+php_uint32 state[8];
2864+const unsigned char block[64];
2865+{
2866+ php_uint32 a = state[0], b = state[1], c = state[2];
2867+ php_uint32 d = state[3], e = state[4], f = state[5];
2868+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2869+
2870+ SHA256Decode(x, block, 64);
2871+
2872+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2873+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2874+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2875+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2876+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2877+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2878+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2879+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2880+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2881+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2882+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2883+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2884+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2885+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2886+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2887+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2888+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2889+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2890+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2891+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2892+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2893+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2894+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2895+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2896+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2897+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2898+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2899+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2900+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2901+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2902+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2903+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2904+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2905+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2906+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2907+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2908+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2909+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2910+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2911+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2912+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2913+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2914+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2915+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2916+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2917+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2918+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2919+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2920+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2921+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2922+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2923+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2924+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2925+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2926+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2927+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2928+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2929+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2930+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2931+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2932+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2933+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2934+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2935+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2936+
2937+ state[0] += a;
2938+ state[1] += b;
2939+ state[2] += c;
2940+ state[3] += d;
2941+ state[4] += e;
2942+ state[5] += f;
2943+ state[6] += g;
2944+ state[7] += h;
2945+
2946+ /* Zeroize sensitive information. */
2947+ memset((unsigned char*) x, 0, sizeof(x));
2948+}
2949+/* }}} */
2950+
2951+/* {{{ SHA256Encode
2952+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2953+ a multiple of 4.
2954+ */
2955+static void SHA256Encode(output, input, len)
2956+unsigned char *output;
2957+php_uint32 *input;
2958+unsigned int len;
2959+{
2960+ unsigned int i, j;
2961+
2962+ for (i = 0, j = 0; j < len; i++, j += 4) {
2963+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2964+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2965+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2966+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2967+ }
2968+}
2969+/* }}} */
2970+
2971+/* {{{ SHA256Decode
2972+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2973+ a multiple of 4.
2974+ */
2975+static void SHA256Decode(output, input, len)
2976+php_uint32 *output;
2977+const unsigned char *input;
2978+unsigned int len;
2979+{
2980+ unsigned int i, j;
2981+
2982+ for (i = 0, j = 0; j < len; i++, j += 4)
2983+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2984+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2985+}
2986+/* }}} */
2987+
2988+/*
2989+ * Local variables:
2990+ * tab-width: 4
2991+ * c-basic-offset: 4
2992+ * End:
2993+ * vim600: sw=4 ts=4 fdm=marker
2994+ * vim<600: sw=4 ts=4
2995+ */
2996diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.10/ext/standard/sha256.h
2997--- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2998+++ hardening-patch-4.4.2-0.4.10/ext/standard/sha256.h 2006-05-11 10:36:02.000000000 +0200
2999@@ -0,0 +1,40 @@
3000+/*
3001+ +----------------------------------------------------------------------+
3002+ | PHP Version 5 |
3003+ +----------------------------------------------------------------------+
3004+ | Copyright (c) 1997-2004 The PHP Group |
3005+ +----------------------------------------------------------------------+
3006+ | This source file is subject to version 3.0 of the PHP license, |
3007+ | that is bundled with this package in the file LICENSE, and is |
3008+ | available through the world-wide-web at the following url: |
3009+ | http://www.php.net/license/3_0.txt. |
3010+ | If you did not receive a copy of the PHP license and are unable to |
3011+ | obtain it through the world-wide-web, please send a note to |
3012+ | license@php.net so we can mail you a copy immediately. |
3013+ +----------------------------------------------------------------------+
3014+ | Author: Stefan Esser <sesser@php.net> |
3015+ +----------------------------------------------------------------------+
3016+*/
3017+
3018+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
3019+
3020+#ifndef SHA256_H
3021+#define SHA256_H
3022+
3023+#include "ext/standard/basic_functions.h"
3024+
3025+/* SHA1 context. */
3026+typedef struct {
3027+ php_uint32 state[8]; /* state (ABCD) */
3028+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
3029+ unsigned char buffer[64]; /* input buffer */
3030+} PHP_SHA256_CTX;
3031+
3032+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
3033+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
3034+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
3035+
3036+PHP_FUNCTION(sha256);
3037+PHP_FUNCTION(sha256_file);
3038+
3039+#endif
3040diff -Nura php-4.4.2/ext/standard/string.c hardening-patch-4.4.2-0.4.10/ext/standard/string.c
3041--- php-4.4.2/ext/standard/string.c 2006-01-01 14:46:58.000000000 +0100
3042+++ hardening-patch-4.4.2-0.4.10/ext/standard/string.c 2006-05-11 10:36:02.000000000 +0200
3043@@ -18,7 +18,7 @@
3044 +----------------------------------------------------------------------+
3045 */
3046
3047-/* $Id: string.c,v 1.333.2.52.2.3 2006/01/01 13:46:58 sniper Exp $ */
3048+/* $Id: string.c,v 1.333.2.52.2.4 2006/03/13 14:41:27 iliaa Exp $ */
3049
3050 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
3051
3052@@ -672,15 +672,13 @@
3053 /* Multiple character line break or forced cut */
3054 if (linelength > 0) {
3055 chk = (int)(textlen/linelength + 1);
3056+ newtext = safe_emalloc(chk, breakcharlen, textlen + 1);
3057 alloced = textlen + chk * breakcharlen + 1;
3058 } else {
3059 chk = textlen;
3060+ newtext = safe_emalloc(textlen, (breakcharlen + 1), 1);
3061 alloced = textlen * (breakcharlen + 1) + 1;
3062 }
3063- if (alloced <= 0) {
3064- RETURN_FALSE;
3065- }
3066- newtext = emalloc(alloced);
3067
3068 /* now keep track of the actual new text length */
3069 newtextlen = 0;
3070diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.10/ext/standard/syslog.c
3071--- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100
3072+++ hardening-patch-4.4.2-0.4.10/ext/standard/syslog.c 2006-05-11 10:36:02.000000000 +0200
3073@@ -42,6 +42,8 @@
3074 */
3075 PHP_MINIT_FUNCTION(syslog)
3076 {
3077+
3078+#if !HARDENING_PATCH
3079 /* error levels */
3080 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
3081 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
3082@@ -97,7 +99,7 @@
3083 /* AIX doesn't have LOG_PERROR */
3084 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
3085 #endif
3086-
3087+#endif
3088 return SUCCESS;
3089 }
3090 /* }}} */
3091diff -Nura php-4.4.2/ext/standard/url.c hardening-patch-4.4.2-0.4.10/ext/standard/url.c
3092--- php-4.4.2/ext/standard/url.c 2006-01-01 14:46:58.000000000 +0100
3093+++ hardening-patch-4.4.2-0.4.10/ext/standard/url.c 2006-05-11 10:36:02.000000000 +0200
3094@@ -15,7 +15,7 @@
3095 | Author: Jim Winstead <jimw@php.net> |
3096 +----------------------------------------------------------------------+
3097 */
3098-/* $Id: url.c,v 1.58.2.21.2.2 2006/01/01 13:46:58 sniper Exp $ */
3099+/* $Id: url.c,v 1.58.2.21.2.3 2006/02/12 16:43:03 iliaa Exp $ */
3100
3101 #include <stdlib.h>
3102 #include <string.h>
3103@@ -137,7 +137,7 @@
3104 p++;
3105 }
3106
3107- if ((*p) == '\0' || *p == '/') {
3108+ if ((*p == '\0' || *p == '/') && (p - e) < 7) {
3109 goto parse_port;
3110 }
3111
3112diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.10/ext/varfilter/config.m4
3113--- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
3114+++ hardening-patch-4.4.2-0.4.10/ext/varfilter/config.m4 2006-05-11 10:36:02.000000000 +0200
3115@@ -0,0 +1,11 @@
3116+dnl
3117+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
3118+dnl
3119+
3120+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
3121+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
3122+
3123+if test "$PHP_VARFILTER" != "no"; then
3124+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
3125+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
3126+fi
3127diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.10/ext/varfilter/CREDITS
3128--- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
3129+++ hardening-patch-4.4.2-0.4.10/ext/varfilter/CREDITS 2006-05-11 10:36:02.000000000 +0200
3130@@ -0,0 +1,2 @@
3131+varfilter
3132+Stefan Esser
3133\ Kein Zeilenumbruch am Dateiende.
3134diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.10/ext/varfilter/php_varfilter.h
3135--- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
3136+++ hardening-patch-4.4.2-0.4.10/ext/varfilter/php_varfilter.h 2006-05-11 10:36:02.000000000 +0200
3137@@ -0,0 +1,144 @@
3138+/*
3139+ +----------------------------------------------------------------------+
3140+ | Hardened-PHP Project's varfilter extension |
3141+ +----------------------------------------------------------------------+
3142+ | Copyright (c) 2004-2005 Stefan Esser |
3143+ +----------------------------------------------------------------------+
3144+ | This source file is subject to version 2.02 of the PHP license, |
3145+ | that is bundled with this package in the file LICENSE, and is |
3146+ | available at through the world-wide-web at |
3147+ | http://www.php.net/license/2_02.txt. |
3148+ | If you did not receive a copy of the PHP license and are unable to |
3149+ | obtain it through the world-wide-web, please send a note to |
3150+ | license@php.net so we can mail you a copy immediately. |
3151+ +----------------------------------------------------------------------+
3152+ | Author: Stefan Esser <sesser@hardened-php.net> |
3153+ +----------------------------------------------------------------------+
3154+
3155+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
3156+*/
3157+
3158+#ifndef PHP_VARFILTER_H
3159+#define PHP_VARFILTER_H
3160+
3161+extern zend_module_entry varfilter_module_entry;
3162+#define phpext_varfilter_ptr &varfilter_module_entry
3163+
3164+#ifdef PHP_WIN32
3165+#define PHP_VARFILTER_API __declspec(dllexport)
3166+#else
3167+#define PHP_VARFILTER_API
3168+#endif
3169+
3170+#ifdef ZTS
3171+#include "TSRM.h"
3172+#endif
3173+
3174+#include "SAPI.h"
3175+
3176+#include "php_variables.h"
3177+
3178+#ifdef ZEND_ENGINE_2
3179+#define HASH_HTTP_GET_VARS 0x2095733f
3180+#define HASH_HTTP_POST_VARS 0xbfee1265
3181+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
3182+#define HASH_HTTP_ENV_VARS 0x1fe186a8
3183+#define HASH_HTTP_SERVER_VARS 0xc987afd6
3184+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
3185+#define HASH_HTTP_POST_FILES 0x98eb1ddc
3186+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
3187+#else
3188+#define HASH_HTTP_GET_VARS 0x8d8645bd
3189+#define HASH_HTTP_POST_VARS 0x7c699bf3
3190+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
3191+#define HASH_HTTP_ENV_VARS 0x84da3016
3192+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
3193+#define HASH_HTTP_SESSION_VARS 0x322906f5
3194+#define HASH_HTTP_POST_FILES 0xe4e4ce70
3195+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
3196+#endif
3197+
3198+PHP_MINIT_FUNCTION(varfilter);
3199+PHP_MSHUTDOWN_FUNCTION(varfilter);
3200+PHP_RINIT_FUNCTION(varfilter);
3201+PHP_RSHUTDOWN_FUNCTION(varfilter);
3202+PHP_MINFO_FUNCTION(varfilter);
3203+
3204+
3205+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3206+/* request variables */
3207+ long max_request_variables;
3208+ long cur_request_variables;
3209+ long max_varname_length;
3210+ long max_totalname_length;
3211+ long max_value_length;
3212+ long max_array_depth;
3213+ long max_array_index_length;
3214+ zend_bool disallow_nul;
3215+/* cookie variables */
3216+ long max_cookie_vars;
3217+ long cur_cookie_vars;
3218+ long max_cookie_name_length;
3219+ long max_cookie_totalname_length;
3220+ long max_cookie_value_length;
3221+ long max_cookie_array_depth;
3222+ long max_cookie_array_index_length;
3223+ zend_bool disallow_cookie_nul;
3224+/* get variables */
3225+ long max_get_vars;
3226+ long cur_get_vars;
3227+ long max_get_name_length;
3228+ long max_get_totalname_length;
3229+ long max_get_value_length;
3230+ long max_get_array_depth;
3231+ long max_get_array_index_length;
3232+ zend_bool disallow_get_nul;
3233+/* post variables */
3234+ long max_post_vars;
3235+ long cur_post_vars;
3236+ long max_post_name_length;
3237+ long max_post_totalname_length;
3238+ long max_post_value_length;
3239+ long max_post_array_depth;
3240+ long max_post_array_index_length;
3241+ zend_bool disallow_post_nul;
3242+/* fileupload */
3243+ long max_uploads;
3244+ long cur_uploads;
3245+ zend_bool disallow_elf_files;
3246+ char *verification_script;
3247+
3248+ zend_bool no_more_variables;
3249+ zend_bool no_more_get_variables;
3250+ zend_bool no_more_post_variables;
3251+ zend_bool no_more_cookie_variables;
3252+ zend_bool no_more_uploads;
3253+
3254+ZEND_END_MODULE_GLOBALS(varfilter)
3255+
3256+
3257+#ifdef ZTS
3258+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3259+#else
3260+#define VARFILTER_G(v) (varfilter_globals.v)
3261+#endif
3262+
3263+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3264+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3265+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3266+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3267+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3268+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3269+
3270+
3271+
3272+#endif /* PHP_VARFILTER_H */
3273+
3274+
3275+/*
3276+ * Local variables:
3277+ * tab-width: 4
3278+ * c-basic-offset: 4
3279+ * indent-tabs-mode: t
3280+ * End:
3281+ */
3282diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.10/ext/varfilter/varfilter.c
3283--- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3284+++ hardening-patch-4.4.2-0.4.10/ext/varfilter/varfilter.c 2006-05-11 10:37:14.000000000 +0200
3285@@ -0,0 +1,915 @@
3286+/*
3287+ +----------------------------------------------------------------------+
3288+ | Hardened-PHP Project's varfilter extension |
3289+ +----------------------------------------------------------------------+
3290+ | Copyright (c) 2004-2005 Stefan Esser |
3291+ +----------------------------------------------------------------------+
3292+ | This source file is subject to version 2.02 of the PHP license, |
3293+ | that is bundled with this package in the file LICENSE, and is |
3294+ | available at through the world-wide-web at |
3295+ | http://www.php.net/license/2_02.txt. |
3296+ | If you did not receive a copy of the PHP license and are unable to |
3297+ | obtain it through the world-wide-web, please send a note to |
3298+ | license@php.net so we can mail you a copy immediately. |
3299+ +----------------------------------------------------------------------+
3300+ | Author: Stefan Esser <sesser@hardened-php.net> |
3301+ +----------------------------------------------------------------------+
3302+
3303+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3304+*/
3305+
3306+#ifdef HAVE_CONFIG_H
3307+#include "config.h"
3308+#endif
3309+
3310+#include "php.h"
3311+#include "php_ini.h"
3312+#include "ext/standard/info.h"
3313+#include "php_varfilter.h"
3314+#include "hardening_patch.h"
3315+
3316+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3317+
3318+/* True global resources - no need for thread safety here */
3319+static int le_varfilter;
3320+
3321+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3322+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3323+static zend_bool hooked = 0;
3324+
3325+/* {{{ varfilter_module_entry
3326+ */
3327+zend_module_entry varfilter_module_entry = {
3328+#if ZEND_MODULE_API_NO >= 20010901
3329+ STANDARD_MODULE_HEADER,
3330+#endif
3331+ "varfilter",
3332+ NULL,
3333+ PHP_MINIT(varfilter),
3334+ PHP_MSHUTDOWN(varfilter),
3335+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3336+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3337+ PHP_MINFO(varfilter),
3338+#if ZEND_MODULE_API_NO >= 20010901
3339+ "0.4.10", /* Replace with version number for your extension */
3340+#endif
3341+ STANDARD_MODULE_PROPERTIES
3342+};
3343+/* }}} */
3344+
3345+#ifdef COMPILE_DL_VARFILTER
3346+ZEND_GET_MODULE(varfilter)
3347+#endif
3348+
3349+/* {{{ PHP_INI
3350+ */
3351+PHP_INI_BEGIN()
3352+ /* for backward compatibility */
3353+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3354+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3355+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3356+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3357+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3358+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3359+
3360+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3361+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3362+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3363+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3364+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3365+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3366+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3367+
3368+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3369+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3370+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3371+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3372+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3373+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
3374+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3375+
3376+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3377+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3378+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3379+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3380+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3381+ STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
3382+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3383+
3384+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3385+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3386+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3387+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3388+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3389+ STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
3390+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3391+
3392+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3393+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3394+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3395+
3396+
3397+PHP_INI_END()
3398+/* }}} */
3399+
3400+/* {{{ php_varfilter_init_globals
3401+ */
3402+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3403+{
3404+ varfilter_globals->max_request_variables = 200;
3405+ varfilter_globals->max_varname_length = 64;
3406+ varfilter_globals->max_value_length = 10000;
3407+ varfilter_globals->max_array_depth = 100;
3408+ varfilter_globals->max_totalname_length = 256;
3409+ varfilter_globals->max_array_index_length = 64;
3410+ varfilter_globals->disallow_nul = 1;
3411+
3412+ varfilter_globals->max_cookie_vars = 100;
3413+ varfilter_globals->max_cookie_name_length = 64;
3414+ varfilter_globals->max_cookie_totalname_length = 256;
3415+ varfilter_globals->max_cookie_value_length = 10000;
3416+ varfilter_globals->max_cookie_array_depth = 100;
3417+ varfilter_globals->max_cookie_array_index_length = 64;
3418+ varfilter_globals->disallow_cookie_nul = 1;
3419+
3420+ varfilter_globals->max_get_vars = 100;
3421+ varfilter_globals->max_get_name_length = 64;
3422+ varfilter_globals->max_get_totalname_length = 256;
3423+ varfilter_globals->max_get_value_length = 512;
3424+ varfilter_globals->max_get_array_depth = 50;
3425+ varfilter_globals->max_get_array_index_length = 64;
3426+ varfilter_globals->disallow_get_nul = 1;
3427+
3428+ varfilter_globals->max_post_vars = 200;
3429+ varfilter_globals->max_post_name_length = 64;
3430+ varfilter_globals->max_post_totalname_length = 256;
3431+ varfilter_globals->max_post_value_length = 65000;
3432+ varfilter_globals->max_post_array_depth = 100;
3433+ varfilter_globals->max_post_array_index_length = 64;
3434+ varfilter_globals->disallow_post_nul = 1;
3435+
3436+ varfilter_globals->max_uploads = 25;
3437+ varfilter_globals->disallow_elf_files = 1;
3438+ varfilter_globals->verification_script = NULL;
3439+
3440+ varfilter_globals->no_more_variables = 0;
3441+ varfilter_globals->no_more_get_variables = 0;
3442+ varfilter_globals->no_more_post_variables = 0;
3443+ varfilter_globals->no_more_cookie_variables = 0;
3444+ varfilter_globals->no_more_uploads = 0;
3445+
3446+ varfilter_globals->cur_request_variables = 0;
3447+ varfilter_globals->cur_get_vars = 0;
3448+ varfilter_globals->cur_post_vars = 0;
3449+ varfilter_globals->cur_cookie_vars = 0;
3450+
3451+ varfilter_globals->cur_uploads = 0;
3452+
3453+}
3454+/* }}} */
3455+
3456+
3457+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3458+{
3459+ HashTable *svars;
3460+ int retval, failure=0;
3461+
3462+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3463+
3464+ svars = Z_ARRVAL_P(track_vars_array);
3465+
3466+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3467+ if (retval == SUCCESS) failure = 1;
3468+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3469+ if (retval == SUCCESS) failure = 1;
3470+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3471+ if (retval == SUCCESS) failure = 1;
3472+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3473+ if (retval == SUCCESS) failure = 1;
3474+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3475+ if (retval == SUCCESS) failure = 1;
3476+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3477+ if (retval == SUCCESS) failure = 1;
3478+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3479+ if (retval == SUCCESS) failure = 1;
3480+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX);
3481+ if (retval == SUCCESS) failure = 1;
3482+
3483+ if (failure) {
3484+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3485+ }
3486+}
3487+
3488+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3489+{
3490+ int retval = SAPI_HEADER_ADD, i;
3491+ char *tmp;
3492+
3493+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3494+
3495+ tmp = sapi_header->header;
3496+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3497+ if (tmp[0] == 0) {
3498+ char *fname = get_active_function_name(TSRMLS_C);
3499+
3500+ if (!fname) {
3501+ fname = "unknown";
3502+ }
3503+
3504+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3505+ sapi_header->header_len = i;
3506+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3507+ char *fname = get_active_function_name(TSRMLS_C);
3508+
3509+ if (!fname) {
3510+ fname = "unknown";
3511+ }
3512+
3513+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3514+ sapi_header->header_len = i;
3515+ tmp[0] = 0;
3516+ }
3517+ }
3518+ }
3519+
3520+ if (orig_header_handler) {
3521+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3522+ }
3523+
3524+ return retval;
3525+}
3526+
3527+/* {{{ PHP_MINIT_FUNCTION
3528+ */
3529+PHP_MINIT_FUNCTION(varfilter)
3530+{
3531+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3532+ REGISTER_INI_ENTRIES();
3533+
3534+ if (!hooked) {
3535+ void *temp;
3536+ hooked = 1;
3537+
3538+ temp = (void *)sapi_module.register_server_variables;
3539+ if (temp != varfilter_register_server_variables) {
3540+ orig_register_server_variables = temp;
3541+ }
3542+ temp = (void *)sapi_module.header_handler;
3543+ if (temp != varfilter_header_handler) {
3544+ orig_header_handler = temp;
3545+ }
3546+ }
3547+
3548+ sapi_register_input_filter(varfilter_input_filter);
3549+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3550+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3551+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3552+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3553+
3554+ sapi_module.header_handler = varfilter_header_handler;
3555+ sapi_module.register_server_variables = varfilter_register_server_variables;
3556+
3557+
3558+ return SUCCESS;
3559+}
3560+/* }}} */
3561+
3562+/* {{{ PHP_MSHUTDOWN_FUNCTION
3563+ */
3564+PHP_MSHUTDOWN_FUNCTION(varfilter)
3565+{
3566+ UNREGISTER_INI_ENTRIES();
3567+
3568+ return SUCCESS;
3569+}
3570+/* }}} */
3571+
3572+/* Remove if there's nothing to do at request start */
3573+/* {{{ PHP_RINIT_FUNCTION
3574+ */
3575+PHP_RINIT_FUNCTION(varfilter)
3576+{
3577+ VARFILTER_G(cur_request_variables) = 0;
3578+ VARFILTER_G(cur_get_vars) = 0;
3579+ VARFILTER_G(cur_post_vars) = 0;
3580+ VARFILTER_G(cur_cookie_vars) = 0;
3581+
3582+ VARFILTER_G(cur_uploads) = 0;
3583+
3584+ VARFILTER_G(no_more_variables) = 0;
3585+ VARFILTER_G(no_more_get_variables) = 0;
3586+ VARFILTER_G(no_more_post_variables) = 0;
3587+ VARFILTER_G(no_more_cookie_variables) = 0;
3588+ VARFILTER_G(no_more_uploads) = 0;
3589+
3590+ return SUCCESS;
3591+}
3592+/* }}} */
3593+
3594+/* Remove if there's nothing to do at request end */
3595+/* {{{ PHP_RSHUTDOWN_FUNCTION
3596+ */
3597+PHP_RSHUTDOWN_FUNCTION(varfilter)
3598+{
3599+ return SUCCESS;
3600+}
3601+/* }}} */
3602+
3603+/* {{{ PHP_MINFO_FUNCTION
3604+ */
3605+PHP_MINFO_FUNCTION(varfilter)
3606+{
3607+ php_info_print_table_start();
3608+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3609+ php_info_print_table_end();
3610+
3611+ DISPLAY_INI_ENTRIES();
3612+}
3613+/* }}} */
3614+
3615+/* {{{ normalize_varname
3616+ */
3617+static void normalize_varname(char *varname)
3618+{
3619+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3620+
3621+ /* overjump leading space */
3622+ while (*s == ' ') {
3623+ s++;
3624+ }
3625+
3626+ /* and remove it */
3627+ if (s != varname) {
3628+ memmove(varname, s, strlen(s)+1);
3629+ }
3630+
3631+ for (p=varname; *p && *p != '['; p++) {
3632+ switch(*p) {
3633+ case ' ':
3634+ case '.':
3635+ *p='_';
3636+ break;
3637+ }
3638+ }
3639+
3640+ /* find index */
3641+ index = strchr(varname, '[');
3642+ if (index) {
3643+ index++;
3644+ s=index;
3645+ } else {
3646+ return;
3647+ }
3648+
3649+ /* done? */
3650+ while (index) {
3651+
3652+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3653+ index++;
3654+ }
3655+ indexend = strchr(index, ']');
3656+ indexend = indexend ? indexend + 1 : index + strlen(index);
3657+
3658+ if (s != index) {
3659+ memmove(s, index, strlen(index)+1);
3660+ s += indexend-index;
3661+ } else {
3662+ s = indexend;
3663+ }
3664+
3665+ if (*s == '[') {
3666+ s++;
3667+ index = s;
3668+ } else {
3669+ index = NULL;
3670+ }
3671+ }
3672+ *s++='\0';
3673+}
3674+/* }}} */
3675+
3676+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3677+ */
3678+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3679+{
3680+ char *index, *prev_index = NULL, *var;
3681+ unsigned int var_len, total_len, depth = 0;
3682+
3683+ var = estrdup(varname);
3684+
3685+ /* Normalize the variable name */
3686+ normalize_varname(var);
3687+
3688+ /* Find length of variable name */
3689+ index = strchr(var, '[');
3690+ total_len = strlen(var);
3691+ var_len = index ? index-var : total_len;
3692+
3693+ /* Drop this variable if it exceeds the varname/total length limit */
3694+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3695+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3696+ goto return_failure;
3697+ }
3698+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3699+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3700+ goto return_failure;
3701+ }
3702+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3703+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3704+
3705+ goto return_failure;
3706+ }
3707+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3708+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3709+ goto return_failure;
3710+ }
3711+
3712+ /* Find out array depth */
3713+ while (index) {
3714+ unsigned int index_length;
3715+
3716+ depth++;
3717+ index = strchr(index+1, '[');
3718+
3719+ if (prev_index) {
3720+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3721+
3722+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3723+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3724+ goto return_failure;
3725+ }
3726+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3727+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3728+ goto return_failure;
3729+ }
3730+ prev_index = index;
3731+ }
3732+
3733+ }
3734+
3735+ /* Drop this variable if it exceeds the array depth limit */
3736+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3737+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3738+ goto return_failure;
3739+ }
3740+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3741+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3742+ goto return_failure;
3743+ }
3744+
3745+
3746+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3747+ /* This is to protect several silly scripts that do globalizing themself */
3748+
3749+ switch (var_len) {
3750+ case 18:
3751+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3752+ break;
3753+ case 17:
3754+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3755+ break;
3756+ case 16:
3757+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3758+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3759+ break;
3760+ case 15:
3761+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3762+ break;
3763+ case 14:
3764+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3765+ break;
3766+ case 13:
3767+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3768+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3769+ break;
3770+ case 8:
3771+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3772+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3773+ break;
3774+ case 7:
3775+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3776+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3777+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3778+ break;
3779+ case 6:
3780+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3781+ break;
3782+ case 5:
3783+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3784+ break;
3785+ case 4:
3786+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3787+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3788+ break;
3789+ }
3790+
3791+ efree(var);
3792+ return SUCCESS;
3793+protected_varname2:
3794+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3795+return_failure:
3796+ efree(var);
3797+ return FAILURE;
3798+}
3799+/* }}} */
3800+
3801+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3802+ */
3803+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3804+{
3805+ /* Drop if no more variables flag is set */
3806+ if (VARFILTER_G(no_more_uploads)) {
3807+ return FAILURE;
3808+ }
3809+ /* Drop this fileupload if the limit is reached */
3810+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3811+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3812+ VARFILTER_G(no_more_uploads) = 1;
3813+ return FAILURE;
3814+ }
3815+
3816+ return SUCCESS;
3817+}
3818+/* }}} */
3819+
3820+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3821+ */
3822+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3823+{
3824+
3825+ if (VARFILTER_G(disallow_elf_files)) {
3826+
3827+ if (offset == 0 && buffer_len > 10) {
3828+
3829+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3830+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3831+ return FAILURE;
3832+ }
3833+ }
3834+
3835+ }
3836+
3837+ return SUCCESS;
3838+}
3839+/* }}} */
3840+
3841+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3842+ */
3843+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3844+{
3845+ int retval = SUCCESS;
3846+
3847+ if (VARFILTER_G(verification_script)) {
3848+ char cmd[8192];
3849+ FILE *in;
3850+ int first=1;
3851+
3852+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3853+
3854+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3855+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3856+ return FAILURE;
3857+ }
3858+
3859+ retval = FAILURE;
3860+
3861+ /* read and forget the result */
3862+ while (1) {
3863+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3864+ if (readbytes<=0) {
3865+ break;
3866+ }
3867+ if (first) {
3868+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3869+ first = 0;
3870+ }
3871+ }
3872+ pclose(in);
3873+ }
3874+
3875+ if (retval != SUCCESS) {
3876+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3877+ return FAILURE;
3878+ }
3879+
3880+ VARFILTER_G(cur_uploads)++;
3881+ return SUCCESS;
3882+}
3883+/* }}} */
3884+
3885+/* {{{ SAPI_INPUT_FILTER_FUNC
3886+ */
3887+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3888+{
3889+ char *index, *prev_index = NULL;
3890+ unsigned int var_len, total_len, depth = 0;
3891+
3892+ /* Drop this variable if the limit was reached */
3893+ switch (arg) {
3894+ case PARSE_GET:
3895+ if (VARFILTER_G(no_more_get_variables)) {
3896+ return 0;
3897+ }
3898+ break;
3899+ case PARSE_POST:
3900+ if (VARFILTER_G(no_more_post_variables)) {
3901+ return 0;
3902+ }
3903+ break;
3904+ case PARSE_COOKIE:
3905+ if (VARFILTER_G(no_more_cookie_variables)) {
3906+ return 0;
3907+ }
3908+ break;
3909+ default: /* we do not want to protect parse_str() and friends */
3910+ if (new_val_len) {
3911+ *new_val_len = val_len;
3912+ }
3913+ return 1;
3914+ }
3915+ if (VARFILTER_G(no_more_variables)) {
3916+ return 0;
3917+ }
3918+
3919+ /* Drop this variable if the limit is now reached */
3920+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3921+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3922+ VARFILTER_G(no_more_variables) = 1;
3923+ return 0;
3924+ }
3925+ switch (arg) {
3926+ case PARSE_GET:
3927+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3928+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3929+ VARFILTER_G(no_more_get_variables) = 1;
3930+ return 0;
3931+ }
3932+ break;
3933+ case PARSE_COOKIE:
3934+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3935+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3936+ VARFILTER_G(no_more_cookie_variables) = 1;
3937+ return 0;
3938+ }
3939+ break;
3940+ case PARSE_POST:
3941+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3942+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3943+ VARFILTER_G(no_more_post_variables) = 1;
3944+ return 0;
3945+ }
3946+ break;
3947+ }
3948+
3949+
3950+ /* Drop this variable if it exceeds the value length limit */
3951+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3952+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3953+ return 0;
3954+ }
3955+ switch (arg) {
3956+ case PARSE_GET:
3957+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3958+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3959+ return 0;
3960+ }
3961+ break;
3962+ case PARSE_COOKIE:
3963+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3964+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3965+ return 0;
3966+ }
3967+ break;
3968+ case PARSE_POST:
3969+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3970+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3971+ return 0;
3972+ }
3973+ break;
3974+ }
3975+
3976+ /* Normalize the variable name */
3977+ normalize_varname(var);
3978+
3979+ /* Find length of variable name */
3980+ index = strchr(var, '[');
3981+ total_len = strlen(var);
3982+ var_len = index ? index-var : total_len;
3983+
3984+ /* Drop this variable if it exceeds the varname/total length limit */
3985+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3986+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3987+ return 0;
3988+ }
3989+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3990+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3991+ return 0;
3992+ }
3993+ switch (arg) {
3994+ case PARSE_GET:
3995+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3996+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3997+ return 0;
3998+ }
3999+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
4000+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
4001+ return 0;
4002+ }
4003+ break;
4004+ case PARSE_COOKIE:
4005+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
4006+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
4007+ return 0;
4008+ }
4009+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
4010+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
4011+ return 0;
4012+ }
4013+ break;
4014+ case PARSE_POST:
4015+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
4016+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
4017+ return 0;
4018+ }
4019+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
4020+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
4021+ return 0;
4022+ }
4023+ break;
4024+ }
4025+
4026+ /* Find out array depth */
4027+ while (index) {
4028+ unsigned int index_length;
4029+
4030+ depth++;
4031+ index = strchr(index+1, '[');
4032+
4033+ if (prev_index) {
4034+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
4035+
4036+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
4037+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
4038+ return 0;
4039+ }
4040+ switch (arg) {
4041+ case PARSE_GET:
4042+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
4043+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
4044+ return 0;
4045+ }
4046+ break;
4047+ case PARSE_COOKIE:
4048+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
4049+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
4050+ return 0;
4051+ }
4052+ break;
4053+ case PARSE_POST:
4054+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
4055+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
4056+ return 0;
4057+ }
4058+ break;
4059+ }
4060+ prev_index = index;
4061+ }
4062+
4063+ }
4064+
4065+ /* Drop this variable if it exceeds the array depth limit */
4066+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
4067+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
4068+ return 0;
4069+ }
4070+ switch (arg) {
4071+ case PARSE_GET:
4072+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
4073+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
4074+ return 0;
4075+ }
4076+ break;
4077+ case PARSE_COOKIE:
4078+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
4079+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
4080+ return 0;
4081+ }
4082+ break;
4083+ case PARSE_POST:
4084+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
4085+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
4086+ return 0;
4087+ }
4088+ break;
4089+ }
4090+
4091+ /* Check if variable value is truncated by a \0 */
4092+
4093+ if (val && *val && val_len != strlen(*val)) {
4094+
4095+ if (VARFILTER_G(disallow_nul)) {
4096+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
4097+ return 0;
4098+ }
4099+ switch (arg) {
4100+ case PARSE_GET:
4101+ if (VARFILTER_G(disallow_get_nul)) {
4102+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
4103+ return 0;
4104+ }
4105+ break;
4106+ case PARSE_COOKIE:
4107+ if (VARFILTER_G(disallow_cookie_nul)) {
4108+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
4109+ return 0;
4110+ }
4111+ break;
4112+ case PARSE_POST:
4113+ if (VARFILTER_G(disallow_post_nul)) {
4114+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
4115+ return 0;
4116+ }
4117+ break;
4118+ }
4119+ }
4120+
4121+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
4122+ /* This is to protect several silly scripts that do globalizing themself */
4123+
4124+ switch (var_len) {
4125+ case 18:
4126+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
4127+ break;
4128+ case 17:
4129+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
4130+ break;
4131+ case 16:
4132+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
4133+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
4134+ break;
4135+ case 15:
4136+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
4137+ break;
4138+ case 14:
4139+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
4140+ break;
4141+ case 13:
4142+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
4143+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
4144+ break;
4145+ case 8:
4146+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
4147+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
4148+ break;
4149+ case 7:
4150+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
4151+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
4152+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
4153+ break;
4154+ case 6:
4155+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
4156+ break;
4157+ case 5:
4158+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
4159+ break;
4160+ case 4:
4161+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
4162+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
4163+ break;
4164+ }
4165+
4166+ /* Okay let PHP register this variable */
4167+ VARFILTER_G(cur_request_variables)++;
4168+ switch (arg) {
4169+ case PARSE_GET:
4170+ VARFILTER_G(cur_get_vars)++;
4171+ break;
4172+ case PARSE_COOKIE:
4173+ VARFILTER_G(cur_cookie_vars)++;
4174+ break;
4175+ case PARSE_POST:
4176+ VARFILTER_G(cur_post_vars)++;
4177+ break;
4178+ }
4179+
4180+ if (new_val_len) {
4181+ *new_val_len = val_len;
4182+ }
4183+
4184+ return 1;
4185+protected_varname:
4186+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
4187+ return 0;
4188+}
4189+/* }}} */
4190+
4191+/*
4192+ * Local variables:
4193+ * tab-width: 4
4194+ * c-basic-offset: 4
4195+ * End:
4196+ * vim600: noet sw=4 ts=4 fdm=marker
4197+ * vim<600: noet sw=4 ts=4
4198+ */
4199+
4200+
4201diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.10/main/fopen_wrappers.c
4202--- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100
4203+++ hardening-patch-4.4.2-0.4.10/main/fopen_wrappers.c 2006-05-11 10:37:40.000000000 +0200
4204@@ -116,14 +116,20 @@
4205 }
4206 }
4207
4208+ resolved_name_len = strlen(resolved_name);
4209 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
4210- resolved_name_len = strlen(resolved_name);
4211 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
4212 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
4213 resolved_name[++resolved_name_len] = '\0';
4214 }
4215 }
4216
4217+ if (resolved_name_len == resolved_basedir_len - 1) {
4218+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4219+ resolved_basedir_len--;
4220+ }
4221+ }
4222+
4223 /* Check the path */
4224 #ifdef PHP_WIN32
4225 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4226@@ -156,6 +162,21 @@
4227 char *pathbuf;
4228 char *ptr;
4229 char *end;
4230+ char path_copy[MAXPATHLEN];
4231+ int path_len;
4232+
4233+ /* Special case path ends with a trailing slash */
4234+ path_len = strlen(path);
4235+ if (path_len >= MAXPATHLEN) {
4236+ errno = EPERM; /* we deny permission to open it */
4237+ return -1;
4238+ }
4239+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4240+ memcpy(path_copy, path, path_len+1);
4241+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4242+ path_copy[path_len] = '\0';
4243+ path = (const char *)&path_copy;
4244+ }
4245
4246 pathbuf = estrdup(PG(open_basedir));
4247
4248diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.10/main/hardened_globals.h
4249--- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4250+++ hardening-patch-4.4.2-0.4.10/main/hardened_globals.h 2006-05-11 10:36:02.000000000 +0200
4251@@ -0,0 +1,62 @@
4252+/*
4253+ +----------------------------------------------------------------------+
4254+ | Hardening-Patch for PHP |
4255+ +----------------------------------------------------------------------+
4256+ | Copyright (c) 2004-2005 Stefan Esser |
4257+ +----------------------------------------------------------------------+
4258+ | This source file is subject to version 2.02 of the PHP license, |
4259+ | that is bundled with this package in the file LICENSE, and is |
4260+ | available at through the world-wide-web at |
4261+ | http://www.php.net/license/2_02.txt. |
4262+ | If you did not receive a copy of the PHP license and are unable to |
4263+ | obtain it through the world-wide-web, please send a note to |
4264+ | license@php.net so we can mail you a copy immediately. |
4265+ +----------------------------------------------------------------------+
4266+ | Author: Stefan Esser <sesser@hardened-php.net> |
4267+ +----------------------------------------------------------------------+
4268+ */
4269+
4270+#ifndef HARDENED_GLOBALS_H
4271+#define HARDENED_GLOBALS_H
4272+
4273+typedef struct _hardened_globals hardened_globals_struct;
4274+
4275+#ifdef ZTS
4276+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4277+extern int hardened_globals_id;
4278+#else
4279+# define HG(v) (hardened_globals.v)
4280+extern struct _hardened_globals hardened_globals;
4281+#endif
4282+
4283+
4284+struct _hardened_globals {
4285+#if HARDENING_PATCH_MM_PROTECT
4286+ unsigned int canary_1;
4287+ unsigned int canary_2;
4288+#endif
4289+#if HARDENING_PATCH_LL_PROTECT
4290+ unsigned int canary_3;
4291+ unsigned int canary_4;
4292+ unsigned int ll_canary_inited;
4293+#endif
4294+ zend_bool hphp_sql_bailout_on_error;
4295+ zend_bool hphp_multiheader;
4296+ HashTable *eval_whitelist;
4297+ HashTable *eval_blacklist;
4298+ HashTable *func_whitelist;
4299+ HashTable *func_blacklist;
4300+ HashTable *include_whitelist;
4301+ HashTable *include_blacklist;
4302+ unsigned int dummy;
4303+};
4304+
4305+
4306+#endif /* HARDENED_GLOBALS_H */
4307+
4308+/*
4309+ * Local variables:
4310+ * tab-width: 4
4311+ * c-basic-offset: 4
4312+ * End:
4313+ */
4314diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.10/main/hardening_patch.c
4315--- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4316+++ hardening-patch-4.4.2-0.4.10/main/hardening_patch.c 2006-05-11 10:36:02.000000000 +0200
4317@@ -0,0 +1,430 @@
4318+/*
4319+ +----------------------------------------------------------------------+
4320+ | Hardening Patch for PHP |
4321+ +----------------------------------------------------------------------+
4322+ | Copyright (c) 2004-2005 Stefan Esser |
4323+ +----------------------------------------------------------------------+
4324+ | This source file is subject to version 2.02 of the PHP license, |
4325+ | that is bundled with this package in the file LICENSE, and is |
4326+ | available at through the world-wide-web at |
4327+ | http://www.php.net/license/2_02.txt. |
4328+ | If you did not receive a copy of the PHP license and are unable to |
4329+ | obtain it through the world-wide-web, please send a note to |
4330+ | license@php.net so we can mail you a copy immediately. |
4331+ +----------------------------------------------------------------------+
4332+ | Author: Stefan Esser <sesser@hardened-php.net> |
4333+ +----------------------------------------------------------------------+
4334+ */
4335+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4336+
4337+#include "php.h"
4338+
4339+#include <stdio.h>
4340+#include <stdlib.h>
4341+
4342+#if HAVE_UNISTD_H
4343+#include <unistd.h>
4344+#endif
4345+#include "SAPI.h"
4346+#include "php_globals.h"
4347+
4348+#if HARDENING_PATCH
4349+
4350+#ifdef HAVE_SYS_SOCKET_H
4351+#include <sys/socket.h>
4352+#endif
4353+
4354+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4355+#undef AF_UNIX
4356+#endif
4357+
4358+#if defined(AF_UNIX)
4359+#include <sys/un.h>
4360+#endif
4361+
4362+#define SYSLOG_PATH "/dev/log"
4363+
4364+#include "snprintf.h"
4365+
4366+#include "hardening_patch.h"
4367+
4368+#ifdef ZTS
4369+#include "hardened_globals.h"
4370+int hardened_globals_id;
4371+#else
4372+struct _hardened_globals hardened_globals;
4373+#endif
4374+
4375+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4376+{
4377+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4378+}
4379+
4380+
4381+PHPAPI void hardened_startup()
4382+{
4383+#ifdef ZTS
4384+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4385+#else
4386+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4387+#endif
4388+}
4389+
4390+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4391+{
4392+ HG(canary_1) = php_canary();
4393+ HG(canary_2) = php_canary();
4394+}
4395+
4396+char *loglevel2string(int loglevel)
4397+{
4398+ switch (loglevel) {
4399+ case S_FILES:
4400+ return "FILES";
4401+ case S_INCLUDE:
4402+ return "INCLUDE";
4403+ case S_MEMORY:
4404+ return "MEMORY";
4405+ case S_MISC:
4406+ return "MISC";
4407+ case S_SQL:
4408+ return "SQL";
4409+ case S_EXECUTOR:
4410+ return "EXECUTOR";
4411+ case S_VARS:
4412+ return "VARS";
4413+ default:
4414+ return "UNKNOWN";
4415+ }
4416+}
4417+
4418+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4419+{
4420+#if defined(AF_UNIX)
4421+ int s, r, i=0;
4422+ struct sockaddr_un saun;
4423+ char buf[4096+64];
4424+ char error[4096+100];
4425+ char *ip_address;
4426+ char *fname;
4427+ int lineno;
4428+ va_list ap;
4429+ TSRMLS_FETCH();
4430+
4431+ if (EG(hphp_log_use_x_forwarded_for)) {
4432+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4433+ if (ip_address == NULL) {
4434+ ip_address = "X-FORWARDED-FOR not set";
4435+ }
4436+ } else {
4437+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4438+ if (ip_address == NULL) {
4439+ ip_address = "REMOTE_ADDR not set";
4440+ }
4441+ }
4442+
4443+
4444+ va_start(ap, fmt);
4445+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4446+ va_end(ap);
4447+ while (error[i]) {
4448+ if (error[i] < 32) error[i] = '.';
4449+ i++;
4450+ }
4451+
4452+ if (zend_is_executing(TSRMLS_C)) {
4453+ lineno = zend_get_executed_lineno(TSRMLS_C);
4454+ fname = zend_get_executed_filename(TSRMLS_C);
4455+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4456+ } else {
4457+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4458+ if (fname==NULL) {
4459+ fname = "unknown";
4460+ }
4461+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4462+ }
4463+
4464+ /* Syslog-Logging disabled? */
4465+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4466+ goto log_sapi;
4467+ }
4468+
4469+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4470+
4471+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4472+ if (s == -1) {
4473+ goto log_sapi;
4474+ }
4475+
4476+ memset(&saun, 0, sizeof(saun));
4477+ saun.sun_family = AF_UNIX;
4478+ strcpy(saun.sun_path, SYSLOG_PATH);
4479+ /*saun.sun_len = sizeof(saun);*/
4480+
4481+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4482+ if (r) {
4483+ close(s);
4484+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4485+ if (s == -1) {
4486+ goto log_sapi;
4487+ }
4488+
4489+ memset(&saun, 0, sizeof(saun));
4490+ saun.sun_family = AF_UNIX;
4491+ strcpy(saun.sun_path, SYSLOG_PATH);
4492+ /*saun.sun_len = sizeof(saun);*/
4493+
4494+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4495+ if (r) {
4496+ close(s);
4497+ goto log_sapi;
4498+ }
4499+ }
4500+ send(s, error, strlen(error), 0);
4501+
4502+ close(s);
4503+
4504+log_sapi:
4505+ /* SAPI Logging activated? */
4506+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4507+ sapi_module.log_message(buf);
4508+ }
4509+
4510+log_script:
4511+ /* script logging activaed? */
4512+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4513+ char cmd[8192], *cmdpos, *bufpos;
4514+ FILE *in;
4515+ int space;
4516+
4517+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4518+ space = sizeof(cmd) - strlen(cmd);
4519+ cmdpos = cmd + strlen(cmd);
4520+ bufpos = buf;
4521+ if (space <= 1) return;
4522+ while (space > 2 && *bufpos) {
4523+ if (*bufpos == '\'') {
4524+ if (space<=5) break;
4525+ *cmdpos++ = '\'';
4526+ *cmdpos++ = '\\';
4527+ *cmdpos++ = '\'';
4528+ *cmdpos++ = '\'';
4529+ bufpos++;
4530+ space-=4;
4531+ } else {
4532+ *cmdpos++ = *bufpos++;
4533+ space--;
4534+ }
4535+ }
4536+ *cmdpos++ = '\'';
4537+ *cmdpos = 0;
4538+
4539+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4540+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4541+ return;
4542+ }
4543+ /* read and forget the result */
4544+ while (1) {
4545+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4546+ if (readbytes<=0) {
4547+ break;
4548+ }
4549+ }
4550+ pclose(in);
4551+ }
4552+
4553+#endif
4554+}
4555+#endif
4556+
4557+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4558+
4559+/* will be replaced later with more compatible method */
4560+PHPAPI unsigned int php_canary()
4561+{
4562+ time_t t;
4563+ unsigned int canary;
4564+ int fd;
4565+
4566+ fd = open("/dev/urandom", 0);
4567+ if (fd != -1) {
4568+ int r = read(fd, &canary, sizeof(canary));
4569+ close(fd);
4570+ if (r == sizeof(canary)) {
4571+ return (canary);
4572+ }
4573+ }
4574+ /* not good but we never want to do this */
4575+ time(&t);
4576+ canary = *(unsigned int *)&t + getpid() << 16;
4577+ return (canary);
4578+}
4579+#endif
4580+
4581+#if HARDENING_PATCH_INC_PROTECT
4582+
4583+PHPAPI int php_is_valid_include(zval *z)
4584+{
4585+ char *filename;
4586+ int len, i;
4587+ TSRMLS_FETCH();
4588+
4589+ /* must be of type string */
4590+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4591+ return (0);
4592+ }
4593+
4594+ /* short cut */
4595+ filename = z->value.str.val;
4596+ len = z->value.str.len;
4597+
4598+ /* 1. must be shorter than MAXPATHLEN */
4599+ if (len > MAXPATHLEN) {
4600+ char *fname = estrndup(filename, len);
4601+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4602+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4603+ efree(fname);
4604+ return (0);
4605+ }
4606+
4607+ /* 2. must not be cutted */
4608+ if (len != strlen(filename)) {
4609+ char *fname = estrndup(filename, len);
4610+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4611+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4612+ efree(fname);
4613+ return (0);
4614+ }
4615+
4616+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4617+ if (strstr(filename, "://")) {
4618+ char *fname = estrndup(filename, len);
4619+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4620+
4621+ /* no black or whitelist then disallow all */
4622+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4623+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4624+ efree(fname);
4625+ return (0);
4626+ }
4627+
4628+ /* whitelist is stronger than blacklist */
4629+ if (HG(include_whitelist)) {
4630+ char *s, *t, *h, *index;
4631+ uint indexlen;
4632+ ulong numindex;
4633+
4634+ s = filename;
4635+
4636+ do {
4637+ zend_bool isOk = 0;
4638+ int tlen;
4639+
4640+ t = h = strstr(s, "://");
4641+ if (h == NULL) break;
4642+
4643+
4644+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4645+ t--;
4646+ }
4647+
4648+ tlen = strlen(t);
4649+
4650+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4651+ do {
4652+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4653+
4654+ if (r==HASH_KEY_NON_EXISTANT) {
4655+ break;
4656+ }
4657+ if (r==HASH_KEY_IS_STRING) {
4658+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4659+ if (strncmp(t, index, indexlen-1)==0) {
4660+ isOk = 1;
4661+ break;
4662+ }
4663+ }
4664+ }
4665+
4666+ zend_hash_move_forward(HG(include_whitelist));
4667+ } while (1);
4668+
4669+ /* not found in whitelist */
4670+ if (!isOk) {
4671+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4672+ efree(fname);
4673+ return 0;
4674+ }
4675+
4676+ s = h + 3;
4677+ } while (1);
4678+ } else {
4679+ /* okay then handle the blacklist */
4680+ char *s, *t, *h, *index;
4681+ uint indexlen;
4682+ ulong numindex;
4683+
4684+ s = filename;
4685+
4686+ do {
4687+ int tlen;
4688+
4689+ t = h = strstr(s, "://");
4690+ if (h == NULL) break;
4691+
4692+
4693+ while (t > s) {
4694+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4695+ }
4696+
4697+ tlen = strlen(t);
4698+
4699+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4700+ do {
4701+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4702+
4703+ if (r==HASH_KEY_NON_EXISTANT) {
4704+ break;
4705+ }
4706+ if (r==HASH_KEY_IS_STRING) {
4707+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4708+ if (strncmp(t, index, indexlen-1)==0) {
4709+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4710+ efree(fname);
4711+ return 0;
4712+ }
4713+ }
4714+ }
4715+
4716+ zend_hash_move_forward(HG(include_blacklist));
4717+ } while (1);
4718+
4719+ s = h + 3;
4720+ } while (1);
4721+ }
4722+
4723+ efree(fname);
4724+ }
4725+
4726+ /* 4. must not be an uploaded file */
4727+ if (SG(rfc1867_uploaded_files)) {
4728+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4729+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4730+ return (0);
4731+ }
4732+ }
4733+
4734+ /* passed all tests */
4735+ return (1);
4736+}
4737+
4738+#endif
4739+
4740+/*
4741+ * Local variables:
4742+ * tab-width: 4
4743+ * c-basic-offset: 4
4744+ * End:
4745+ * vim600: sw=4 ts=4 fdm=marker
4746+ * vim<600: sw=4 ts=4
4747+ */
4748diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.10/main/hardening_patch.h
4749--- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4750+++ hardening-patch-4.4.2-0.4.10/main/hardening_patch.h 2006-05-11 10:37:28.000000000 +0200
4751@@ -0,0 +1,46 @@
4752+/*
4753+ +----------------------------------------------------------------------+
4754+ | Hardening Patch for PHP |
4755+ +----------------------------------------------------------------------+
4756+ | Copyright (c) 2004-2005 Stefan Esser |
4757+ +----------------------------------------------------------------------+
4758+ | This source file is subject to version 2.02 of the PHP license, |
4759+ | that is bundled with this package in the file LICENSE, and is |
4760+ | available at through the world-wide-web at |
4761+ | http://www.php.net/license/2_02.txt. |
4762+ | If you did not receive a copy of the PHP license and are unable to |
4763+ | obtain it through the world-wide-web, please send a note to |
4764+ | license@php.net so we can mail you a copy immediately. |
4765+ +----------------------------------------------------------------------+
4766+ | Author: Stefan Esser <sesser@hardened-php.net> |
4767+ +----------------------------------------------------------------------+
4768+ */
4769+
4770+#ifndef HARDENING_PATCH_H
4771+#define HARDENING_PATCH_H
4772+
4773+#include "zend.h"
4774+
4775+#if HARDENING_PATCH
4776+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4777+PHPAPI void hardened_startup();
4778+#define HARDENING_PATCH_VERSION "0.4.10"
4779+
4780+#endif
4781+
4782+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4783+PHPAPI unsigned int php_canary();
4784+#endif
4785+
4786+#if HARDENING_PATCH_INC_PROTECT
4787+PHPAPI int php_is_valid_include(zval *z);
4788+#endif
4789+
4790+#endif /* HARDENING_PATCH_H */
4791+
4792+/*
4793+ * Local variables:
4794+ * tab-width: 4
4795+ * c-basic-offset: 4
4796+ * End:
4797+ */
4798diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.10/main/hardening_patch.m4
4799--- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4800+++ hardening-patch-4.4.2-0.4.10/main/hardening_patch.m4 2006-05-11 10:36:02.000000000 +0200
4801@@ -0,0 +1,95 @@
4802+dnl
4803+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4804+dnl
4805+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4806+dnl
4807+
4808+AC_ARG_ENABLE(hardening-patch-mm-protect,
4809+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4810+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4811+],[
4812+ DO_HARDENING_PATCH_MM_PROTECT=yes
4813+])
4814+
4815+AC_ARG_ENABLE(hardening-patch-ll-protect,
4816+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4817+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4818+],[
4819+ DO_HARDENING_PATCH_LL_PROTECT=yes
4820+])
4821+
4822+AC_ARG_ENABLE(hardening-patch-inc-protect,
4823+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4824+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4825+],[
4826+ DO_HARDENING_PATCH_INC_PROTECT=yes
4827+])
4828+
4829+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4830+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4831+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4832+],[
4833+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4834+])
4835+
4836+AC_ARG_ENABLE(hardening-patch-hash-protect,
4837+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4838+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4839+],[
4840+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4841+])
4842+
4843+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4844+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4845+
4846+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4847+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4848+
4849+AC_MSG_CHECKING(whether to protect include/require statements)
4850+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4851+
4852+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4853+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4854+
4855+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4856+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4857+
4858+
4859+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4860+
4861+
4862+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4863+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4864+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4865+else
4866+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4867+fi
4868+
4869+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4870+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4871+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4872+else
4873+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4874+fi
4875+
4876+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4877+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4878+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4879+else
4880+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4881+fi
4882+
4883+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4884+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4885+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4886+else
4887+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4888+fi
4889+
4890+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4891+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4892+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4893+else
4894+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4895+fi
4896+
4897diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.10/main/main.c
4898--- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100
4899+++ hardening-patch-4.4.2-0.4.10/main/main.c 2006-05-11 10:36:02.000000000 +0200
4900@@ -92,6 +92,10 @@
4901 PHPAPI int core_globals_id;
4902 #endif
4903
4904+#if HARDENING_PATCH
4905+#include "hardened_globals.h"
4906+#endif
4907+
4908 #define ERROR_BUF_LEN 1024
4909
4910 typedef struct {
4911@@ -142,10 +146,33 @@
4912 */
4913 static PHP_INI_MH(OnChangeMemoryLimit)
4914 {
4915+#if HARDENING_PATCH
4916+ long orig_memory_limit;
4917+
4918+ if (entry->modified) {
4919+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4920+ } else {
4921+ orig_memory_limit = 1<<30;
4922+ }
4923+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4924+ orig_memory_limit = 1<<30;
4925+ }
4926+#endif
4927 if (new_value) {
4928 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4929+#if HARDENING_PATCH
4930+ if (PG(memory_limit) > orig_memory_limit) {
4931+ PG(memory_limit) = orig_memory_limit;
4932+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4933+ return FAILURE;
4934+ }
4935+#endif
4936 } else {
4937+#if HARDENING_PATCH
4938+ PG(memory_limit) = orig_memory_limit;
4939+#else
4940 PG(memory_limit) = 1<<30; /* effectively, no limit */
4941+#endif
4942 }
4943 return zend_set_memory_limit(PG(memory_limit));
4944 }
4945@@ -1008,6 +1035,9 @@
4946
4947 zend_try {
4948 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4949+#if HARDENING_PATCH
4950+ hardened_clear_mm_canaries(TSRMLS_C);
4951+#endif
4952 } zend_end_try();
4953
4954 zend_try {
4955@@ -1098,6 +1128,10 @@
4956 tsrm_ls = ts_resource(0);
4957 #endif
4958
4959+#if HARDENING_PATCH
4960+ hardened_startup();
4961+#endif
4962+
4963 sapi_initialize_empty_request(TSRMLS_C);
4964 sapi_activate(TSRMLS_C);
4965
4966@@ -1110,6 +1144,12 @@
4967 php_output_startup();
4968 php_output_activate(TSRMLS_C);
4969
4970+#if HARDENING_PATCH_INC_PROTECT
4971+ zuf.is_valid_include = php_is_valid_include;
4972+#endif
4973+#if HARDENING_PATCH
4974+ zuf.security_log_function = php_security_log;
4975+#endif
4976 zuf.error_function = php_error_cb;
4977 zuf.printf_function = php_printf;
4978 zuf.write_function = php_body_write_wrapper;
4979@@ -1211,6 +1251,10 @@
4980 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4981 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);
4982 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4983+#if HARDENING_PATCH
4984+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4985+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4986+#endif
4987 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4988 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4989 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4990@@ -1318,7 +1362,7 @@
4991 */
4992 static inline void php_register_server_variables(TSRMLS_D)
4993 {
4994- zval *array_ptr=NULL;
4995+ zval *array_ptr=NULL, *vptr;
4996
4997 ALLOC_ZVAL(array_ptr);
4998 array_init(array_ptr);
4999diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.10/main/php_config.h.in
5000--- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100
5001+++ hardening-patch-4.4.2-0.4.10/main/php_config.h.in 2006-05-11 10:36:02.000000000 +0200
5002@@ -865,6 +865,39 @@
5003 /* Enabling BIND8 compatibility for Panther */
5004 #undef BIND_8_COMPAT
5005
5006+/* Hardening-Patch */
5007+#undef HARDENING_PATCH
5008+
5009+/* Memory Manager Protection */
5010+#undef HARDENING_PATCH_MM_PROTECT
5011+
5012+/* Memory Manager Protection */
5013+#undef HARDENING_PATCH_MM_PROTECT
5014+
5015+/* Linked List Protection */
5016+#undef HARDENING_PATCH_LL_PROTECT
5017+
5018+/* Linked List Protection */
5019+#undef HARDENING_PATCH_LL_PROTECT
5020+
5021+/* Include/Require Protection */
5022+#undef HARDENING_PATCH_INC_PROTECT
5023+
5024+/* Include/Require Protection */
5025+#undef HARDENING_PATCH_INC_PROTECT
5026+
5027+/* Fmt String Protection */
5028+#undef HARDENING_PATCH_FMT_PROTECT
5029+
5030+/* Fmt String Protection */
5031+#undef HARDENING_PATCH_FMT_PROTECT
5032+
5033+/* HashTable DTOR Protection */
5034+#undef HARDENING_PATCH_HASH_PROTECT
5035+
5036+/* HashTable DTOR Protection */
5037+#undef HARDENING_PATCH_HASH_PROTECT
5038+
5039 /* Whether you have AOLserver */
5040 #undef HAVE_AOLSERVER
5041
5042@@ -1148,6 +1181,12 @@
5043 /* Define if you have the getaddrinfo function */
5044 #undef HAVE_GETADDRINFO
5045
5046+/* Whether realpath is broken */
5047+#undef PHP_BROKEN_REALPATH
5048+
5049+/* Whether realpath is broken */
5050+#undef PHP_BROKEN_REALPATH
5051+
5052 /* Whether system headers declare timezone */
5053 #undef HAVE_DECLARED_TIMEZONE
5054
5055diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.10/main/php_content_types.c
5056--- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100
5057+++ hardening-patch-4.4.2-0.4.10/main/php_content_types.c 2006-05-11 10:36:02.000000000 +0200
5058@@ -77,6 +77,7 @@
5059 sapi_register_post_entries(php_post_entries);
5060 sapi_register_default_post_reader(php_default_post_reader);
5061 sapi_register_treat_data(php_default_treat_data);
5062+ sapi_register_input_filter(php_default_input_filter);
5063 return SUCCESS;
5064 }
5065 /* }}} */
5066diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.10/main/php.h
5067--- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100
5068+++ hardening-patch-4.4.2-0.4.10/main/php.h 2006-05-11 10:36:02.000000000 +0200
5069@@ -35,11 +35,19 @@
5070 #include "zend_qsort.h"
5071 #include "php_compat.h"
5072
5073+
5074 #include "zend_API.h"
5075
5076 #undef sprintf
5077 #define sprintf php_sprintf
5078
5079+#if HARDENING_PATCH
5080+#if HAVE_REALPATH
5081+#undef realpath
5082+#define realpath php_realpath
5083+#endif
5084+#endif
5085+
5086 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
5087 #undef PHP_DEBUG
5088 #define PHP_DEBUG ZEND_DEBUG
5089@@ -409,6 +417,10 @@
5090 #endif
5091 #endif /* !XtOffsetOf */
5092
5093+#if HARDENING_PATCH
5094+#include "hardening_patch.h"
5095+#endif
5096+
5097 #endif
5098
5099 /*
5100diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.10/main/php_variables.c
5101--- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100
5102+++ hardening-patch-4.4.2-0.4.10/main/php_variables.c 2006-05-11 10:36:02.000000000 +0200
5103@@ -236,17 +236,28 @@
5104 while (var) {
5105 val = strchr(var, '=');
5106 if (val) { /* have a value */
5107- int val_len;
5108+ unsigned int val_len, new_val_len;
5109
5110 *val++ = '\0';
5111 php_url_decode(var, strlen(var));
5112 val_len = php_url_decode(val, strlen(val));
5113- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5114+ val = estrndup(val, val_len);
5115+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5116+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5117+ }
5118+ efree(val);
5119 }
5120 var = php_strtok_r(NULL, "&", &strtok_buf);
5121 }
5122 }
5123
5124+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
5125+{
5126+ /* TODO: check .ini setting here and apply user-defined input filter */
5127+ *new_val_len = val_len;
5128+ return 1;
5129+}
5130+
5131 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
5132 {
5133 char *res = NULL, *var, *val, *separator=NULL;
5134@@ -324,15 +335,26 @@
5135 while (var) {
5136 val = strchr(var, '=');
5137 if (val) { /* have a value */
5138- int val_len;
5139+ unsigned int val_len, new_val_len;
5140
5141 *val++ = '\0';
5142 php_url_decode(var, strlen(var));
5143 val_len = php_url_decode(val, strlen(val));
5144- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5145+ val = estrndup(val, val_len);
5146+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5147+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5148+ }
5149+ efree(val);
5150 } else {
5151+ unsigned int val_len, new_val_len;
5152+
5153 php_url_decode(var, strlen(var));
5154- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
5155+ val_len = 0;
5156+ val = estrndup("", 0);
5157+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5158+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5159+ }
5160+ efree(val);
5161 }
5162 var = php_strtok_r(NULL, separator, &strtok_buf);
5163 }
5164diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.10/main/rfc1867.c
5165--- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100
5166+++ hardening-patch-4.4.2-0.4.10/main/rfc1867.c 2006-05-11 10:36:02.000000000 +0200
5167@@ -128,6 +128,8 @@
5168 #define UPLOAD_ERROR_D 4 /* No file uploaded */
5169 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
5170 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
5171+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
5172+
5173
5174 void php_rfc1867_register_constants(TSRMLS_D)
5175 {
5176@@ -138,6 +140,7 @@
5177 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
5178 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
5179 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
5180+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
5181 }
5182
5183 static void normalize_protected_variable(char *varname TSRMLS_DC)
5184@@ -849,6 +852,7 @@
5185 char buff[FILLUNIT];
5186 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
5187 int blen=0, wlen=0;
5188+ unsigned long offset;
5189
5190 zend_llist_clean(&header);
5191
5192@@ -897,21 +901,24 @@
5193 if (!filename && param) {
5194
5195 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
5196+ unsigned int new_val_len; /* Dummy variable */
5197
5198 if (!value) {
5199 value = estrdup("");
5200 }
5201
5202+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
5203 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
5204- if (php_mb_encoding_translation(TSRMLS_C)) {
5205- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5206- &num_vars, &num_vars_max TSRMLS_CC);
5207- } else {
5208- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5209- }
5210+ if (php_mb_encoding_translation(TSRMLS_C)) {
5211+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5212+ &num_vars, &num_vars_max TSRMLS_CC);
5213+ } else {
5214+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5215+ }
5216 #else
5217- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5218+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5219 #endif
5220+ }
5221 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
5222 max_file_size = atol(value);
5223 }
5224@@ -963,7 +970,11 @@
5225 tmp++;
5226 }
5227 }
5228-
5229+
5230+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
5231+ skip_upload = 1;
5232+ }
5233+
5234 total_bytes = cancel_upload = 0;
5235
5236 if (!skip_upload) {
5237@@ -987,6 +998,11 @@
5238 cancel_upload = UPLOAD_ERROR_D;
5239 }
5240
5241+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
5242+ cancel_upload = UPLOAD_ERROR_X;
5243+ }
5244+
5245+ offset = 0;
5246 end = 0;
5247 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
5248 {
5249@@ -997,6 +1013,11 @@
5250 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
5251 cancel_upload = UPLOAD_ERROR_B;
5252 } else if (blen > 0) {
5253+
5254+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
5255+ cancel_upload = UPLOAD_ERROR_X;
5256+ }
5257+
5258 wlen = write(fd, buff, blen);
5259
5260 if (wlen < blen) {
5261@@ -1004,6 +1025,7 @@
5262 cancel_upload = UPLOAD_ERROR_F;
5263 } else {
5264 total_bytes += wlen;
5265+ offset += wlen;
5266 }
5267 }
5268 }
5269@@ -1025,6 +1047,10 @@
5270 }
5271 #endif
5272
5273+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5274+ cancel_upload = UPLOAD_ERROR_X;
5275+ }
5276+
5277 if (cancel_upload) {
5278 if (temp_filename) {
5279 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5280diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.10/main/SAPI.c
5281--- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100
5282+++ hardening-patch-4.4.2-0.4.10/main/SAPI.c 2006-05-11 10:36:02.000000000 +0200
5283@@ -854,6 +854,37 @@
5284 return SUCCESS;
5285 }
5286
5287+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))
5288+{
5289+ sapi_module.input_filter = input_filter;
5290+ return SUCCESS;
5291+}
5292+
5293+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5294+{
5295+ sapi_module.upload_varname_filter = upload_varname_filter;
5296+ return SUCCESS;
5297+}
5298+
5299+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5300+{
5301+ sapi_module.pre_upload_filter = pre_upload_filter;
5302+ return SUCCESS;
5303+}
5304+
5305+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
5306+{
5307+ sapi_module.upload_content_filter = upload_content_filter;
5308+ return SUCCESS;
5309+}
5310+
5311+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5312+{
5313+ sapi_module.post_upload_filter = post_upload_filter;
5314+ return SUCCESS;
5315+}
5316+
5317+
5318
5319 SAPI_API int sapi_flush(TSRMLS_D)
5320 {
5321diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.10/main/SAPI.h
5322--- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100
5323+++ hardening-patch-4.4.2-0.4.10/main/SAPI.h 2006-05-11 10:36:02.000000000 +0200
5324@@ -101,9 +101,10 @@
5325 char *current_user;
5326 int current_user_length;
5327
5328- /* this is necessary for CLI module */
5329- int argc;
5330- char **argv;
5331+ /* this is necessary for CLI module */
5332+ int argc;
5333+ char **argv;
5334+
5335 } sapi_request_info;
5336
5337
5338@@ -177,6 +178,10 @@
5339 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5340 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5341 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5342+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));
5343+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5344+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
5345+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5346
5347 SAPI_API int sapi_flush(TSRMLS_D);
5348 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5349@@ -238,8 +243,16 @@
5350 int (*get_target_uid)(uid_t * TSRMLS_DC);
5351 int (*get_target_gid)(gid_t * TSRMLS_DC);
5352
5353+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5354+
5355+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5356+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5357+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5358+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5359+
5360 void (*ini_defaults)(HashTable *configuration_hash);
5361 int phpinfo_as_text;
5362+
5363 };
5364
5365
5366@@ -262,16 +275,27 @@
5367
5368 #define SAPI_DEFAULT_MIMETYPE "text/html"
5369 #define SAPI_DEFAULT_CHARSET ""
5370+
5371+#if HARDENING_PATCH
5372+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5373+#else
5374 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5375+#endif
5376
5377 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5378 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5379
5380 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5381+#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)
5382+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5383+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5384+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
5385+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5386
5387 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5388 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5389 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5390+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5391
5392 #define STANDARD_SAPI_MODULE_PROPERTIES
5393
5394diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.10/main/snprintf.c
5395--- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100
5396+++ hardening-patch-4.4.2-0.4.10/main/snprintf.c 2006-05-11 10:36:02.000000000 +0200
5397@@ -1014,7 +1014,11 @@
5398
5399
5400 case 'n':
5401+#if HARDENING_PATCH_FMT_PROTECT
5402+ php_security_log(S_MISC, "'n' specifier within format string");
5403+#else
5404 *(va_arg(ap, int *)) = cc;
5405+#endif
5406 break;
5407
5408 /*
5409diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.10/main/spprintf.c
5410--- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100
5411+++ hardening-patch-4.4.2-0.4.10/main/spprintf.c 2006-05-11 10:36:02.000000000 +0200
5412@@ -630,7 +630,11 @@
5413
5414
5415 case 'n':
5416+#if HARDENING_PATCH_FMT_PROTECT
5417+ php_security_log(S_MISC, "'n' specifier within format string");
5418+#else
5419 *(va_arg(ap, int *)) = xbuf->len;
5420+#endif
5421 break;
5422
5423 /*
5424diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.10/php.ini-dist
5425--- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100
5426+++ hardening-patch-4.4.2-0.4.10/php.ini-dist 2006-05-11 10:36:02.000000000 +0200
5427@@ -1114,6 +1114,209 @@
5428 ;exif.decode_jis_motorola = JIS
5429 ;exif.decode_jis_intel = JIS
5430
5431+[hardening-patch]
5432+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5433+; Hardening-Patch's logging ;
5434+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5435+
5436+;
5437+; hphp.log.syslog - Configures level for alerts reported through syslog
5438+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5439+; hphp.log.script - Configures level for alerts reported through external script
5440+;
5441+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5442+; Or each number up to get desired Hardening-Patch's reporting level
5443+;
5444+; S_ALL - All alerts
5445+; S_MEMORY - All canary violations and the safe unlink protection use this class
5446+; S_VARS - All variable filters trigger this class
5447+; S_FILES - All violation of uploaded files filter use this class
5448+; S_INCLUDE - The protection against malicious include filenames use this class
5449+; S_SQL - Failed SQL queries in MySQL are logged with this class
5450+; S_EXECUTOR - The execution depth protection uses this logging class
5451+; S_MISC - All other log messages (f.e. format string protection) use this class
5452+;
5453+; Example:
5454+;
5455+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5456+; memory alerts through syslog and SQL+Include alerts fo the script
5457+;
5458+;hphp.log.syslog = S_MEMORY
5459+;hphp.log.sapi = S_ALL & ~S_MEMORY
5460+;hphp.log.script = S_INCLUDE | S_SQL
5461+;
5462+; Syslog logging:
5463+;
5464+; - Facility configuration: one of the following facilities
5465+;
5466+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5467+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5468+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5469+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5470+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5471+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5472+; LOG_PERROR
5473+;
5474+; - Priority configuration: one of the followinf priorities
5475+;
5476+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5477+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5478+;
5479+hphp.log.syslog.priority = LOG_ALERT
5480+hphp.log.syslog.facility = LOG_USER
5481+;
5482+; Script logging:
5483+;
5484+;hphp.log.script.name = /home/hphp/log_script
5485+;
5486+; Alert configuration:
5487+;
5488+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5489+;
5490+;hphp.log.use-x-forwarded-for = On
5491+;
5492+
5493+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5494+; Hardening-Patch's Executor options ;
5495+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5496+
5497+; Execution depth limit
5498+;hphp.executor.max_depth = 8000
5499+
5500+; White-/blacklist for function calls during normal execution
5501+;hphp.executor.func.whitelist = ord,chr
5502+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5503+
5504+; White-/blacklist for function calls during eval() execution
5505+;hphp.executor.eval.whitelist = ord,chr
5506+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5507+
5508+; White-/blacklist for URLs allowes in include filenames
5509+;
5510+; - When both options are not set all URLs are forbidden
5511+;
5512+; - When both options are set whitelist is taken and blacklist ignored
5513+;
5514+; - An entry in the lists is either a URL sheme like: http, https
5515+; or the beginning of an URL like: php://input
5516+;
5517+;hphp.executor.include.whitelist = cookietest
5518+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5519+
5520+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5521+; Hardening-Patch's REQUEST variable filters ;
5522+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5523+
5524+; Limits the number of REQUEST variables
5525+hphp.request.max_vars = 200
5526+
5527+; Limits the length of variable names (without indices)
5528+hphp.request.max_varname_length = 64
5529+
5530+; Limits the length of complete variable names (with indices)
5531+hphp.request.max_totalname_length = 256
5532+
5533+; Limits the length of array indices
5534+hphp.request.max_array_index_length = 64
5535+
5536+; Limits the depth of arrays
5537+hphp.request.max_array_depth = 100
5538+
5539+; Limits the length of variable values
5540+hphp.request.max_value_length = 65000
5541+
5542+; Disallow ASCII-NUL characters in input
5543+hphp.request.disallow_nul = 1
5544+
5545+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5546+; Hardening-Patch's COOKIE variable filters ;
5547+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5548+
5549+; Limits the number of COOKIE variables
5550+hphp.cookie.max_vars = 100
5551+
5552+; Limits the length of variable names (without indices)
5553+hphp.cookie.max_name_length = 64
5554+
5555+; Limits the length of complete variable names (with indices)
5556+hphp.cookie.max_totalname_length = 256
5557+
5558+; Limits the length of array indices
5559+hphp.cookie.max_array_index_length = 64
5560+
5561+; Limits the depth of arrays
5562+hphp.cookie.max_array_depth = 100
5563+
5564+; Limits the length of variable values
5565+hphp.cookie.max_value_length = 10000
5566+
5567+; Disallow ASCII-NUL characters in input
5568+hphp.cookie.disallow_nul = 1
5569+
5570+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5571+; Hardening-Patch's GET variable filters ;
5572+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5573+
5574+; Limits the number of COOKIE variables
5575+hphp.get.max_vars = 100
5576+
5577+; Limits the length of variable names (without indices)
5578+hphp.get.max_name_length = 64
5579+
5580+; Limits the length of complete variable names (with indices)
5581+hphp.get.max_totalname_length = 256
5582+
5583+; Limits the length of array indices
5584+hphp.get.max_array_index_length = 64
5585+
5586+; Limits the depth of arrays
5587+hphp.get.max_array_depth = 50
5588+
5589+; Limits the length of variable values
5590+hphp.get.max_value_length = 512
5591+
5592+; Disallow ASCII-NUL characters in input
5593+hphp.get.disallow_nul = 1
5594+
5595+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5596+; Hardening-Patch's POST variable filters ;
5597+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5598+
5599+; Limits the number of POST variables
5600+hphp.post.max_vars = 200
5601+
5602+; Limits the length of variable names (without indices)
5603+hphp.post.max_name_length = 64
5604+
5605+; Limits the length of complete variable names (with indices)
5606+hphp.post.max_totalname_length = 256
5607+
5608+; Limits the length of array indices
5609+hphp.post.max_array_index_length = 64
5610+
5611+; Limits the depth of arrays
5612+hphp.post.max_array_depth = 100
5613+
5614+; Limits the length of variable values
5615+hphp.post.max_value_length = 65000
5616+
5617+; Disallow ASCII-NUL characters in input
5618+hphp.post.disallow_nul = 1
5619+
5620+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5621+; Hardening-Patch's fileupload variable filters ;
5622+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5623+
5624+; Limits the number of uploadable files
5625+hphp.upload.max_uploads = 25
5626+
5627+; Filter out the upload of ELF executables
5628+hphp.upload.disallow_elf_files = On
5629+
5630+; External filterscript for upload verification
5631+;hphp.upload.verification_script = /home/hphp/verify_script
5632+
5633+
5634 ; Local Variables:
5635 ; tab-width: 4
5636 ; End:
5637diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.10/php.ini-recommended
5638--- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100
5639+++ hardening-patch-4.4.2-0.4.10/php.ini-recommended 2006-05-11 10:36:02.000000000 +0200
5640@@ -1112,6 +1112,209 @@
5641 ;exif.decode_jis_motorola = JIS
5642 ;exif.decode_jis_intel = JIS
5643
5644+[hardening-patch]
5645+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5646+; Hardening-Patch's logging ;
5647+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5648+
5649+;
5650+; hphp.log.syslog - Configures level for alerts reported through syslog
5651+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5652+; hphp.log.script - Configures level for alerts reported through external script
5653+;
5654+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5655+; Or each number up to get desired Hardening-Patch's reporting level
5656+;
5657+; S_ALL - All alerts
5658+; S_MEMORY - All canary violations and the safe unlink protection use this class
5659+; S_VARS - All variable filters trigger this class
5660+; S_FILES - All violation of uploaded files filter use this class
5661+; S_INCLUDE - The protection against malicious include filenames use this class
5662+; S_SQL - Failed SQL queries in MySQL are logged with this class
5663+; S_EXECUTOR - The execution depth protection uses this logging class
5664+; S_MISC - All other log messages (f.e. format string protection) use this class
5665+;
5666+; Example:
5667+;
5668+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5669+; memory alerts through syslog and SQL+Include alerts fo the script
5670+;
5671+;hphp.log.syslog = S_MEMORY
5672+;hphp.log.sapi = S_ALL & ~S_MEMORY
5673+;hphp.log.script = S_INCLUDE | S_SQL
5674+;
5675+; Syslog logging:
5676+;
5677+; - Facility configuration: one of the following facilities
5678+;
5679+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5680+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5681+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5682+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5683+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5684+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5685+; LOG_PERROR
5686+;
5687+; - Priority configuration: one of the followinf priorities
5688+;
5689+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5690+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5691+;
5692+hphp.log.syslog.priority = LOG_ALERT
5693+hphp.log.syslog.facility = LOG_USER
5694+;
5695+; Script logging:
5696+;
5697+;hphp.log.script.name = /home/hphp/log_script
5698+;
5699+; Alert configuration:
5700+;
5701+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5702+;
5703+;hphp.log.use-x-forwarded-for = On
5704+;
5705+
5706+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5707+; Hardening-Patch's Executor options ;
5708+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5709+
5710+; Execution depth limit
5711+;hphp.executor.max_depth = 8000
5712+
5713+; White-/blacklist for function calls during normal execution
5714+;hphp.executor.func.whitelist = ord,chr
5715+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5716+
5717+; White-/blacklist for function calls during eval() execution
5718+;hphp.executor.eval.whitelist = ord,chr
5719+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5720+
5721+; White-/blacklist for URLs allowes in include filenames
5722+;
5723+; - When both options are not set all URLs are forbidden
5724+;
5725+; - When both options are set whitelist is taken and blacklist ignored
5726+;
5727+; - An entry in the lists is either a URL sheme like: http, https
5728+; or the beginning of an URL like: php://input
5729+;
5730+;hphp.executor.include.whitelist = cookietest
5731+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5732+
5733+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5734+; Hardening-Patch's REQUEST variable filters ;
5735+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5736+
5737+; Limits the number of REQUEST variables
5738+hphp.request.max_vars = 200
5739+
5740+; Limits the length of variable names (without indices)
5741+hphp.request.max_varname_length = 64
5742+
5743+; Limits the length of complete variable names (with indices)
5744+hphp.request.max_totalname_length = 256
5745+
5746+; Limits the length of array indices
5747+hphp.request.max_array_index_length = 64
5748+
5749+; Limits the depth of arrays
5750+hphp.request.max_array_depth = 100
5751+
5752+; Limits the length of variable values
5753+hphp.request.max_value_length = 65000
5754+
5755+; Disallow ASCII-NUL characters in input
5756+hphp.request.disallow_nul = 1
5757+
5758+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5759+; Hardening-Patch's COOKIE variable filters ;
5760+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5761+
5762+; Limits the number of COOKIE variables
5763+hphp.cookie.max_vars = 100
5764+
5765+; Limits the length of variable names (without indices)
5766+hphp.cookie.max_name_length = 64
5767+
5768+; Limits the length of complete variable names (with indices)
5769+hphp.cookie.max_totalname_length = 256
5770+
5771+; Limits the length of array indices
5772+hphp.cookie.max_array_index_length = 64
5773+
5774+; Limits the depth of arrays
5775+hphp.cookie.max_array_depth = 100
5776+
5777+; Limits the length of variable values
5778+hphp.cookie.max_value_length = 10000
5779+
5780+; Disallow ASCII-NUL characters in input
5781+hphp.cookie.disallow_nul = 1
5782+
5783+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5784+; Hardening-Patch's GET variable filters ;
5785+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5786+
5787+; Limits the number of COOKIE variables
5788+hphp.get.max_vars = 100
5789+
5790+; Limits the length of variable names (without indices)
5791+hphp.get.max_name_length = 64
5792+
5793+; Limits the length of complete variable names (with indices)
5794+hphp.get.max_totalname_length = 256
5795+
5796+; Limits the length of array indices
5797+hphp.get.max_array_index_length = 64
5798+
5799+; Limits the depth of arrays
5800+hphp.get.max_array_depth = 50
5801+
5802+; Limits the length of variable values
5803+hphp.get.max_value_length = 512
5804+
5805+; Disallow ASCII-NUL characters in input
5806+hphp.get.disallow_nul = 1
5807+
5808+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5809+; Hardening-Patch's POST variable filters ;
5810+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5811+
5812+; Limits the number of POST variables
5813+hphp.post.max_vars = 200
5814+
5815+; Limits the length of variable names (without indices)
5816+hphp.post.max_name_length = 64
5817+
5818+; Limits the length of complete variable names (with indices)
5819+hphp.post.max_totalname_length = 256
5820+
5821+; Limits the length of array indices
5822+hphp.post.max_array_index_length = 64
5823+
5824+; Limits the depth of arrays
5825+hphp.post.max_array_depth = 100
5826+
5827+; Limits the length of variable values
5828+hphp.post.max_value_length = 65000
5829+
5830+; Disallow ASCII-NUL characters in input
5831+hphp.post.disallow_nul = 1
5832+
5833+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5834+; Hardening-Patch's fileupload variable filters ;
5835+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5836+
5837+; Limits the number of uploadable files
5838+hphp.upload.max_uploads = 25
5839+
5840+; Filter out the upload of ELF executables
5841+hphp.upload.disallow_elf_files = On
5842+
5843+; External filterscript for upload verification
5844+;hphp.upload.verification_script = /home/hphp/verify_script
5845+
5846+
5847 ; Local Variables:
5848 ; tab-width: 4
5849 ; End:
5850diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.10/README.input_filter
5851--- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5852+++ hardening-patch-4.4.2-0.4.10/README.input_filter 2006-05-11 10:36:02.000000000 +0200
5853@@ -0,0 +1,193 @@
5854+Input Filter Support ported from PHP 5
5855+--------------------------------------
5856+
5857+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5858+and can be quite difficult to prevent. Whenever you accept user data
5859+and somehow display this data back to users, you are likely vulnerable
5860+to XSS hacks.
5861+
5862+The Input Filter support in PHP 5 is aimed at providing the framework
5863+through which a company-wide or site-wide security policy can be
5864+enforced. It is implemented as a SAPI hook and is called from the
5865+treat_data and post handler functions. To implement your own security
5866+policy you will need to write a standard PHP extension.
5867+
5868+A simple implementation might look like the following. This stores the
5869+original raw user data and adds a my_get_raw() function while the normal
5870+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5871+data. In this simple example all I am doing is calling strip_tags() on
5872+the data. If register_globals is turned on, the default globals that
5873+are created will be stripped ($foo) while a $RAW_foo is created with the
5874+original user input.
5875+
5876+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5877+ zval *post_array;
5878+ zval *get_array;
5879+ zval *cookie_array;
5880+ZEND_END_MODULE_GLOBALS(my_input_filter)
5881+
5882+#ifdef ZTS
5883+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5884+#else
5885+#define IF_G(v) (my_input_filter_globals.v)
5886+#endif
5887+
5888+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5889+
5890+function_entry my_input_filter_functions[] = {
5891+ PHP_FE(my_get_raw, NULL)
5892+ {NULL, NULL, NULL}
5893+};
5894+
5895+zend_module_entry my_input_filter_module_entry = {
5896+ STANDARD_MODULE_HEADER,
5897+ "my_input_filter",
5898+ my_input_filter_functions,
5899+ PHP_MINIT(my_input_filter),
5900+ PHP_MSHUTDOWN(my_input_filter),
5901+ NULL,
5902+ PHP_RSHUTDOWN(my_input_filter),
5903+ PHP_MINFO(my_input_filter),
5904+ "0.1",
5905+ STANDARD_MODULE_PROPERTIES
5906+};
5907+
5908+PHP_MINIT_FUNCTION(my_input_filter)
5909+{
5910+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5911+
5912+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5913+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5914+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5915+
5916+ sapi_register_input_filter(my_sapi_input_filter);
5917+ return SUCCESS;
5918+}
5919+
5920+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5921+{
5922+ if(IF_G(get_array)) {
5923+ zval_ptr_dtor(&IF_G(get_array));
5924+ IF_G(get_array) = NULL;
5925+ }
5926+ if(IF_G(post_array)) {
5927+ zval_ptr_dtor(&IF_G(post_array));
5928+ IF_G(post_array) = NULL;
5929+ }
5930+ if(IF_G(cookie_array)) {
5931+ zval_ptr_dtor(&IF_G(cookie_array));
5932+ IF_G(cookie_array) = NULL;
5933+ }
5934+ return SUCCESS;
5935+}
5936+
5937+PHP_MINFO_FUNCTION(my_input_filter)
5938+{
5939+ php_info_print_table_start();
5940+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5941+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5942+ php_info_print_table_end();
5943+}
5944+
5945+/* The filter handler. If you return 1 from it, then PHP also registers the
5946+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5947+ * you can use this if your filter already registers the variable under a
5948+ * different name, or if you just don't want the variable registered at all. */
5949+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5950+{
5951+ zval new_var;
5952+ zval *array_ptr = NULL;
5953+ char *raw_var;
5954+ int var_len;
5955+
5956+ assert(*val != NULL);
5957+
5958+ switch(arg) {
5959+ case PARSE_GET:
5960+ if(!IF_G(get_array)) {
5961+ ALLOC_ZVAL(array_ptr);
5962+ array_init(array_ptr);
5963+ INIT_PZVAL(array_ptr);
5964+ }
5965+ IF_G(get_array) = array_ptr;
5966+ break;
5967+ case PARSE_POST:
5968+ if(!IF_G(post_array)) {
5969+ ALLOC_ZVAL(array_ptr);
5970+ array_init(array_ptr);
5971+ INIT_PZVAL(array_ptr);
5972+ }
5973+ IF_G(post_array) = array_ptr;
5974+ break;
5975+ case PARSE_COOKIE:
5976+ if(!IF_G(cookie_array)) {
5977+ ALLOC_ZVAL(array_ptr);
5978+ array_init(array_ptr);
5979+ INIT_PZVAL(array_ptr);
5980+ }
5981+ IF_G(cookie_array) = array_ptr;
5982+ break;
5983+ }
5984+ Z_STRLEN(new_var) = val_len;
5985+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5986+ Z_TYPE(new_var) = IS_STRING;
5987+
5988+ var_len = strlen(var);
5989+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5990+ strcpy(raw_var, "RAW_");
5991+ strlcat(raw_var,var,var_len+5);
5992+
5993+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5994+
5995+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5996+
5997+ *new_val_len = strlen(*val);
5998+ return 1;
5999+}
6000+
6001+PHP_FUNCTION(my_get_raw)
6002+{
6003+ long arg;
6004+ char *var;
6005+ int var_len;
6006+ zval **tmp;
6007+ zval *array_ptr = NULL;
6008+ HashTable *hash_ptr;
6009+ char *raw_var;
6010+
6011+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
6012+ return;
6013+ }
6014+
6015+ switch(arg) {
6016+ case PARSE_GET:
6017+ array_ptr = IF_G(get_array);
6018+ break;
6019+ case PARSE_POST:
6020+ array_ptr = IF_G(post_array);
6021+ break;
6022+ case PARSE_COOKIE:
6023+ array_ptr = IF_G(post_array);
6024+ break;
6025+ }
6026+
6027+ if(!array_ptr) RETURN_FALSE;
6028+
6029+ /*
6030+ * I'm changing the variable name here because when running with register_globals on,
6031+ * the variable will end up in the global symbol table
6032+ */
6033+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
6034+ strcpy(raw_var, "RAW_");
6035+ strlcat(raw_var,var,var_len+5);
6036+ hash_ptr = HASH_OF(array_ptr);
6037+
6038+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
6039+ *return_value = **tmp;
6040+ zval_copy_ctor(return_value);
6041+ } else {
6042+ RETVAL_FALSE;
6043+ }
6044+ efree(raw_var);
6045+}
6046+
6047diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.10/run-tests.php
6048--- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100
6049+++ hardening-patch-4.4.2-0.4.10/run-tests.php 2006-05-11 10:36:02.000000000 +0200
6050@@ -152,6 +152,10 @@
6051 'error_reporting=2047',
6052 'display_errors=1',
6053 'log_errors=0',
6054+ 'hphp.executor.include.whitelist=cookietest',
6055+ 'hphp.log.syslog=0',
6056+ 'hphp.log.sapi=0',
6057+ 'hphp.log.script=0',
6058 'html_errors=0',
6059 'track_errors=1',
6060 'report_memleaks=1',
6061diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.10/sapi/apache/mod_php4.c
6062--- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100
6063+++ hardening-patch-4.4.2-0.4.10/sapi/apache/mod_php4.c 2006-05-11 10:36:02.000000000 +0200
6064@@ -452,7 +452,7 @@
6065 sapi_apache_get_fd,
6066 sapi_apache_force_http_10,
6067 sapi_apache_get_target_uid,
6068- sapi_apache_get_target_gid
6069+ sapi_apache_get_target_gid,
6070 };
6071 /* }}} */
6072
6073@@ -898,7 +898,11 @@
6074 {
6075 TSRMLS_FETCH();
6076 if (PG(expose_php)) {
6077+#if HARDENING_PATCH
6078+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
6079+#else
6080 ap_add_version_component("PHP/" PHP_VERSION);
6081+#endif
6082 }
6083 }
6084 #endif
6085diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.10/sapi/apache2filter/sapi_apache2.c
6086--- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6087+++ hardening-patch-4.4.2-0.4.10/sapi/apache2filter/sapi_apache2.c 2006-05-11 10:36:02.000000000 +0200
6088@@ -562,7 +562,11 @@
6089 {
6090 TSRMLS_FETCH();
6091 if (PG(expose_php)) {
6092+#if HARDENING_PATCH
6093+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6094+#else
6095 ap_add_version_component(p, "PHP/" PHP_VERSION);
6096+#endif
6097 }
6098 }
6099
6100diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.10/sapi/apache2handler/sapi_apache2.c
6101--- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6102+++ hardening-patch-4.4.2-0.4.10/sapi/apache2handler/sapi_apache2.c 2006-05-11 10:36:02.000000000 +0200
6103@@ -340,7 +340,11 @@
6104 {
6105 TSRMLS_FETCH();
6106 if (PG(expose_php)) {
6107+#if HARDENING_PATCH
6108+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6109+#else
6110 ap_add_version_component(p, "PHP/" PHP_VERSION);
6111+#endif
6112 }
6113 }
6114
6115diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.10/sapi/cgi/cgi_main.c
6116--- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100
6117+++ hardening-patch-4.4.2-0.4.10/sapi/cgi/cgi_main.c 2006-05-11 10:36:02.000000000 +0200
6118@@ -1432,11 +1432,19 @@
6119 SG(headers_sent) = 1;
6120 SG(request_info).no_headers = 1;
6121 }
6122+#if HARDENING_PATCH
6123+#if ZEND_DEBUG
6124+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6125+#else
6126+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6127+#endif
6128+#else
6129 #if ZEND_DEBUG
6130 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6131 #else
6132 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6133 #endif
6134+#endif
6135 php_end_ob_buffers(1 TSRMLS_CC);
6136 exit(0);
6137 break;
6138diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.10/sapi/cli/php_cli.c
6139--- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100
6140+++ hardening-patch-4.4.2-0.4.10/sapi/cli/php_cli.c 2006-05-11 10:36:02.000000000 +0200
6141@@ -654,11 +654,19 @@
6142 if (php_request_startup(TSRMLS_C)==FAILURE) {
6143 goto err;
6144 }
6145+#if HARDENING_PATCH
6146+#if ZEND_DEBUG
6147+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6148+#else
6149+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6150+#endif
6151+#else
6152 #if ZEND_DEBUG
6153 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6154 #else
6155 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6156 #endif
6157+#endif
6158 php_end_ob_buffers(1 TSRMLS_CC);
6159 exit_status=0;
6160 goto out;
6161diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.10/TSRM/TSRM.h
6162--- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
6163+++ hardening-patch-4.4.2-0.4.10/TSRM/TSRM.h 2006-05-11 10:36:02.000000000 +0200
6164@@ -33,6 +33,13 @@
6165 # define TSRM_API
6166 #endif
6167
6168+#if HARDENING_PATCH
6169+# if HAVE_REALPATH
6170+# undef realpath
6171+# define realpath php_realpath
6172+# endif
6173+#endif
6174+
6175 /* Only compile multi-threading functions if we're in ZTS mode */
6176 #ifdef ZTS
6177
6178@@ -84,6 +91,7 @@
6179
6180 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
6181
6182+
6183 #ifdef __cplusplus
6184 extern "C" {
6185 #endif
6186diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.10/TSRM/tsrm_virtual_cwd.c
6187--- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100
6188+++ hardening-patch-4.4.2-0.4.10/TSRM/tsrm_virtual_cwd.c 2006-05-11 10:36:02.000000000 +0200
6189@@ -179,6 +179,165 @@
6190 return p;
6191 }
6192
6193+#if HARDENING_PATCH
6194+CWD_API char *php_realpath(const char *path, char *resolved)
6195+{
6196+ struct stat sb;
6197+ char *p, *q, *s;
6198+ size_t left_len, resolved_len;
6199+ unsigned symlinks;
6200+ int serrno, slen;
6201+ int is_dir = 1;
6202+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
6203+
6204+ serrno = errno;
6205+ symlinks = 0;
6206+ if (path[0] == '/') {
6207+ resolved[0] = '/';
6208+ resolved[1] = '\0';
6209+ if (path[1] == '\0')
6210+ return (resolved);
6211+ resolved_len = 1;
6212+ left_len = strlcpy(left, path + 1, sizeof(left));
6213+ } else {
6214+ if (getcwd(resolved, PATH_MAX) == NULL) {
6215+ strlcpy(resolved, ".", PATH_MAX);
6216+ return (NULL);
6217+ }
6218+ resolved_len = strlen(resolved);
6219+ left_len = strlcpy(left, path, sizeof(left));
6220+ }
6221+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
6222+ errno = ENAMETOOLONG;
6223+ return (NULL);
6224+ }
6225+
6226+ /*
6227+ * Iterate over path components in `left'.
6228+ */
6229+ while (left_len != 0) {
6230+ /*
6231+ * Extract the next path component and adjust `left'
6232+ * and its length.
6233+ */
6234+ p = strchr(left, '/');
6235+ s = p ? p : left + left_len;
6236+ if (s - left >= sizeof(next_token)) {
6237+ errno = ENAMETOOLONG;
6238+ return (NULL);
6239+ }
6240+ memcpy(next_token, left, s - left);
6241+ next_token[s - left] = '\0';
6242+ left_len -= s - left;
6243+ if (p != NULL)
6244+ memmove(left, s + 1, left_len + 1);
6245+ if (resolved[resolved_len - 1] != '/') {
6246+ if (resolved_len + 1 >= PATH_MAX) {
6247+ errno = ENAMETOOLONG;
6248+ return (NULL);
6249+ }
6250+ resolved[resolved_len++] = '/';
6251+ resolved[resolved_len] = '\0';
6252+ }
6253+ if (next_token[0] == '\0')
6254+ continue;
6255+ else if (strcmp(next_token, ".") == 0)
6256+ continue;
6257+ else if (strcmp(next_token, "..") == 0) {
6258+ /*
6259+ * Strip the last path component except when we have
6260+ * single "/"
6261+ */
6262+ if (!is_dir) {
6263+ errno = ENOENT;
6264+ return (NULL);
6265+ }
6266+ if (resolved_len > 1) {
6267+ resolved[resolved_len - 1] = '\0';
6268+ q = strrchr(resolved, '/');
6269+ *q = '\0';
6270+ resolved_len = q - resolved;
6271+ }
6272+ continue;
6273+ }
6274+
6275+ /*
6276+ * Append the next path component and lstat() it. If
6277+ * lstat() fails we still can return successfully if
6278+ * there are no more path components left.
6279+ */
6280+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6281+ if (resolved_len >= PATH_MAX) {
6282+ errno = ENAMETOOLONG;
6283+ return (NULL);
6284+ }
6285+ if (lstat(resolved, &sb) != 0) {
6286+ if (errno == ENOENT && p == NULL) {
6287+ errno = serrno;
6288+ return (resolved);
6289+ }
6290+ return (NULL);
6291+ }
6292+ if (S_ISLNK(sb.st_mode)) {
6293+ if (symlinks++ > MAXSYMLINKS) {
6294+ errno = ELOOP;
6295+ return (NULL);
6296+ }
6297+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6298+ if (slen < 0)
6299+ return (NULL);
6300+ symlink[slen] = '\0';
6301+ if (symlink[0] == '/') {
6302+ resolved[1] = 0;
6303+ resolved_len = 1;
6304+ } else if (resolved_len > 1) {
6305+ /* Strip the last path component. */
6306+ resolved[resolved_len - 1] = '\0';
6307+ q = strrchr(resolved, '/');
6308+ *q = '\0';
6309+ resolved_len = q - resolved;
6310+ }
6311+
6312+ /*
6313+ * If there are any path components left, then
6314+ * append them to symlink. The result is placed
6315+ * in `left'.
6316+ */
6317+ if (p != NULL) {
6318+ if (symlink[slen - 1] != '/') {
6319+ if (slen + 1 >= sizeof(symlink)) {
6320+ errno = ENAMETOOLONG;
6321+ return (NULL);
6322+ }
6323+ symlink[slen] = '/';
6324+ symlink[slen + 1] = 0;
6325+ }
6326+ left_len = strlcat(symlink, left, sizeof(left));
6327+ if (left_len >= sizeof(left)) {
6328+ errno = ENAMETOOLONG;
6329+ return (NULL);
6330+ }
6331+ }
6332+ left_len = strlcpy(left, symlink, sizeof(left));
6333+ } else {
6334+ if (S_ISDIR(sb.st_mode)) {
6335+ is_dir = 1;
6336+ } else {
6337+ is_dir = 0;
6338+ }
6339+ }
6340+ }
6341+
6342+ /*
6343+ * Remove trailing slash except when the resolved pathname
6344+ * is a single "/".
6345+ */
6346+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6347+ resolved[resolved_len - 1] = '\0';
6348+ return (resolved);
6349+}
6350+#endif
6351+
6352 CWD_API void virtual_cwd_startup(void)
6353 {
6354 char cwd[MAXPATHLEN];
6355@@ -300,8 +459,11 @@
6356
6357 if (path_length == 0)
6358 return (0);
6359- if (path_length >= MAXPATHLEN)
6360+ if (path_length >= MAXPATHLEN) {
6361+ state->cwd[0] = 0;
6362+ state->cwd_length = 0;
6363 return (1);
6364+ }
6365
6366 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6367 /* cwd_length can be 0 when getcwd() fails.
6368@@ -313,8 +475,9 @@
6369 path = resolved_path;
6370 path_length = strlen(path);
6371 } else {
6372- /* disable for now
6373- return 1; */
6374+ state->cwd[0] = 0;
6375+ state->cwd_length = 0;
6376+ return 1;
6377 }
6378 }
6379 } else { /* Concat current directory with relative path and then run realpath() on it */
6380@@ -323,6 +486,8 @@
6381
6382 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6383 if (!tmp) {
6384+ state->cwd[0] = 0;
6385+ state->cwd_length = 0;
6386 return 1;
6387 }
6388 memcpy(ptr, state->cwd, state->cwd_length);
6389@@ -332,6 +497,8 @@
6390 ptr += path_length;
6391 *ptr = '\0';
6392 if (strlen(tmp) >= MAXPATHLEN) {
6393+ state->cwd[0] = 0;
6394+ state->cwd_length = 0;
6395 free(tmp);
6396 return 1;
6397 }
6398@@ -340,9 +507,10 @@
6399 path = resolved_path;
6400 path_length = strlen(path);
6401 } else {
6402- /* disable for now
6403+ state->cwd[0] = 0;
6404+ state->cwd_length = 0;
6405 free(tmp);
6406- return 1; */
6407+ return 1;
6408 }
6409 }
6410 free(tmp);
6411diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.10/TSRM/tsrm_virtual_cwd.h
6412--- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100
6413+++ hardening-patch-4.4.2-0.4.10/TSRM/tsrm_virtual_cwd.h 2006-05-11 10:36:02.000000000 +0200
6414@@ -128,6 +128,22 @@
6415
6416 typedef int (*verify_path_func)(const cwd_state *);
6417
6418+#ifndef HAVE_STRLCPY
6419+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6420+#undef strlcpy
6421+#define strlcpy php_strlcpy
6422+#endif
6423+
6424+#ifndef HAVE_STRLCAT
6425+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6426+#undef strlcat
6427+#define strlcat php_strlcat
6428+#endif
6429+
6430+
6431+#if HARDENING_PATCH
6432+CWD_API char *php_realpath(const char *path, char *resolved);
6433+#endif
6434 CWD_API void virtual_cwd_startup(void);
6435 CWD_API void virtual_cwd_shutdown(void);
6436 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6437diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.10/Zend/zend_alloc.c
6438--- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100
6439+++ hardening-patch-4.4.2-0.4.10/Zend/zend_alloc.c 2006-05-11 10:36:02.000000000 +0200
6440@@ -56,6 +56,11 @@
6441 # define END_MAGIC_SIZE 0
6442 #endif
6443
6444+#if HARDENING_PATCH_MM_PROTECT
6445+# define CANARY_SIZE sizeof(unsigned int)
6446+#else
6447+# define CANARY_SIZE 0
6448+#endif
6449
6450 # if MEMORY_LIMIT
6451 # if ZEND_DEBUG
6452@@ -96,9 +101,17 @@
6453 if (p==AG(head)) { \
6454 AG(head) = p->pNext; \
6455 } else { \
6456+ if (p != p->pLast->pNext) { \
6457+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6458+ exit(1); \
6459+ } \
6460 p->pLast->pNext = p->pNext; \
6461 } \
6462 if (p->pNext) { \
6463+ if (p != p->pNext->pLast) { \
6464+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6465+ exit(1); \
6466+ } \
6467 p->pNext->pLast = p->pLast; \
6468 }
6469
6470@@ -130,6 +143,12 @@
6471 DECLARE_CACHE_VARS();
6472 TSRMLS_FETCH();
6473
6474+#if HARDENING_PATCH_MM_PROTECT
6475+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6476+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6477+ exit(1);
6478+ }
6479+#endif
6480 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6481
6482 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6483@@ -147,6 +166,10 @@
6484 AG(cache_stats)[CACHE_INDEX][1]++;
6485 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6486 #endif
6487+#if HARDENING_PATCH_MM_PROTECT
6488+ p->canary = HG(canary_1);
6489+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6490+#endif
6491 p->cached = 0;
6492 p->size = size;
6493 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6494@@ -162,7 +185,7 @@
6495 AG(allocated_memory_peak) = AG(allocated_memory);
6496 }
6497 #endif
6498- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6499+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6500 }
6501
6502 HANDLE_BLOCK_INTERRUPTIONS();
6503@@ -192,7 +215,10 @@
6504 # endif
6505 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6506 #endif
6507-
6508+#if HARDENING_PATCH_MM_PROTECT
6509+ p->canary = HG(canary_1);
6510+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6511+#endif
6512 HANDLE_UNBLOCK_INTERRUPTIONS();
6513 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6514 }
6515@@ -219,17 +245,36 @@
6516 return emalloc_rel(lval + offset);
6517 }
6518 }
6519-
6520+
6521+#if HARDENING_PATCH
6522+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6523+#endif
6524 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6525 return 0;
6526 }
6527
6528 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6529 {
6530+#if HARDENING_PATCH_MM_PROTECT
6531+ unsigned int canary_2;
6532+#endif
6533 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6534 DECLARE_CACHE_VARS();
6535 TSRMLS_FETCH();
6536
6537+#if HARDENING_PATCH_MM_PROTECT
6538+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6539+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6540+ if (canary_2 != HG(canary_2)) {
6541+efree_canary_mismatch:
6542+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6543+ exit(1);
6544+ }
6545+ /* to catch double efree()s */
6546+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6547+ p->canary = 0;
6548+#endif
6549+
6550 #if defined(ZTS) && TSRM_DEBUG
6551 if (p->thread_id != tsrm_thread_id()) {
6552 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6553@@ -274,6 +319,9 @@
6554 size_t _size = nmemb * size;
6555
6556 if (nmemb && (_size/nmemb!=size)) {
6557+#if HARDENING_PATCH
6558+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6559+#endif
6560 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6561 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6562 kill(getpid(), SIGSEGV);
6563@@ -293,6 +341,9 @@
6564
6565 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6566 {
6567+#if HARDENING_PATCH_MM_PROTECT
6568+ unsigned int canary_2;
6569+#endif
6570 zend_mem_header *p;
6571 zend_mem_header *orig;
6572 DECLARE_CACHE_VARS();
6573@@ -304,6 +355,16 @@
6574
6575 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6576
6577+#if HARDENING_PATCH_MM_PROTECT
6578+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6579+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6580+ if (canary_2 != HG(canary_2)) {
6581+erealloc_canary_mismatch:
6582+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6583+ exit(1);
6584+ }
6585+#endif
6586+
6587 #if defined(ZTS) && TSRM_DEBUG
6588 if (p->thread_id != tsrm_thread_id()) {
6589 void *new_p;
6590@@ -327,7 +388,7 @@
6591 }
6592 #endif
6593 REMOVE_POINTER_FROM_LIST(p);
6594- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6595+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6596 if (!p) {
6597 if (!allow_failure) {
6598 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6599@@ -349,6 +410,9 @@
6600 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6601 #endif
6602
6603+#if HARDENING_PATCH_MM_PROTECT
6604+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6605+#endif
6606 p->size = size;
6607
6608 HANDLE_UNBLOCK_INTERRUPTIONS();
6609@@ -423,6 +487,10 @@
6610 {
6611 AG(head) = NULL;
6612
6613+#if HARDENING_PATCH_MM_PROTECT
6614+ HG(canary_1) = zend_canary();
6615+ HG(canary_2) = zend_canary();
6616+#endif
6617 #if MEMORY_LIMIT
6618 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6619 AG(allocated_memory) = 0;
6620diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.10/Zend/zend_alloc.h
6621--- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100
6622+++ hardening-patch-4.4.2-0.4.10/Zend/zend_alloc.h 2006-05-11 10:36:02.000000000 +0200
6623@@ -32,6 +32,9 @@
6624 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6625
6626 typedef struct _zend_mem_header {
6627+#if HARDENING_PATCH_MM_PROTECT
6628+ unsigned int canary;
6629+#endif
6630 #if ZEND_DEBUG
6631 long magic;
6632 char *filename;
6633diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.10/Zend/zend_builtin_functions.c
6634--- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100
6635+++ hardening-patch-4.4.2-0.4.10/Zend/zend_builtin_functions.c 2006-05-11 10:36:02.000000000 +0200
6636@@ -49,6 +49,9 @@
6637 static ZEND_FUNCTION(crash);
6638 #endif
6639 #endif
6640+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6641+static ZEND_FUNCTION(heap_overflow);
6642+#endif
6643 static ZEND_FUNCTION(get_included_files);
6644 static ZEND_FUNCTION(is_subclass_of);
6645 static ZEND_FUNCTION(is_a);
6646@@ -101,6 +104,9 @@
6647 ZEND_FE(crash, NULL)
6648 #endif
6649 #endif
6650+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6651+ ZEND_FE(heap_overflow, NULL)
6652+#endif
6653 ZEND_FE(get_included_files, NULL)
6654 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6655 ZEND_FE(is_subclass_of, NULL)
6656@@ -805,6 +811,19 @@
6657
6658 #endif /* ZEND_DEBUG */
6659
6660+
6661+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6662+ZEND_FUNCTION(heap_overflow)
6663+{
6664+ char *nowhere = emalloc(10);
6665+
6666+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6667+
6668+ efree(nowhere);
6669+}
6670+#endif
6671+
6672+
6673 /* {{{ proto array get_included_files(void)
6674 Returns an array with the file names that were include_once()'d */
6675 ZEND_FUNCTION(get_included_files)
6676diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.10/Zend/zend.c
6677--- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100
6678+++ hardening-patch-4.4.2-0.4.10/Zend/zend.c 2006-05-11 10:36:02.000000000 +0200
6679@@ -53,6 +53,12 @@
6680 ZEND_API void (*zend_unblock_interruptions)(void);
6681 ZEND_API void (*zend_ticks_function)(int ticks);
6682 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6683+#if HARDENING_PATCH
6684+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6685+#endif
6686+#if HARDENING_PATCH_INC_PROTECT
6687+ZEND_API int (*zend_is_valid_include)(zval *z);
6688+#endif
6689
6690 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6691
6692@@ -70,9 +76,390 @@
6693 return SUCCESS;
6694 }
6695
6696+#if HARDENING_PATCH
6697+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6698+{
6699+ if (!new_value) {
6700+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6701+ } else {
6702+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6703+ }
6704+ return SUCCESS;
6705+}
6706+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6707+{
6708+ if (!new_value) {
6709+ EG(hphp_log_syslog_facility) = LOG_USER;
6710+ } else {
6711+ EG(hphp_log_syslog_facility) = atoi(new_value);
6712+ }
6713+ return SUCCESS;
6714+}
6715+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6716+{
6717+ if (!new_value) {
6718+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6719+ } else {
6720+ EG(hphp_log_syslog_priority) = atoi(new_value);
6721+ }
6722+ return SUCCESS;
6723+}
6724+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6725+{
6726+ if (!new_value) {
6727+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6728+ } else {
6729+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6730+ }
6731+ return SUCCESS;
6732+}
6733+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6734+{
6735+ if (!new_value) {
6736+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6737+ } else {
6738+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6739+ }
6740+ return SUCCESS;
6741+}
6742+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6743+{
6744+ if (EG(hphp_log_scriptname)) {
6745+ pefree(EG(hphp_log_scriptname),1);
6746+ }
6747+ EG(hphp_log_scriptname) = NULL;
6748+ if (new_value) {
6749+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6750+ }
6751+ return SUCCESS;
6752+}
6753+
6754+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6755+{
6756+ char *s = NULL, *e, *val;
6757+ unsigned long dummy = 1;
6758+
6759+ if (!new_value) {
6760+include_whitelist_destroy:
6761+ if (HG(include_whitelist)) {
6762+ zend_hash_destroy(HG(include_whitelist));
6763+ pefree(HG(include_whitelist),1);
6764+ }
6765+ HG(include_whitelist) = NULL;
6766+ return SUCCESS;
6767+ }
6768+ if (!(*new_value)) {
6769+ goto include_whitelist_destroy;
6770+ }
6771+
6772+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6773+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6774+
6775+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6776+ e = val;
6777+
6778+ while (*e) {
6779+ switch (*e) {
6780+ case ' ':
6781+ case ',':
6782+ if (s) {
6783+ *e = '\0';
6784+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6785+ s = NULL;
6786+ }
6787+ break;
6788+ default:
6789+ if (!s) {
6790+ s = e;
6791+ }
6792+ break;
6793+ }
6794+ e++;
6795+ }
6796+ if (s) {
6797+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6798+ }
6799+ efree(val);
6800+
6801+ return SUCCESS;
6802+}
6803+
6804+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6805+{
6806+ char *s = NULL, *e, *val;
6807+ unsigned long dummy = 1;
6808+
6809+ if (!new_value) {
6810+include_blacklist_destroy:
6811+ if (HG(include_blacklist)) {
6812+ zend_hash_destroy(HG(include_blacklist));
6813+ pefree(HG(include_blacklist),1);
6814+ }
6815+ HG(include_blacklist) = NULL;
6816+ return SUCCESS;
6817+ }
6818+ if (!(*new_value)) {
6819+ goto include_blacklist_destroy;
6820+ }
6821+
6822+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6823+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6824+
6825+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6826+ e = val;
6827+
6828+ while (*e) {
6829+ switch (*e) {
6830+ case ' ':
6831+ case ',':
6832+ if (s) {
6833+ *e = '\0';
6834+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6835+ s = NULL;
6836+ }
6837+ break;
6838+ default:
6839+ if (!s) {
6840+ s = e;
6841+ }
6842+ break;
6843+ }
6844+ e++;
6845+ }
6846+ if (s) {
6847+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6848+ }
6849+ efree(val);
6850+
6851+ return SUCCESS;
6852+}
6853+
6854+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6855+{
6856+ char *s = NULL, *e, *val;
6857+ unsigned long dummy = 1;
6858+
6859+ if (!new_value) {
6860+eval_whitelist_destroy:
6861+ if (HG(eval_whitelist)) {
6862+ zend_hash_destroy(HG(eval_whitelist));
6863+ pefree(HG(eval_whitelist),1);
6864+ }
6865+ HG(eval_whitelist) = NULL;
6866+ return SUCCESS;
6867+ }
6868+ if (!(*new_value)) {
6869+ goto eval_whitelist_destroy;
6870+ }
6871+
6872+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6873+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6874+
6875+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6876+ e = val;
6877+
6878+ while (*e) {
6879+ switch (*e) {
6880+ case ' ':
6881+ case ',':
6882+ if (s) {
6883+ *e = '\0';
6884+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6885+ s = NULL;
6886+ }
6887+ break;
6888+ default:
6889+ if (!s) {
6890+ s = e;
6891+ }
6892+ break;
6893+ }
6894+ e++;
6895+ }
6896+ if (s) {
6897+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6898+ }
6899+ efree(val);
6900+
6901+ return SUCCESS;
6902+}
6903+
6904+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6905+{
6906+ char *s = NULL, *e, *val;
6907+ unsigned long dummy = 1;
6908+
6909+ if (!new_value) {
6910+eval_blacklist_destroy:
6911+ if (HG(eval_blacklist)) {
6912+ zend_hash_destroy(HG(eval_blacklist));
6913+ pefree(HG(eval_blacklist), 1);
6914+ }
6915+ HG(eval_blacklist) = NULL;
6916+ return SUCCESS;
6917+ }
6918+ if (!(*new_value)) {
6919+ goto eval_blacklist_destroy;
6920+ }
6921+
6922+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6923+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6924+
6925+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6926+ e = val;
6927+
6928+ while (*e) {
6929+ switch (*e) {
6930+ case ' ':
6931+ case ',':
6932+ if (s) {
6933+ *e = '\0';
6934+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6935+ s = NULL;
6936+ }
6937+ break;
6938+ default:
6939+ if (!s) {
6940+ s = e;
6941+ }
6942+ break;
6943+ }
6944+ e++;
6945+ }
6946+ if (s) {
6947+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6948+ }
6949+ efree(val);
6950+
6951+
6952+ return SUCCESS;
6953+}
6954+
6955+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6956+{
6957+ char *s = NULL, *e, *val;
6958+ unsigned long dummy = 1;
6959+
6960+ if (!new_value) {
6961+func_whitelist_destroy:
6962+ if (HG(func_whitelist)) {
6963+ zend_hash_destroy(HG(func_whitelist));
6964+ pefree(HG(func_whitelist),1);
6965+ }
6966+ HG(func_whitelist) = NULL;
6967+ return SUCCESS;
6968+ }
6969+ if (!(*new_value)) {
6970+ goto func_whitelist_destroy;
6971+ }
6972+
6973+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6974+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6975+
6976+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6977+ e = val;
6978+
6979+ while (*e) {
6980+ switch (*e) {
6981+ case ' ':
6982+ case ',':
6983+ if (s) {
6984+ *e = '\0';
6985+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6986+ s = NULL;
6987+ }
6988+ break;
6989+ default:
6990+ if (!s) {
6991+ s = e;
6992+ }
6993+ break;
6994+ }
6995+ e++;
6996+ }
6997+ if (s) {
6998+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6999+ }
7000+ efree(val);
7001+
7002+ return SUCCESS;
7003+}
7004+
7005+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
7006+{
7007+ char *s = NULL, *e, *val;
7008+ unsigned long dummy = 1;
7009+
7010+ if (!new_value) {
7011+func_blacklist_destroy:
7012+ if (HG(func_blacklist)) {
7013+ zend_hash_destroy(HG(func_blacklist));
7014+ pefree(HG(func_blacklist),1);
7015+ }
7016+ HG(func_blacklist) = NULL;
7017+ return SUCCESS;
7018+ }
7019+ if (!(*new_value)) {
7020+ goto func_blacklist_destroy;
7021+ }
7022+
7023+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
7024+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
7025+
7026+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7027+ e = val;
7028+
7029+ while (*e) {
7030+ switch (*e) {
7031+ case ' ':
7032+ case ',':
7033+ if (s) {
7034+ *e = '\0';
7035+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7036+ s = NULL;
7037+ }
7038+ break;
7039+ default:
7040+ if (!s) {
7041+ s = e;
7042+ }
7043+ break;
7044+ }
7045+ e++;
7046+ }
7047+ if (s) {
7048+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7049+ }
7050+ efree(val);
7051+
7052+
7053+ return SUCCESS;
7054+}
7055+
7056+#endif
7057
7058 ZEND_INI_BEGIN()
7059 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
7060+#if HARDENING_PATCH
7061+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
7062+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
7063+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
7064+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
7065+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
7066+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
7067+ STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for", "0", ZEND_INI_SYSTEM, OnUpdateBool, hphp_log_use_x_forwarded_for, zend_executor_globals, executor_globals)
7068+
7069+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
7070+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
7071+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
7072+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
7073+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
7074+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
7075+
7076+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
7077+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
7078+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
7079+#endif
7080 ZEND_INI_END()
7081
7082
7083@@ -354,8 +741,12 @@
7084 zend_init_rsrc_plist(TSRMLS_C);
7085 EG(lambda_count)=0;
7086 EG(user_error_handler) = NULL;
7087+ EG(in_code_type) = 0;
7088 EG(in_execution) = 0;
7089 EG(current_execute_data) = NULL;
7090+#if HARDENING_PATCH
7091+ EG(hphp_log_scriptname) = NULL;
7092+#endif
7093 }
7094
7095
7096@@ -420,6 +811,14 @@
7097 extern zend_scanner_globals language_scanner_globals;
7098 #endif
7099
7100+ /* Set up Hardening-Patch utility functions first */
7101+#if HARDENING_PATCH
7102+ zend_security_log = utility_functions->security_log_function;
7103+#endif
7104+#if HARDENING_PATCH_INC_PROTECT
7105+ zend_is_valid_include = utility_functions->is_valid_include;
7106+#endif
7107+
7108 #ifdef ZTS
7109 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
7110 #else
7111@@ -619,6 +1018,7 @@
7112 }
7113 CG(unclean_shutdown) = 1;
7114 CG(in_compilation) = EG(in_execution) = 0;
7115+ EG(in_code_type) = 0;
7116 EG(current_execute_data) = NULL;
7117 longjmp(EG(bailout), FAILURE);
7118 }
7119diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.10/Zend/zend_canary.c
7120--- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
7121+++ hardening-patch-4.4.2-0.4.10/Zend/zend_canary.c 2006-05-11 10:36:02.000000000 +0200
7122@@ -0,0 +1,58 @@
7123+/*
7124+ +----------------------------------------------------------------------+
7125+ | Hardening-Patch for PHP |
7126+ +----------------------------------------------------------------------+
7127+ | Copyright (c) 2004-2005 Stefan Esser |
7128+ +----------------------------------------------------------------------+
7129+ | This source file is subject to version 2.02 of the PHP license, |
7130+ | that is bundled with this package in the file LICENSE, and is |
7131+ | available at through the world-wide-web at |
7132+ | http://www.php.net/license/2_02.txt. |
7133+ | If you did not receive a copy of the PHP license and are unable to |
7134+ | obtain it through the world-wide-web, please send a note to |
7135+ | license@php.net so we can mail you a copy immediately. |
7136+ +----------------------------------------------------------------------+
7137+ | Author: Stefan Esser <sesser@hardened-php.net> |
7138+ +----------------------------------------------------------------------+
7139+ */
7140+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
7141+
7142+#include "zend.h"
7143+
7144+#include <stdio.h>
7145+#include <stdlib.h>
7146+
7147+
7148+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7149+
7150+/* will be replaced later with more compatible method */
7151+ZEND_API unsigned int zend_canary()
7152+{
7153+ time_t t;
7154+ unsigned int canary;
7155+ int fd;
7156+
7157+ fd = open("/dev/urandom", 0);
7158+ if (fd != -1) {
7159+ int r = read(fd, &canary, sizeof(canary));
7160+ close(fd);
7161+ if (r == sizeof(canary)) {
7162+ return (canary);
7163+ }
7164+ }
7165+ /* not good but we never want to do this */
7166+ time(&t);
7167+ canary = *(unsigned int *)&t + getpid() << 16;
7168+ return (canary);
7169+}
7170+#endif
7171+
7172+
7173+/*
7174+ * Local variables:
7175+ * tab-width: 4
7176+ * c-basic-offset: 4
7177+ * End:
7178+ * vim600: sw=4 ts=4 fdm=marker
7179+ * vim<600: sw=4 ts=4
7180+ */
7181diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.10/Zend/zend_compile.c
7182--- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100
7183+++ hardening-patch-4.4.2-0.4.10/Zend/zend_compile.c 2006-05-11 10:36:02.000000000 +0200
7184@@ -768,6 +768,13 @@
7185 op_array.function_name = name;
7186 op_array.arg_types = NULL;
7187 op_array.return_reference = return_reference;
7188+#if HARDENING_PATCH
7189+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7190+ op_array.created_by_eval = 1;
7191+ } else {
7192+ op_array.created_by_eval = 0;
7193+ }
7194+#endif
7195
7196 if (is_method) {
7197 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
7198diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.10/Zend/zend_compile.h
7199--- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100
7200+++ hardening-patch-4.4.2-0.4.10/Zend/zend_compile.h 2006-05-11 10:36:02.000000000 +0200
7201@@ -106,6 +106,9 @@
7202 char *filename;
7203
7204 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
7205+#if HARDENING_PATCH
7206+ zend_bool created_by_eval;
7207+#endif
7208 };
7209
7210
7211@@ -549,6 +552,7 @@
7212 #define ZEND_USER_FUNCTION 2
7213 #define ZEND_OVERLOADED_FUNCTION 3
7214 #define ZEND_EVAL_CODE 4
7215+#define ZEND_SANDBOX_CODE 6
7216
7217 #define ZEND_INTERNAL_CLASS 1
7218 #define ZEND_USER_CLASS 2
7219diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.10/Zend/zend_constants.c
7220--- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100
7221+++ hardening-patch-4.4.2-0.4.10/Zend/zend_constants.c 2006-05-11 10:36:02.000000000 +0200
7222@@ -111,6 +111,73 @@
7223 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
7224
7225 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
7226+#if HARDENING_PATCH
7227+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
7228+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
7229+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
7230+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
7231+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
7232+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
7233+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
7234+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
7235+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
7236+
7237+ /* error levels */
7238+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
7239+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
7240+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
7241+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
7242+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
7243+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
7244+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
7245+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
7246+ /* facility: type of program logging the message */
7247+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
7248+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
7249+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
7250+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
7251+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
7252+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
7253+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
7254+#ifdef LOG_NEWS
7255+ /* No LOG_NEWS on HP-UX */
7256+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
7257+#endif
7258+#ifdef LOG_UUCP
7259+ /* No LOG_UUCP on HP-UX */
7260+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
7261+#endif
7262+#ifdef LOG_CRON
7263+ /* apparently some systems don't have this one */
7264+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
7265+#endif
7266+#ifdef LOG_AUTHPRIV
7267+ /* AIX doesn't have LOG_AUTHPRIV */
7268+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7269+#endif
7270+#if !defined(PHP_WIN32) && !defined(NETWARE)
7271+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7272+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7273+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7274+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7275+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7276+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7277+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7278+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7279+#endif
7280+ /* options */
7281+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7282+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7283+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7284+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7285+#ifdef LOG_NOWAIT
7286+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7287+#endif
7288+#ifdef LOG_PERROR
7289+ /* AIX doesn't have LOG_PERROR */
7290+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7291+#endif
7292+#endif
7293
7294 /* true/false constants */
7295 {
7296diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.10/Zend/zend_errors.h
7297--- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100
7298+++ hardening-patch-4.4.2-0.4.10/Zend/zend_errors.h 2006-05-11 10:36:02.000000000 +0200
7299@@ -36,5 +36,17 @@
7300 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
7301 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7302
7303+#if HARDENING_PATCH
7304+#define S_MEMORY (1<<0L)
7305+#define S_VARS (1<<1L)
7306+#define S_FILES (1<<2L)
7307+#define S_INCLUDE (1<<3L)
7308+#define S_SQL (1<<4L)
7309+#define S_EXECUTOR (1<<5L)
7310+#define S_MISC (1<<30L)
7311+#define S_INTERNAL (1<<29L)
7312+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
7313+#endif
7314+
7315 #endif /* ZEND_ERRORS_H */
7316
7317diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.10/Zend/zend_execute_API.c
7318--- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100
7319+++ hardening-patch-4.4.2-0.4.10/Zend/zend_execute_API.c 2006-05-11 10:36:02.000000000 +0200
7320@@ -142,6 +142,7 @@
7321 EG(class_table) = CG(class_table);
7322
7323 EG(in_execution) = 0;
7324+ EG(in_code_type) = 0;
7325
7326 zend_ptr_stack_init(&EG(argument_stack));
7327
7328@@ -431,12 +432,14 @@
7329 zend_execute_data execute_data;
7330
7331 /* Initialize execute_data */
7332+ memset(&execute_data, 0, sizeof(execute_data));
7333 EX(fbc) = NULL;
7334 EX(object).ptr = NULL;
7335 EX(ce) = NULL;
7336 EX(Ts) = NULL;
7337 EX(op_array) = NULL;
7338 EX(opline) = NULL;
7339+ EX(execute_depth) = 0;
7340
7341 *retval_ptr_ptr = NULL;
7342
7343@@ -494,6 +497,39 @@
7344 zval_dtor(&function_name_copy);
7345 return FAILURE;
7346 }
7347+#if HARDENING_PATCH
7348+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7349+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7350+ if (HG(eval_whitelist) != NULL) {
7351+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7352+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7353+ zval_dtor(&function_name_copy);
7354+ zend_bailout();
7355+ }
7356+ } else if (HG(eval_blacklist) != NULL) {
7357+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7358+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7359+ zval_dtor(&function_name_copy);
7360+ zend_bailout();
7361+ }
7362+ }
7363+ }
7364+
7365+ if (HG(func_whitelist) != NULL) {
7366+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7367+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7368+ zval_dtor(&function_name_copy);
7369+ zend_bailout();
7370+ }
7371+ } else if (HG(func_blacklist) != NULL) {
7372+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7373+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7374+ zval_dtor(&function_name_copy);
7375+ zend_bailout();
7376+ }
7377+ }
7378+ }
7379+#endif
7380 zval_dtor(&function_name_copy);
7381
7382 for (i=0; i<param_count; i++) {
7383@@ -606,8 +642,7 @@
7384 return SUCCESS;
7385 }
7386
7387-
7388-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7389+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7390 {
7391 zval pv;
7392 zend_op_array *new_op_array;
7393@@ -640,6 +675,7 @@
7394 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7395 zend_op **original_opline_ptr = EG(opline_ptr);
7396
7397+ new_op_array->type = type;
7398 EG(return_value_ptr_ptr) = &local_retval_ptr;
7399 EG(active_op_array) = new_op_array;
7400 EG(no_extensions)=1;
7401@@ -673,6 +709,10 @@
7402 return retval;
7403 }
7404
7405+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7406+{
7407+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7408+}
7409
7410 void execute_new_code(TSRMLS_D)
7411 {
7412diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.10/Zend/zend_execute.c
7413--- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100
7414+++ hardening-patch-4.4.2-0.4.10/Zend/zend_execute.c 2006-05-11 10:36:02.000000000 +0200
7415@@ -1042,6 +1042,7 @@
7416 zend_execute_data execute_data;
7417
7418 /* Initialize execute_data */
7419+ memset(&execute_data, 0, sizeof(execute_data));
7420 EX(fbc) = NULL;
7421 EX(ce) = NULL;
7422 EX(object).ptr = NULL;
7423@@ -1053,9 +1054,21 @@
7424 }
7425 EX(prev_execute_data) = EG(current_execute_data);
7426 EX(original_in_execution)=EG(in_execution);
7427+ EX(original_in_code_type)=EG(in_code_type);
7428
7429 EG(current_execute_data) = &execute_data;
7430
7431+#if HARDENING_PATCH
7432+ EX(execute_depth) = 0;
7433+
7434+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7435+ EG(in_code_type) = ZEND_EVAL_CODE;
7436+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7437+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7438+ op_array->type = ZEND_EVAL_CODE;
7439+ }
7440+#endif
7441+
7442 EG(in_execution) = 1;
7443 if (op_array->start_op) {
7444 EX(opline) = op_array->start_op;
7445@@ -1087,6 +1100,19 @@
7446 }
7447 }
7448
7449+#if HARDENING_PATCH
7450+ if (EX(prev_execute_data) == NULL) {
7451+ EX(execute_depth) = 0;
7452+ } else {
7453+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7454+ }
7455+
7456+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7457+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7458+ zend_bailout();
7459+ }
7460+#endif
7461+
7462 while (1) {
7463 #ifdef ZEND_WIN32
7464 if (EG(timed_out)) {
7465@@ -1634,6 +1660,36 @@
7466 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7467 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7468 }
7469+#if HARDENING_PATCH
7470+ if (active_function_table == EG(function_table)) {
7471+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7472+ if (HG(eval_whitelist) != NULL) {
7473+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7474+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7475+ zend_bailout();
7476+ }
7477+ } else if (HG(eval_blacklist) != NULL) {
7478+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7479+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7480+ zend_bailout();
7481+ }
7482+ }
7483+ }
7484+
7485+ if (HG(func_whitelist) != NULL) {
7486+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7487+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7488+ zend_bailout();
7489+ }
7490+ } else if (HG(func_blacklist) != NULL) {
7491+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7492+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7493+ zend_bailout();
7494+ }
7495+ }
7496+ }
7497+#endif
7498+
7499 zval_dtor(&tmp);
7500 EX(fbc) = function;
7501 overloaded_function_call_cont:
7502@@ -1649,6 +1705,35 @@
7503 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7504 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7505 }
7506+#if HARDENING_PATCH
7507+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7508+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7509+ if (HG(eval_whitelist) != NULL) {
7510+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7511+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7512+ zend_bailout();
7513+ }
7514+ } else if (HG(eval_blacklist) != NULL) {
7515+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7516+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7517+ zend_bailout();
7518+ }
7519+ }
7520+ }
7521+
7522+ if (HG(func_whitelist) != NULL) {
7523+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7524+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7525+ zend_bailout();
7526+ }
7527+ } else if (HG(func_blacklist) != NULL) {
7528+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7529+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7530+ zend_bailout();
7531+ }
7532+ }
7533+ }
7534+#endif
7535 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7536 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7537 EX(object).ptr = NULL;
7538@@ -1821,6 +1906,7 @@
7539 efree(EX(Ts));
7540 }
7541 EG(in_execution) = EX(original_in_execution);
7542+ EG(in_code_type) = EX(original_in_code_type);
7543 EG(current_execute_data) = EX(prev_execute_data);
7544 return;
7545 }
7546@@ -2210,7 +2296,12 @@
7547 int dummy = 1;
7548 zend_file_handle file_handle = {0};
7549
7550+#if HARDENING_PATCH_INC_PROTECT
7551+ if (zend_is_valid_include(inc_filename)
7552+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7553+#else
7554 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7555+#endif
7556 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7557
7558 file_handle.filename = inc_filename->value.str.val;
7559@@ -2239,6 +2330,11 @@
7560 break;
7561 case ZEND_INCLUDE:
7562 case ZEND_REQUIRE:
7563+#if HARDENING_PATCH_INC_PROTECT
7564+ if (!zend_is_valid_include(inc_filename)) {
7565+ break;
7566+ }
7567+#endif
7568 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7569 break;
7570 case ZEND_EVAL: {
7571diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.10/Zend/zend_execute_globals.h
7572--- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100
7573+++ hardening-patch-4.4.2-0.4.10/Zend/zend_execute_globals.h 2006-05-11 10:36:02.000000000 +0200
7574@@ -60,6 +60,8 @@
7575 object_info object;
7576 temp_variable *Ts;
7577 zend_bool original_in_execution;
7578+ zend_uint original_in_code_type;
7579+ zend_uint execute_depth;
7580 zend_op_array *op_array;
7581 struct _zend_execute_data *prev_execute_data;
7582 } zend_execute_data;
7583diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.10/Zend/zend_extensions.c
7584--- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100
7585+++ hardening-patch-4.4.2-0.4.10/Zend/zend_extensions.c 2006-05-11 10:36:02.000000000 +0200
7586@@ -54,23 +54,44 @@
7587 return FAILURE;
7588 }
7589
7590+ /* check if module is compiled against Hardening-Patch */
7591+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7592+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7593+ "The Hardening-Patch version %d is installed.\n\n",
7594+ new_extension->name,
7595+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7596+ DL_UNLOAD(handle);
7597+ return FAILURE;
7598+ }
7599+
7600+
7601+ /* check if module is compiled against correct Hardening-Patch version */
7602+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7603+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7604+ "The Hardening-Patch version %d is installed.\n\n",
7605+ new_extension->name,
7606+ extension_version_info->zend_extension_api_no,
7607+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7608+ DL_UNLOAD(handle);
7609+ return FAILURE;
7610+ }
7611
7612 /* allow extension to proclaim compatibility with any Zend version */
7613- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7614- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7615+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7616+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7617 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7618 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7619 new_extension->name,
7620- extension_version_info->zend_extension_api_no,
7621+ extension_version_info->real_zend_extension_api_no,
7622 ZEND_EXTENSION_API_NO);
7623 DL_UNLOAD(handle);
7624 return FAILURE;
7625- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7626+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7627 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7628 "The Zend Engine API version %d which is installed, is newer.\n"
7629 "Contact %s at %s for a later version of %s.\n\n",
7630 new_extension->name,
7631- extension_version_info->zend_extension_api_no,
7632+ extension_version_info->real_zend_extension_api_no,
7633 ZEND_EXTENSION_API_NO,
7634 new_extension->author,
7635 new_extension->URL,
7636diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.10/Zend/zend_extensions.h
7637--- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100
7638+++ hardening-patch-4.4.2-0.4.10/Zend/zend_extensions.h 2006-05-11 10:36:02.000000000 +0200
7639@@ -23,6 +23,9 @@
7640
7641 #include "zend_compile.h"
7642
7643+/* Create own API version number for Hardening-Patch */
7644+
7645+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7646 #define ZEND_EXTENSION_API_NO 20050606
7647
7648 typedef struct _zend_extension_version_info {
7649@@ -30,6 +33,7 @@
7650 char *required_zend_version;
7651 unsigned char thread_safe;
7652 unsigned char debug;
7653+ int real_zend_extension_api_no;
7654 } zend_extension_version_info;
7655
7656
7657@@ -96,7 +100,7 @@
7658
7659
7660 #define ZEND_EXTENSION() \
7661- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7662+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
7663
7664 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7665 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7666diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.10/Zend/zend_globals.h
7667--- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100
7668+++ hardening-patch-4.4.2-0.4.10/Zend/zend_globals.h 2006-05-11 10:36:02.000000000 +0200
7669@@ -163,6 +163,16 @@
7670
7671 int error_reporting;
7672 int orig_error_reporting;
7673+#if HARDENING_PATCH
7674+ int hphp_log_syslog;
7675+ int hphp_log_syslog_facility;
7676+ int hphp_log_syslog_priority;
7677+ int hphp_log_sapi;
7678+ int hphp_log_script;
7679+ char *hphp_log_scriptname;
7680+ zend_bool hphp_log_use_x_forwarded_for;
7681+ long hphp_executor_max_depth;
7682+#endif
7683 int exit_status;
7684
7685 zend_op_array *active_op_array;
7686@@ -176,6 +186,7 @@
7687 int ticks_count;
7688
7689 zend_bool in_execution;
7690+ zend_uint in_code_type;
7691 zend_bool bailout_set;
7692 zend_bool full_tables_cleanup;
7693
7694diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.10/Zend/zend.h
7695--- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100
7696+++ hardening-patch-4.4.2-0.4.10/Zend/zend.h 2006-05-11 10:36:02.000000000 +0200
7697@@ -274,9 +274,10 @@
7698 struct _zval_struct {
7699 /* Variable information */
7700 zvalue_value value; /* value */
7701+ zend_uint refcount;
7702+ zend_ushort flags;
7703 zend_uchar type; /* active type */
7704 zend_uchar is_ref;
7705- zend_ushort refcount;
7706 };
7707
7708
7709@@ -337,6 +338,12 @@
7710 void (*ticks_function)(int ticks);
7711 void (*on_timeout)(int seconds TSRMLS_DC);
7712 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7713+#if HARDENING_PATCH
7714+ void (*security_log_function)(int loglevel, char *fmt, ...);
7715+#endif
7716+#if HARDENING_PATCH_INC_PROTECT
7717+ int (*is_valid_include)(zval *z);
7718+#endif
7719 } zend_utility_functions;
7720
7721
7722@@ -468,7 +475,16 @@
7723 extern ZEND_API void (*zend_ticks_function)(int ticks);
7724 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);
7725 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7726+#if HARDENING_PATCH
7727+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7728+#endif
7729+#if HARDENING_PATCH_INC_PROTECT
7730+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7731+#endif
7732
7733+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7734+ZEND_API unsigned int zend_canary(void);
7735+#endif
7736
7737 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7738
7739@@ -575,6 +591,11 @@
7740
7741 #define ZEND_MAX_RESERVED_RESOURCES 4
7742
7743+#if HARDENING_PATCH
7744+#include "hardened_globals.h"
7745+#include "php_syslog.h"
7746+#endif
7747+
7748 #endif /* ZEND_H */
7749
7750 /*
7751diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.10/Zend/zend_hash.c
7752--- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100
7753+++ hardening-patch-4.4.2-0.4.10/Zend/zend_hash.c 2006-05-11 10:36:02.000000000 +0200
7754@@ -26,6 +26,17 @@
7755 # include <stdlib.h>
7756 #endif
7757
7758+#if HARDENING_PATCH_HASH_PROTECT
7759+ unsigned int zend_hash_canary = 0x1234567;
7760+ zend_bool zend_hash_canary_inited = 0;
7761+#endif
7762+
7763+#define CHECK_HASH_CANARY(hash) \
7764+ if (zend_hash_canary != (hash)->canary) { \
7765+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7766+ exit(1); \
7767+ }
7768+
7769 #define HANDLE_NUMERIC(key, length, func) { \
7770 register char *tmp=key; \
7771 \
7772@@ -175,6 +186,9 @@
7773 {
7774 uint i = 3;
7775 Bucket **tmp;
7776+#if HARDENING_PATCH_HASH_PROTECT
7777+ TSRMLS_FETCH();
7778+#endif
7779
7780 SET_INCONSISTENT(HT_OK);
7781
7782@@ -184,6 +198,13 @@
7783
7784 ht->nTableSize = 1 << i;
7785 ht->nTableMask = ht->nTableSize - 1;
7786+#if HARDENING_PATCH_HASH_PROTECT
7787+ if (zend_hash_canary_inited==0) {
7788+ zend_hash_canary = zend_canary();
7789+ zend_hash_canary_inited = 1;
7790+ }
7791+ ht->canary = zend_hash_canary;
7792+#endif
7793 ht->pDestructor = pDestructor;
7794 ht->pListHead = NULL;
7795 ht->pListTail = NULL;
7796@@ -259,6 +280,9 @@
7797 }
7798 #endif
7799 if (ht->pDestructor) {
7800+#if HARDENING_PATCH_HASH_PROTECT
7801+ CHECK_HASH_CANARY(ht);
7802+#endif
7803 ht->pDestructor(p->pData);
7804 }
7805 UPDATE_DATA(ht, p, pData, nDataSize);
7806@@ -327,6 +351,9 @@
7807 }
7808 #endif
7809 if (ht->pDestructor) {
7810+#if HARDENING_PATCH_HASH_PROTECT
7811+ CHECK_HASH_CANARY(ht);
7812+#endif
7813 ht->pDestructor(p->pData);
7814 }
7815 UPDATE_DATA(ht, p, pData, nDataSize);
7816@@ -402,6 +429,9 @@
7817 }
7818 #endif
7819 if (ht->pDestructor) {
7820+#if HARDENING_PATCH_HASH_PROTECT
7821+ CHECK_HASH_CANARY(ht);
7822+#endif
7823 ht->pDestructor(p->pData);
7824 }
7825 UPDATE_DATA(ht, p, pData, nDataSize);
7826@@ -450,7 +480,7 @@
7827 IS_CONSISTENT(ht);
7828
7829 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7830- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7831+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7832 if (t) {
7833 HANDLE_BLOCK_INTERRUPTIONS();
7834 ht->arBuckets = t;
7835@@ -460,6 +490,7 @@
7836 HANDLE_UNBLOCK_INTERRUPTIONS();
7837 return SUCCESS;
7838 }
7839+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7840 return FAILURE;
7841 }
7842 return SUCCESS;
7843@@ -491,15 +522,17 @@
7844 IS_CONSISTENT(ht);
7845
7846 if (flag == HASH_DEL_KEY) {
7847- HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX));
7848+ HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, NULL, 0, idx, HASH_DEL_INDEX));
7849 h = zend_inline_hash_func(arKey, nKeyLength);
7850 }
7851 nIndex = h & ht->nTableMask;
7852
7853 p = ht->arBuckets[nIndex];
7854 while (p != NULL) {
7855- if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric index */
7856- ((p->nKeyLength == nKeyLength) && (!memcmp(p->arKey, arKey, nKeyLength))))) {
7857+ if ((p->h == h)
7858+ && (p->nKeyLength == nKeyLength)
7859+ && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */
7860+ || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */
7861 HANDLE_BLOCK_INTERRUPTIONS();
7862 if (p == ht->arBuckets[nIndex]) {
7863 ht->arBuckets[nIndex] = p->pNext;
7864@@ -524,6 +557,9 @@
7865 ht->pInternalPointer = p->pListNext;
7866 }
7867 if (ht->pDestructor) {
7868+#if HARDENING_PATCH_HASH_PROTECT
7869+ CHECK_HASH_CANARY(ht);
7870+#endif
7871 ht->pDestructor(p->pData);
7872 }
7873 if (!p->pDataPtr) {
7874@@ -553,6 +589,9 @@
7875 q = p;
7876 p = p->pListNext;
7877 if (ht->pDestructor) {
7878+#if HARDENING_PATCH_HASH_PROTECT
7879+ CHECK_HASH_CANARY(ht);
7880+#endif
7881 ht->pDestructor(q->pData);
7882 }
7883 if (!q->pDataPtr && q->pData) {
7884@@ -579,6 +618,9 @@
7885 q = p;
7886 p = p->pListNext;
7887 if (ht->pDestructor) {
7888+#if HARDENING_PATCH_HASH_PROTECT
7889+ CHECK_HASH_CANARY(ht);
7890+#endif
7891 ht->pDestructor(q->pData);
7892 }
7893 if (!q->pDataPtr && q->pData) {
7894@@ -608,6 +650,9 @@
7895 HANDLE_BLOCK_INTERRUPTIONS();
7896
7897 if (ht->pDestructor) {
7898+#if HARDENING_PATCH_HASH_PROTECT
7899+ CHECK_HASH_CANARY(ht);
7900+#endif
7901 ht->pDestructor(p->pData);
7902 }
7903 if (!p->pDataPtr) {
7904diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.10/Zend/zend_hash.h
7905--- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100
7906+++ hardening-patch-4.4.2-0.4.10/Zend/zend_hash.h 2006-05-11 10:36:02.000000000 +0200
7907@@ -54,6 +54,9 @@
7908 } Bucket;
7909
7910 typedef struct _hashtable {
7911+#if HARDENING_PATCH_HASH_PROTECT
7912+ unsigned int canary;
7913+#endif
7914 uint nTableSize;
7915 uint nTableMask;
7916 uint nNumOfElements;
7917diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.10/Zend/zend_ini.h
7918--- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7919+++ hardening-patch-4.4.2-0.4.10/Zend/zend_ini.h 2006-05-11 10:36:02.000000000 +0200
7920@@ -174,6 +174,7 @@
7921 /* Standard message handlers */
7922 BEGIN_EXTERN_C()
7923 ZEND_API ZEND_INI_MH(OnUpdateBool);
7924+#define OnUpdateLong OnUpdateInt
7925 ZEND_API ZEND_INI_MH(OnUpdateInt);
7926 ZEND_API ZEND_INI_MH(OnUpdateReal);
7927 ZEND_API ZEND_INI_MH(OnUpdateString);
7928diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.10/Zend/zend_language_scanner.l
7929--- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100
7930+++ hardening-patch-4.4.2-0.4.10/Zend/zend_language_scanner.l 2006-05-11 10:36:02.000000000 +0200
7931@@ -393,6 +393,13 @@
7932 compilation_successful=0;
7933 } else {
7934 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7935+#if HARDENING_PATCH
7936+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7937+ op_array->created_by_eval = 1;
7938+ } else {
7939+ op_array->created_by_eval = 0;
7940+ }
7941+#endif
7942 CG(in_compilation) = 1;
7943 CG(active_op_array) = op_array;
7944 compiler_result = zendparse(TSRMLS_C);
7945diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.10/Zend/zend_language_scanner.c
7946--- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100
7947+++ hardening-patch-4.4.2-0.4.10/Zend/zend_language_scanner.c 2006-05-11 10:36:02.000000000 +0200
7948@@ -3036,6 +3036,13 @@
7949 compilation_successful=0;
7950 } else {
7951 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7952+#if HARDENING_PATCH
7953+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7954+ op_array->created_by_eval = 1;
7955+ } else {
7956+ op_array->created_by_eval = 0;
7957+ }
7958+#endif
7959 CG(in_compilation) = 1;
7960 CG(active_op_array) = op_array;
7961 compiler_result = zendparse(TSRMLS_C);
7962diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.10/Zend/zend_llist.c
7963--- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100
7964+++ hardening-patch-4.4.2-0.4.10/Zend/zend_llist.c 2006-05-11 10:36:02.000000000 +0200
7965@@ -21,9 +21,49 @@
7966 #include "zend.h"
7967 #include "zend_llist.h"
7968 #include "zend_qsort.h"
7969+#include "zend_globals.h"
7970+
7971+#if HARDENING_PATCH_LL_PROTECT
7972+ unsigned int zend_llist_canary_1 = 0x1234567;
7973+ unsigned int zend_llist_canary_2 = 0x1553425;
7974+ zend_bool zend_llist_canary_inited = 0;
7975+#endif
7976+
7977+#define CHECK_LIST_CANARY(list) \
7978+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7979+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7980+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7981+ exit(1); \
7982+ }
7983+
7984+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7985+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7986+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7987+ exit(1); \
7988+ }
7989+
7990
7991 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7992 {
7993+#if HARDENING_PATCH_LL_PROTECT
7994+ TSRMLS_FETCH();
7995+
7996+ if (persistent) {
7997+ if (!zend_llist_canary_inited) {
7998+ /* do not change order to ensure thread safety */
7999+ zend_llist_canary_1 = zend_canary();
8000+ zend_llist_canary_2 = zend_canary();
8001+ zend_llist_canary_inited = 1;
8002+ }
8003+ } else
8004+ if (!HG(ll_canary_inited)) {
8005+ HG(canary_3) = zend_canary();
8006+ HG(canary_4) = zend_canary();
8007+ HG(ll_canary_inited) = 1;
8008+ }
8009+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
8010+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
8011+#endif
8012 l->head = NULL;
8013 l->tail = NULL;
8014 l->count = 0;
8015@@ -37,6 +77,11 @@
8016 {
8017 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8018
8019+#if HARDENING_PATCH_LL_PROTECT
8020+ TSRMLS_FETCH();
8021+ CHECK_LIST_CANARY(l)
8022+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8023+#endif
8024 tmp->prev = l->tail;
8025 tmp->next = NULL;
8026 if (l->tail) {
8027@@ -55,6 +100,11 @@
8028 {
8029 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8030
8031+#if HARDENING_PATCH_LL_PROTECT
8032+ TSRMLS_FETCH();
8033+ CHECK_LIST_CANARY(l)
8034+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8035+#endif
8036 tmp->next = l->head;
8037 tmp->prev = NULL;
8038 if (l->head) {
8039@@ -91,10 +141,20 @@
8040 zend_llist_element *current=l->head;
8041 zend_llist_element *next;
8042
8043+#if HARDENING_PATCH_LL_PROTECT
8044+ TSRMLS_FETCH();
8045+ CHECK_LIST_CANARY(l)
8046+#endif
8047 while (current) {
8048+#if HARDENING_PATCH_LL_PROTECT
8049+ CHECK_LISTELEMENT_CANARY(current, l)
8050+#endif
8051 next = current->next;
8052 if (compare(current->data, element)) {
8053 DEL_LLIST_ELEMENT(current, l);
8054+#if HARDENING_PATCH_LL_PROTECT
8055+ current->canary = 0;
8056+#endif
8057 break;
8058 }
8059 current = next;
8060@@ -106,7 +166,14 @@
8061 {
8062 zend_llist_element *current=l->head, *next;
8063
8064+#if HARDENING_PATCH_LL_PROTECT
8065+ TSRMLS_FETCH();
8066+ CHECK_LIST_CANARY(l)
8067+#endif
8068 while (current) {
8069+#if HARDENING_PATCH_LL_PROTECT
8070+ CHECK_LISTELEMENT_CANARY(current, l)
8071+#endif
8072 next = current->next;
8073 if (l->dtor) {
8074 l->dtor(current->data);
8075@@ -131,7 +198,14 @@
8076 zend_llist_element *old_tail;
8077 void *data;
8078
8079+#if HARDENING_PATCH_LL_PROTECT
8080+ TSRMLS_FETCH();
8081+ CHECK_LIST_CANARY(l)
8082+#endif
8083 if ((old_tail = l->tail)) {
8084+#if HARDENING_PATCH_LL_PROTECT
8085+ CHECK_LISTELEMENT_CANARY(old_tail, l)
8086+#endif
8087 if (l->tail->prev) {
8088 l->tail->prev->next = NULL;
8089 }
8090@@ -157,9 +231,16 @@
8091 {
8092 zend_llist_element *ptr;
8093
8094+#if HARDENING_PATCH_LL_PROTECT
8095+ TSRMLS_FETCH();
8096+ CHECK_LIST_CANARY(src)
8097+#endif
8098 zend_llist_init(dst, src->size, src->dtor, src->persistent);
8099 ptr = src->head;
8100 while (ptr) {
8101+#if HARDENING_PATCH_LL_PROTECT
8102+ CHECK_LISTELEMENT_CANARY(ptr, src)
8103+#endif
8104 zend_llist_add_element(dst, ptr->data);
8105 ptr = ptr->next;
8106 }
8107@@ -170,11 +251,21 @@
8108 {
8109 zend_llist_element *element, *next;
8110
8111+#if HARDENING_PATCH_LL_PROTECT
8112+ TSRMLS_FETCH();
8113+ CHECK_LIST_CANARY(l)
8114+#endif
8115 element=l->head;
8116 while (element) {
8117+#if HARDENING_PATCH_LL_PROTECT
8118+ CHECK_LISTELEMENT_CANARY(element, l)
8119+#endif
8120 next = element->next;
8121 if (func(element->data)) {
8122 DEL_LLIST_ELEMENT(element, l);
8123+#if HARDENING_PATCH_LL_PROTECT
8124+ element->canary = 0;
8125+#endif
8126 }
8127 element = next;
8128 }
8129@@ -185,7 +276,13 @@
8130 {
8131 zend_llist_element *element;
8132
8133+#if HARDENING_PATCH_LL_PROTECT
8134+ CHECK_LIST_CANARY(l)
8135+#endif
8136 for (element=l->head; element; element=element->next) {
8137+#if HARDENING_PATCH_LL_PROTECT
8138+ CHECK_LISTELEMENT_CANARY(element, l)
8139+#endif
8140 func(element->data TSRMLS_CC);
8141 }
8142 }
8143@@ -197,6 +294,9 @@
8144 zend_llist_element **elements;
8145 zend_llist_element *element, **ptr;
8146
8147+#if HARDENING_PATCH_LL_PROTECT
8148+ CHECK_LIST_CANARY(l)
8149+#endif
8150 if (l->count <= 0) {
8151 return;
8152 }
8153@@ -206,6 +306,9 @@
8154 ptr = &elements[0];
8155
8156 for (element=l->head; element; element=element->next) {
8157+#if HARDENING_PATCH_LL_PROTECT
8158+ CHECK_LISTELEMENT_CANARY(element, l)
8159+#endif
8160 *ptr++ = element;
8161 }
8162
8163@@ -228,7 +331,13 @@
8164 {
8165 zend_llist_element *element;
8166
8167+#if HARDENING_PATCH_LL_PROTECT
8168+ CHECK_LIST_CANARY(l)
8169+#endif
8170 for (element=l->head; element; element=element->next) {
8171+#if HARDENING_PATCH_LL_PROTECT
8172+ CHECK_LISTELEMENT_CANARY(element, l)
8173+#endif
8174 func(element->data, arg TSRMLS_CC);
8175 }
8176 }
8177@@ -239,8 +348,14 @@
8178 zend_llist_element *element;
8179 va_list args;
8180
8181+#if HARDENING_PATCH_LL_PROTECT
8182+ CHECK_LIST_CANARY(l)
8183+#endif
8184 va_start(args, num_args);
8185 for (element=l->head; element; element=element->next) {
8186+#if HARDENING_PATCH_LL_PROTECT
8187+ CHECK_LISTELEMENT_CANARY(element, l)
8188+#endif
8189 func(element->data, num_args, args TSRMLS_CC);
8190 }
8191 va_end(args);
8192@@ -249,6 +364,10 @@
8193
8194 ZEND_API int zend_llist_count(zend_llist *l)
8195 {
8196+#if HARDENING_PATCH_LL_PROTECT
8197+ TSRMLS_FETCH();
8198+ CHECK_LIST_CANARY(l)
8199+#endif
8200 return l->count;
8201 }
8202
8203@@ -256,8 +375,15 @@
8204 {
8205 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8206
8207+#if HARDENING_PATCH_LL_PROTECT
8208+ TSRMLS_FETCH();
8209+ CHECK_LIST_CANARY(l)
8210+#endif
8211 *current = l->head;
8212 if (*current) {
8213+#if HARDENING_PATCH_LL_PROTECT
8214+ CHECK_LISTELEMENT_CANARY(*current, l)
8215+#endif
8216 return (*current)->data;
8217 } else {
8218 return NULL;
8219@@ -269,8 +395,15 @@
8220 {
8221 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8222
8223+#if HARDENING_PATCH_LL_PROTECT
8224+ TSRMLS_FETCH();
8225+ CHECK_LIST_CANARY(l)
8226+#endif
8227 *current = l->tail;
8228 if (*current) {
8229+#if HARDENING_PATCH_LL_PROTECT
8230+ CHECK_LISTELEMENT_CANARY(*current, l)
8231+#endif
8232 return (*current)->data;
8233 } else {
8234 return NULL;
8235@@ -282,9 +415,19 @@
8236 {
8237 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8238
8239+#if HARDENING_PATCH_LL_PROTECT
8240+ TSRMLS_FETCH();
8241+ CHECK_LIST_CANARY(l)
8242+#endif
8243 if (*current) {
8244+#if HARDENING_PATCH_LL_PROTECT
8245+ CHECK_LISTELEMENT_CANARY(*current, l)
8246+#endif
8247 *current = (*current)->next;
8248 if (*current) {
8249+#if HARDENING_PATCH_LL_PROTECT
8250+ CHECK_LISTELEMENT_CANARY(*current, l)
8251+#endif
8252 return (*current)->data;
8253 }
8254 }
8255@@ -296,9 +439,19 @@
8256 {
8257 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8258
8259+#if HARDENING_PATCH_LL_PROTECT
8260+ TSRMLS_FETCH();
8261+ CHECK_LIST_CANARY(l)
8262+#endif
8263 if (*current) {
8264+#if HARDENING_PATCH_LL_PROTECT
8265+ CHECK_LISTELEMENT_CANARY(*current, l)
8266+#endif
8267 *current = (*current)->prev;
8268 if (*current) {
8269+#if HARDENING_PATCH_LL_PROTECT
8270+ CHECK_LISTELEMENT_CANARY(*current, l)
8271+#endif
8272 return (*current)->data;
8273 }
8274 }
8275diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.10/Zend/zend_llist.h
8276--- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100
8277+++ hardening-patch-4.4.2-0.4.10/Zend/zend_llist.h 2006-05-11 10:36:02.000000000 +0200
8278@@ -24,6 +24,9 @@
8279 #include <stdlib.h>
8280
8281 typedef struct _zend_llist_element {
8282+#if HARDENING_PATCH_LL_PROTECT
8283+ unsigned int canary, padding;
8284+#endif
8285 struct _zend_llist_element *next;
8286 struct _zend_llist_element *prev;
8287 char data[1]; /* Needs to always be last in the struct */
8288@@ -36,6 +39,9 @@
8289 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
8290
8291 typedef struct _zend_llist {
8292+#if HARDENING_PATCH_LL_PROTECT
8293+ unsigned int canary_h; /* head */
8294+#endif
8295 zend_llist_element *head;
8296 zend_llist_element *tail;
8297 size_t size;
8298@@ -43,6 +49,9 @@
8299 llist_dtor_func_t dtor;
8300 unsigned char persistent;
8301 zend_llist_element *traverse_ptr;
8302+#if HARDENING_PATCH_LL_PROTECT
8303+ unsigned int canary_t; /* tail */
8304+#endif
8305 } zend_llist;
8306
8307 typedef zend_llist_element* zend_llist_position;
8308diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.10/Zend/zend_modules.h
8309--- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100
8310+++ hardening-patch-4.4.2-0.4.10/Zend/zend_modules.h 2006-05-11 10:36:02.000000000 +0200
8311@@ -34,6 +34,7 @@
8312 ZEND_API extern unsigned char second_arg_force_ref[];
8313 ZEND_API extern unsigned char third_arg_force_ref[];
8314
8315+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8316 #define ZEND_MODULE_API_NO 20020429
8317 #ifdef ZTS
8318 #define USING_ZTS 1
8319@@ -41,9 +42,9 @@
8320 #define USING_ZTS 0
8321 #endif
8322
8323-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8324+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8325
8326-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8327+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8328
8329 #define STANDARD_MODULE_PROPERTIES \
8330 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8331@@ -75,6 +76,7 @@
8332 unsigned char type;
8333 void *handle;
8334 int module_number;
8335+ unsigned int real_zend_api;
8336 };
8337
8338
8339diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.10/Zend/zend_opcode.c
8340--- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100
8341+++ hardening-patch-4.4.2-0.4.10/Zend/zend_opcode.c 2006-05-11 10:36:02.000000000 +0200
8342@@ -88,6 +88,9 @@
8343 op_array->done_pass_two = 0;
8344
8345 op_array->start_op = NULL;
8346+#if HARDENING_PATCH
8347+ op_array->created_by_eval = 0;
8348+#endif
8349
8350 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8351 }
8352diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.10/Zend/zend_operators.c
8353--- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100
8354+++ hardening-patch-4.4.2-0.4.10/Zend/zend_operators.c 2006-05-11 10:36:02.000000000 +0200
8355@@ -1604,6 +1604,20 @@
8356 return (op->value.lval ? 1 : 0);
8357 }
8358
8359+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8360+{
8361+ register unsigned char *str = (unsigned char*)source;
8362+ register unsigned char *result = (unsigned char*)dest;
8363+ register unsigned char *end = str + length;
8364+
8365+ while (str < end) {
8366+ *result++ = tolower((int)*str++);
8367+ }
8368+ *result = *end;
8369+
8370+ return dest;
8371+}
8372+
8373 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8374 {
8375 register char *p=str, *end=p+length;
8376diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.10/Zend/zend_operators.h
8377--- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100
8378+++ hardening-patch-4.4.2-0.4.10/Zend/zend_operators.h 2006-05-11 10:36:02.000000000 +0200
8379@@ -174,6 +174,14 @@
8380 #endif
8381
8382 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8383+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8384+
8385+static inline char *
8386+zend_str_tolower_dup(const char *source, unsigned int length)
8387+{
8388+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8389+}
8390+
8391 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8392 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8393 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
diff --git a/0.4.13/hardening-patch-5.1.4-0.4.13.patch b/0.4.13/hardening-patch-5.1.4-0.4.13.patch
new file mode 100644
index 0000000..286dedf
--- /dev/null
+++ b/0.4.13/hardening-patch-5.1.4-0.4.13.patch
@@ -0,0 +1,8620 @@
1diff -Nura php-5.1.4/Changelog.hphp hardening-patch-5.1.4-0.4.13/Changelog.hphp
2--- php-5.1.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100
3+++ hardening-patch-5.1.4-0.4.13/Changelog.hphp 2006-08-07 11:06:06.000000000 +0200
4@@ -0,0 +1,39 @@
5+Changelog of the Hardening-Patch
6+--------------------------------
7+
8+0.4.13 - 07. August 2006
9+
10+ PHP4+5:
11+ [+] Added a fix for a compile problem on solaris due to missing strcasestr()
12+
13+0.4.12 - 19. July 2006
14+
15+ PHP4:
16+ [+] Added fixes from sf4 security patch / see changelog.secfix for details
17+
18+ PHP5:
19+ [+] Added fixes from sf5 security patch / see changelog.secfix for details
20+
21+ PHP4+5:
22+ [+] Added anti mail spam feature
23+ [+] Speedup of zend_hash canary (clear/destroy)
24+ [+] Added a fix for a DOS in the handling of URL blacklists
25+
26+0.4.11 - 13. May 2006
27+
28+ PHP5:
29+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache
30+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4
31+
32+ PHP4+5:
33+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories
34+
35+
36+0.4.10 - 11. May 2006
37+
38+ PHP4:
39+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
40+
41+ PHP4+5:
42+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
43+
44diff -Nura php-5.1.4/Changelog.secfix hardening-patch-5.1.4-0.4.13/Changelog.secfix
45--- php-5.1.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100
46+++ hardening-patch-5.1.4-0.4.13/Changelog.secfix 2006-08-07 11:04:06.000000000 +0200
47@@ -0,0 +1,32 @@
48+Changelog of PHP 5.1.4 Security Fixes
49+
50+Release 5 - 13. July 2006
51+
52+ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode
53+
54+Release 4 - 13. July 2006
55+
56+ [+] Added a recursive array printing fix to the phpinfo() XSS fix
57+ [+] Added a fix for stat() on non existing files in safe_mode
58+
59+Release 3 - 07. July 2006
60+
61+ [+] Added a fix for an integer overflow in str_repeat()
62+ [+] Added a *working* wordwrap() fix
63+ [+] Added code to make memory_limit work on 64bit systems
64+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability
65+ [+] Added a fix for overlong tempfilename
66+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl
67+ [+] Added a high characters fix to ext/wddx
68+
69+Release 2 - 16. May 2006
70+
71+ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP
72+ tarball got updated
73+
74+Release 1 - 13. May 2006
75+
76+ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball
77+ and is downloaded when make install is called (usually as root -> security risk)
78+ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache
79+
80diff -Nura php-5.1.4/configure hardening-patch-5.1.4-0.4.13/configure
81--- php-5.1.4/configure 2006-05-12 16:41:10.000000000 +0200
82+++ hardening-patch-5.1.4-0.4.13/configure 2006-08-07 11:04:06.000000000 +0200
83@@ -942,6 +942,16 @@
84 ac_help="$ac_help
85 --with-libdir=NAME Look for libraries in .../NAME rather than .../lib"
86 ac_help="$ac_help
87+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
88+ac_help="$ac_help
89+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
90+ac_help="$ac_help
91+ --disable-hardening-patch-inc-protect Disable include/require protection."
92+ac_help="$ac_help
93+ --disable-hardening-patch-fmt-protect Disable format string protection."
94+ac_help="$ac_help
95+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
96+ac_help="$ac_help
97
98 SAPI modules:
99 "
100@@ -1410,6 +1420,8 @@
101 ac_help="$ac_help
102 --enable-wddx Enable WDDX support"
103 ac_help="$ac_help
104+ --disable-varfilter Disable Hardening-Patch's variable filter"
105+ac_help="$ac_help
106 --disable-xml Disable XML support"
107 ac_help="$ac_help
108 --with-libxml-dir=DIR XML: libxml2 install prefix"
109@@ -3618,6 +3630,157 @@
110
111
112
113+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
114+if test "${enable_hardening_patch_mm_protect+set}" = set; then
115+ enableval="$enable_hardening_patch_mm_protect"
116+
117+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
118+
119+else
120+
121+ DO_HARDENING_PATCH_MM_PROTECT=yes
122+
123+fi
124+
125+
126+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
127+if test "${enable_hardening_patch_ll_protect+set}" = set; then
128+ enableval="$enable_hardening_patch_ll_protect"
129+
130+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
131+
132+else
133+
134+ DO_HARDENING_PATCH_LL_PROTECT=yes
135+
136+fi
137+
138+
139+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
140+if test "${enable_hardening_patch_inc_protect+set}" = set; then
141+ enableval="$enable_hardening_patch_inc_protect"
142+
143+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
144+
145+else
146+
147+ DO_HARDENING_PATCH_INC_PROTECT=yes
148+
149+fi
150+
151+
152+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
153+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
154+ enableval="$enable_hardening_patch_fmt_protect"
155+
156+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
157+
158+else
159+
160+ DO_HARDENING_PATCH_FMT_PROTECT=yes
161+
162+fi
163+
164+
165+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
166+if test "${enable_hardening_patch_hash_protect+set}" = set; then
167+ enableval="$enable_hardening_patch_hash_protect"
168+
169+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
170+
171+else
172+
173+ DO_HARDENING_PATCH_HASH_PROTECT=yes
174+
175+fi
176+
177+
178+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
179+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
180+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
181+
182+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
183+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
184+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
185+
186+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
187+echo "configure:2733: checking whether to protect include/require statements" >&5
188+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
189+
190+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
191+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
192+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
193+
194+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
195+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
196+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
197+
198+
199+cat >> confdefs.h <<\EOF
200+#define HARDENING_PATCH 1
201+EOF
202+
203+
204+
205+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
206+ cat >> confdefs.h <<\EOF
207+#define HARDENING_PATCH_MM_PROTECT 1
208+EOF
209+
210+else
211+ cat >> confdefs.h <<\EOF
212+#define HARDENING_PATCH_MM_PROTECT 0
213+EOF
214+
215+fi
216+
217+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
218+ cat >> confdefs.h <<\EOF
219+#define HARDENING_PATCH_LL_PROTECT 1
220+EOF
221+
222+else
223+ cat >> confdefs.h <<\EOF
224+#define HARDENING_PATCH_LL_PROTECT 0
225+EOF
226+
227+fi
228+
229+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
230+ cat >> confdefs.h <<\EOF
231+#define HARDENING_PATCH_INC_PROTECT 1
232+EOF
233+
234+else
235+ cat >> confdefs.h <<\EOF
236+#define HARDENING_PATCH_INC_PROTECT 0
237+EOF
238+
239+fi
240+
241+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
242+ cat >> confdefs.h <<\EOF
243+#define HARDENING_PATCH_FMT_PROTECT 1
244+EOF
245+
246+else
247+ cat >> confdefs.h <<\EOF
248+#define HARDENING_PATCH_FMT_PROTECT 0
249+EOF
250+
251+fi
252+
253+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
254+ cat >> confdefs.h <<\EOF
255+#define HARDENING_PATCH_HASH_PROTECT 1
256+EOF
257+
258+else
259+ cat >> confdefs.h <<\EOF
260+#define HARDENING_PATCH_HASH_PROTECT 0
261+EOF
262+
263+fi
264
265
266
267@@ -18607,6 +18770,62 @@
268 fi
269
270
271+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
272+echo "configure:14928: checking whether realpath is broken" >&5
273+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
274+ echo $ac_n "(cached) $ac_c" 1>&6
275+else
276+
277+ if test "$cross_compiling" = yes; then
278+
279+ ac_cv_broken_realpath=no
280+
281+else
282+ cat > conftest.$ac_ext <<EOF
283+#line 14939 "configure"
284+#include "confdefs.h"
285+
286+main() {
287+ char buf[4096+1];
288+ buf[0] = 0;
289+ realpath("/etc/hosts/../passwd", buf);
290+ exit(strcmp(buf, "/etc/passwd")==0);
291+}
292+
293+EOF
294+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
295+then
296+
297+ ac_cv_broken_realpath=no
298+
299+else
300+ echo "configure: failed program was:" >&5
301+ cat conftest.$ac_ext >&5
302+ rm -fr conftest*
303+
304+ ac_cv_broken_realpath=yes
305+
306+fi
307+rm -fr conftest*
308+fi
309+
310+
311+fi
312+
313+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
314+ if test "$ac_cv_broken_realpath" = "yes"; then
315+ cat >> confdefs.h <<\EOF
316+#define PHP_BROKEN_REALPATH 1
317+EOF
318+
319+ else
320+ cat >> confdefs.h <<\EOF
321+#define PHP_BROKEN_REALPATH 0
322+EOF
323+
324+ fi
325+
326+
327 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
328 echo "configure:18612: checking for declared timezone" >&5
329 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
330@@ -89422,7 +89641,7 @@
331 if test "$ac_cv_crypt_blowfish" = "yes"; then
332 ac_result=1
333 else
334- ac_result=0
335+ ac_result=1
336 fi
337 cat >> confdefs.h <<EOF
338 #define PHP_BLOWFISH_CRYPT $ac_result
339@@ -92022,7 +92241,7 @@
340 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
341 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
342 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
343- filters.c proc_open.c streamsfuncs.c http.c; do
344+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
345
346 IFS=.
347 set $ac_src
348@@ -92081,7 +92300,7 @@
349 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
350 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
351 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
352- filters.c proc_open.c streamsfuncs.c http.c; do
353+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
354
355 IFS=.
356 set $ac_src
357@@ -92211,7 +92430,7 @@
358 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
359 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
360 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
361- filters.c proc_open.c streamsfuncs.c http.c; do
362+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
363
364 IFS=.
365 set $ac_src
366@@ -92266,7 +92485,7 @@
367 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
368 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
369 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
370- filters.c proc_open.c streamsfuncs.c http.c; do
371+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
372
373 IFS=.
374 set $ac_src
375@@ -96101,6 +96320,265 @@
376 fi
377
378
379+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
380+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
381+# Check whether --enable-varfilter or --disable-varfilter was given.
382+if test "${enable_varfilter+set}" = set; then
383+ enableval="$enable_varfilter"
384+ PHP_VARFILTER=$enableval
385+else
386+
387+ PHP_VARFILTER=yes
388+
389+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
390+ PHP_VARFILTER=$PHP_ENABLE_ALL
391+ fi
392+
393+fi
394+
395+
396+
397+ext_output="yes, shared"
398+ext_shared=yes
399+case $PHP_VARFILTER in
400+shared,*)
401+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
402+ ;;
403+shared)
404+ PHP_VARFILTER=yes
405+ ;;
406+no)
407+ ext_output=no
408+ ext_shared=no
409+ ;;
410+*)
411+ ext_output=yes
412+ ext_shared=no
413+ ;;
414+esac
415+
416+
417+
418+echo "$ac_t""$ext_output" 1>&6
419+
420+
421+
422+
423+if test "$PHP_VARFILTER" != "no"; then
424+ cat >> confdefs.h <<\EOF
425+#define HAVE_VARFILTER 1
426+EOF
427+
428+
429+ ext_builddir=ext/varfilter
430+ ext_srcdir=$abs_srcdir/ext/varfilter
431+
432+ ac_extra=
433+
434+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
435+
436+
437+
438+ case ext/varfilter in
439+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
440+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
441+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
442+ esac
443+
444+
445+
446+ b_c_pre=$php_c_pre
447+ b_cxx_pre=$php_cxx_pre
448+ b_c_meta=$php_c_meta
449+ b_cxx_meta=$php_cxx_meta
450+ b_c_post=$php_c_post
451+ b_cxx_post=$php_cxx_post
452+ b_lo=$php_lo
453+
454+
455+ old_IFS=$IFS
456+ for ac_src in varfilter.c; do
457+
458+ IFS=.
459+ set $ac_src
460+ ac_obj=$1
461+ IFS=$old_IFS
462+
463+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
464+
465+ case $ac_src in
466+ *.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" ;;
467+ *.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" ;;
468+ esac
469+
470+ cat >>Makefile.objects<<EOF
471+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
472+ $ac_comp
473+EOF
474+ done
475+
476+
477+ EXT_STATIC="$EXT_STATIC varfilter"
478+ if test "$ext_shared" != "nocli"; then
479+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
480+ fi
481+ else
482+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
483+
484+ case ext/varfilter in
485+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
486+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
487+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
488+ esac
489+
490+
491+
492+ b_c_pre=$shared_c_pre
493+ b_cxx_pre=$shared_cxx_pre
494+ b_c_meta=$shared_c_meta
495+ b_cxx_meta=$shared_cxx_meta
496+ b_c_post=$shared_c_post
497+ b_cxx_post=$shared_cxx_post
498+ b_lo=$shared_lo
499+
500+
501+ old_IFS=$IFS
502+ for ac_src in varfilter.c; do
503+
504+ IFS=.
505+ set $ac_src
506+ ac_obj=$1
507+ IFS=$old_IFS
508+
509+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
510+
511+ case $ac_src in
512+ *.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" ;;
513+ *.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" ;;
514+ esac
515+
516+ cat >>Makefile.objects<<EOF
517+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
518+ $ac_comp
519+EOF
520+ done
521+
522+
523+ install_modules="install-modules"
524+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
525+
526+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
527+
528+ cat >>Makefile.objects<<EOF
529+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
530+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
531+
532+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
533+ \$(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)
534+
535+EOF
536+
537+ cat >> confdefs.h <<EOF
538+#define COMPILE_DL_VARFILTER 1
539+EOF
540+
541+ fi
542+ fi
543+
544+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
545+ if test "$PHP_SAPI" = "cgi"; then
546+
547+
548+ case ext/varfilter in
549+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
550+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
551+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
552+ esac
553+
554+
555+
556+ b_c_pre=$php_c_pre
557+ b_cxx_pre=$php_cxx_pre
558+ b_c_meta=$php_c_meta
559+ b_cxx_meta=$php_cxx_meta
560+ b_c_post=$php_c_post
561+ b_cxx_post=$php_cxx_post
562+ b_lo=$php_lo
563+
564+
565+ old_IFS=$IFS
566+ for ac_src in varfilter.c; do
567+
568+ IFS=.
569+ set $ac_src
570+ ac_obj=$1
571+ IFS=$old_IFS
572+
573+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
574+
575+ case $ac_src in
576+ *.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" ;;
577+ *.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" ;;
578+ esac
579+
580+ cat >>Makefile.objects<<EOF
581+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
582+ $ac_comp
583+EOF
584+ done
585+
586+
587+ EXT_STATIC="$EXT_STATIC varfilter"
588+ else
589+
590+
591+ case ext/varfilter in
592+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
593+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
594+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
595+ esac
596+
597+
598+
599+ b_c_pre=$php_c_pre
600+ b_cxx_pre=$php_cxx_pre
601+ b_c_meta=$php_c_meta
602+ b_cxx_meta=$php_cxx_meta
603+ b_c_post=$php_c_post
604+ b_cxx_post=$php_cxx_post
605+ b_lo=$php_lo
606+
607+
608+ old_IFS=$IFS
609+ for ac_src in varfilter.c; do
610+
611+ IFS=.
612+ set $ac_src
613+ ac_obj=$1
614+ IFS=$old_IFS
615+
616+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
617+
618+ case $ac_src in
619+ *.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" ;;
620+ *.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" ;;
621+ esac
622+
623+ cat >>Makefile.objects<<EOF
624+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
625+ $ac_comp
626+EOF
627+ done
628+
629+
630+ fi
631+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
632+ fi
633+
634+ BUILD_DIR="$BUILD_DIR $ext_builddir"
635+
636+
637+fi
638
639
640 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
641@@ -112351,7 +112829,7 @@
642 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
643 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
644 network.c php_open_temporary_file.c php_logos.c \
645- output.c ; do
646+ output.c hardening_patch.c ; do
647
648 IFS=.
649 set $ac_src
650@@ -112596,7 +113074,7 @@
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
654- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
655+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
656
657 IFS=.
658 set $ac_src
659diff -Nura php-5.1.4/configure.in hardening-patch-5.1.4-0.4.13/configure.in
660--- php-5.1.4/configure.in 2006-05-04 01:30:02.000000000 +0200
661+++ hardening-patch-5.1.4-0.4.13/configure.in 2006-08-07 11:04:06.000000000 +0200
662@@ -209,7 +209,7 @@
663
664 sinclude(Zend/Zend.m4)
665 sinclude(TSRM/tsrm.m4)
666-
667+sinclude(main/hardening_patch.m4)
668
669 divert(2)
670
671@@ -1275,7 +1275,7 @@
672 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
673 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
674 network.c php_open_temporary_file.c php_logos.c \
675- output.c )
676+ output.c hardening_patch.c )
677
678 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
679 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
680@@ -1302,7 +1302,7 @@
681 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
682 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
683 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
684- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
685+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
686
687 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
688 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
689diff -Nura php-5.1.4/ext/curl/interface.c hardening-patch-5.1.4-0.4.13/ext/curl/interface.c
690--- php-5.1.4/ext/curl/interface.c 2006-04-13 13:26:10.000000000 +0200
691+++ hardening-patch-5.1.4-0.4.13/ext/curl/interface.c 2006-08-07 11:04:06.000000000 +0200
692@@ -167,6 +167,11 @@
693 RETURN_FALSE; \
694 } \
695 \
696+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \
697+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \
698+ RETURN_FALSE; \
699+ } \
700+ \
701 if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
702 (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
703 ) { \
704@@ -1065,7 +1070,6 @@
705 case CURLOPT_FTPLISTONLY:
706 case CURLOPT_FTPAPPEND:
707 case CURLOPT_NETRC:
708- case CURLOPT_FOLLOWLOCATION:
709 case CURLOPT_PUT:
710 #if CURLOPT_MUTE != 0
711 case CURLOPT_MUTE:
712@@ -1116,6 +1120,16 @@
713 convert_to_long_ex(zvalue);
714 error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
715 break;
716+ case CURLOPT_FOLLOWLOCATION:
717+ convert_to_long_ex(zvalue);
718+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
719+ if (Z_LVAL_PP(zvalue) != 0) {
720+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set");
721+ RETURN_FALSE;
722+ }
723+ }
724+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
725+ break;
726 case CURLOPT_URL:
727 case CURLOPT_PROXY:
728 case CURLOPT_USERPWD:
729diff -Nura php-5.1.4/ext/curl/streams.c hardening-patch-5.1.4-0.4.13/ext/curl/streams.c
730--- php-5.1.4/ext/curl/streams.c 2006-01-01 13:50:01.000000000 +0100
731+++ hardening-patch-5.1.4-0.4.13/ext/curl/streams.c 2006-08-07 11:04:06.000000000 +0200
732@@ -289,7 +289,11 @@
733 curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream);
734
735 /* currently buggy (bug is in curl) */
736- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
737+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
738+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0);
739+ } else {
740+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
741+ }
742
743 curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr);
744 curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0);
745diff -Nura php-5.1.4/ext/fbsql/php_fbsql.c hardening-patch-5.1.4-0.4.13/ext/fbsql/php_fbsql.c
746--- php-5.1.4/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100
747+++ hardening-patch-5.1.4-0.4.13/ext/fbsql/php_fbsql.c 2006-08-07 11:04:06.000000000 +0200
748@@ -1925,8 +1925,24 @@
749 }
750 else if (fbcmdErrorsFound(md))
751 {
752+#if HARDENING_PATCH
753+ char* query_copy;
754+ int i;
755+#endif
756 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
757 char* emg = fbcemdAllErrorMessages(emd);
758+#if HARDENING_PATCH
759+ query_copy=estrdup(query_copy);
760+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
761+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
762+ efree(query_copy);
763+ if (HG(hphp_sql_bailout_on_error)) {
764+ free(emg);
765+ fbcemdRelease(emd);
766+ result = 0;
767+ zend_bailout();
768+ }
769+#endif
770 if (FB_SQL_G(generateWarnings))
771 {
772 if (emg)
773diff -Nura php-5.1.4/ext/mysql/php_mysql.c hardening-patch-5.1.4-0.4.13/ext/mysql/php_mysql.c
774--- php-5.1.4/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100
775+++ hardening-patch-5.1.4-0.4.13/ext/mysql/php_mysql.c 2006-08-07 11:04:06.000000000 +0200
776@@ -1231,6 +1231,8 @@
777 {
778 php_mysql_conn *mysql;
779 MYSQL_RES *mysql_result;
780+ char *copy_query;
781+ int i;
782
783 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
784
785@@ -1281,6 +1283,13 @@
786 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
787 }
788 }
789+ copy_query = estrdup(Z_STRVAL_PP(query));
790+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
791+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
792+ efree(copy_query);
793+ if (HG(hphp_sql_bailout_on_error)) {
794+ zend_bailout();
795+ }
796 RETURN_FALSE;
797 }
798 #else
799@@ -1291,6 +1300,13 @@
800 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
801 }
802 }
803+ copy_query = estrdup(Z_STRVAL_PP(query));
804+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
805+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
806+ efree(copy_query);
807+ if (HG(hphp_sql_bailout_on_error)) {
808+ zend_bailout();
809+ }
810 RETURN_FALSE;
811 }
812 #endif
813diff -Nura php-5.1.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.4-0.4.13/ext/mysqli/mysqli_nonapi.c
814--- php-5.1.4/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100
815+++ hardening-patch-5.1.4-0.4.13/ext/mysqli/mysqli_nonapi.c 2006-08-07 11:04:06.000000000 +0200
816@@ -184,6 +184,17 @@
817 if (mysql_real_query(mysql->mysql, query, query_len)) {
818 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
819 unsigned int s_errno;
820+#if HARDENING_PATCH
821+ char *query_copy = estrdup(query);
822+ int i;
823+
824+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
825+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
826+ efree(query_copy);
827+ if (HG(hphp_sql_bailout_on_error)) {
828+ zend_bailout();
829+ }
830+#endif
831 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
832
833 /* we have to save error information, cause
834@@ -234,6 +245,17 @@
835 MYSQLI_DISABLE_MQ;
836
837 if (mysql_real_query(mysql->mysql, query, query_len)) {
838+#if HARDENING_PATCH
839+ char *query_copy = estrdup(query);
840+ int i;
841+
842+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
843+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
844+ efree(query_copy);
845+ if (HG(hphp_sql_bailout_on_error)) {
846+ zend_bailout();
847+ }
848+#endif
849 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
850 RETURN_FALSE;
851 }
852diff -Nura php-5.1.4/ext/pgsql/pgsql.c hardening-patch-5.1.4-0.4.13/ext/pgsql/pgsql.c
853--- php-5.1.4/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200
854+++ hardening-patch-5.1.4-0.4.13/ext/pgsql/pgsql.c 2006-08-07 11:04:06.000000000 +0200
855@@ -1152,10 +1152,28 @@
856 case PGRES_EMPTY_QUERY:
857 case PGRES_BAD_RESPONSE:
858 case PGRES_NONFATAL_ERROR:
859- case PGRES_FATAL_ERROR:
860- PHP_PQ_ERROR("Query failed: %s", pgsql);
861- PQclear(pgsql_result);
862- RETURN_FALSE;
863+ case PGRES_FATAL_ERROR:
864+ {
865+#if HARDENING_PATCH
866+ int i;
867+ char *query_copy;
868+#endif
869+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
870+ PQclear(pgsql_result);
871+#if HARDENING_PATCH
872+ query_copy = estrdup(Z_STRVAL_PP(query));
873+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
874+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
875+ efree(query_copy);
876+ if (HG(hphp_sql_bailout_on_error)) {
877+ efree(msgbuf);
878+ zend_bailout();
879+ }
880+#endif
881+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
882+ efree(msgbuf);
883+ RETURN_FALSE;
884+ }
885 break;
886 case PGRES_COMMAND_OK: /* successful command that did not return rows */
887 default:
888diff -Nura php-5.1.4/ext/session/mod_files.c hardening-patch-5.1.4-0.4.13/ext/session/mod_files.c
889--- php-5.1.4/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200
890+++ hardening-patch-5.1.4-0.4.13/ext/session/mod_files.c 2006-08-07 11:04:06.000000000 +0200
891@@ -422,6 +422,35 @@
892 return SUCCESS;
893 }
894
895+PS_VALIDATE_SID_FUNC(files)
896+{
897+ char buf[MAXPATHLEN];
898+ int fd;
899+ PS_FILES_DATA;
900+
901+ if (!ps_files_valid_key(key)) {
902+ return FAILURE;
903+ }
904+
905+ if (!PS(use_strict_mode)) {
906+ return SUCCESS;
907+ }
908+
909+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
910+ return FAILURE;
911+ }
912+
913+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY,
914+ data->filemode);
915+
916+ if (fd != -1) {
917+ close(fd);
918+ return SUCCESS;
919+ }
920+
921+ return FAILURE;
922+}
923+
924 /*
925 * Local variables:
926 * tab-width: 4
927diff -Nura php-5.1.4/ext/session/mod_mm.c hardening-patch-5.1.4-0.4.13/ext/session/mod_mm.c
928--- php-5.1.4/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100
929+++ hardening-patch-5.1.4-0.4.13/ext/session/mod_mm.c 2006-08-07 11:04:06.000000000 +0200
930@@ -425,6 +425,42 @@
931 return SUCCESS;
932 }
933
934+PS_VALIDATE_SID_FUNC(mm)
935+{
936+ PS_MM_DATA;
937+ ps_sd *sd;
938+ const char *p;
939+ char c;
940+ int ret = SUCCESS;
941+
942+ for (p = key; (c = *p); p++) {
943+ /* valid characters are a..z,A..Z,0..9 */
944+ if (!((c >= 'a' && c <= 'z')
945+ || (c >= 'A' && c <= 'Z')
946+ || (c >= '0' && c <= '9')
947+ || c == ','
948+ || c == '-')) {
949+ return FAILURE;
950+ }
951+ }
952+
953+ if (!PS(use_strict_mode)) {
954+ return SUCCESS;
955+ }
956+
957+ mm_lock(data->mm, MM_LOCK_RD);
958+
959+ sd = ps_sd_lookup(data, key, 0);
960+ if (sd) {
961+ mm_unlock(data->mm);
962+ return SUCCESS;
963+ }
964+
965+ mm_unlock(data->mm);
966+
967+ return FAILURE;
968+}
969+
970 #endif
971
972 /*
973diff -Nura php-5.1.4/ext/session/mod_user.c hardening-patch-5.1.4-0.4.13/ext/session/mod_user.c
974--- php-5.1.4/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100
975+++ hardening-patch-5.1.4-0.4.13/ext/session/mod_user.c 2006-08-07 11:04:06.000000000 +0200
976@@ -23,7 +23,7 @@
977 #include "mod_user.h"
978
979 ps_module ps_mod_user = {
980- PS_MOD(user)
981+ PS_MOD_SID(user)
982 };
983
984 #define SESS_ZVAL_LONG(val, a) \
985@@ -174,6 +174,83 @@
986 FINISH;
987 }
988
989+PS_CREATE_SID_FUNC(user)
990+{
991+ int i;
992+ char *val = NULL;
993+ zval *retval;
994+ ps_user *mdata = PS_GET_MOD_DATA();
995+
996+ if (!mdata)
997+ return estrndup("", 0);
998+
999+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
1000+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
1001+ }
1002+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
1003+
1004+ if (retval) {
1005+ if (Z_TYPE_P(retval) == IS_STRING) {
1006+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
1007+ } else {
1008+ val = estrndup("", 0);
1009+ }
1010+ zval_ptr_dtor(&retval);
1011+ } else {
1012+ val = estrndup("", 0);
1013+ }
1014+
1015+ return val;
1016+}
1017+
1018+static int ps_user_valid_key(const char *key TSRMLS_DC)
1019+{
1020+ size_t len;
1021+ const char *p;
1022+ char c;
1023+ int ret = SUCCESS;
1024+
1025+ for (p = key; (c = *p); p++) {
1026+ /* valid characters are a..z,A..Z,0..9 */
1027+ if (!((c >= 'a' && c <= 'z')
1028+ || (c >= 'A' && c <= 'Z')
1029+ || (c >= '0' && c <= '9')
1030+ || c == ','
1031+ || c == '-')) {
1032+ ret = FAILURE;
1033+ break;
1034+ }
1035+ }
1036+
1037+ len = p - key;
1038+
1039+ if (len == 0)
1040+ ret = FAILURE;
1041+
1042+ return ret;
1043+}
1044+
1045+PS_VALIDATE_SID_FUNC(user)
1046+{
1047+ zval *args[1];
1048+ STDVARS;
1049+
1050+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
1051+ return ps_user_valid_key(key TSRMLS_CC);
1052+ }
1053+ SESS_ZVAL_STRING(key, args[0]);
1054+
1055+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1056+
1057+ if (retval) {
1058+ convert_to_long(retval);
1059+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1060+ zval_ptr_dtor(&retval);
1061+ }
1062+
1063+ return ret;
1064+}
1065+
1066 /*
1067 * Local variables:
1068 * tab-width: 4
1069diff -Nura php-5.1.4/ext/session/mod_user.h hardening-patch-5.1.4-0.4.13/ext/session/mod_user.h
1070--- php-5.1.4/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100
1071+++ hardening-patch-5.1.4-0.4.13/ext/session/mod_user.h 2006-08-07 11:04:06.000000000 +0200
1072@@ -22,7 +22,7 @@
1073 #define MOD_USER_H
1074
1075 typedef union {
1076- zval *names[6];
1077+ zval *names[8];
1078 struct {
1079 zval *ps_open;
1080 zval *ps_close;
1081@@ -30,6 +30,8 @@
1082 zval *ps_write;
1083 zval *ps_destroy;
1084 zval *ps_gc;
1085+ zval *ps_create;
1086+ zval *ps_validate;
1087 } name;
1088 } ps_user;
1089
1090diff -Nura php-5.1.4/ext/session/php_session.h hardening-patch-5.1.4-0.4.13/ext/session/php_session.h
1091--- php-5.1.4/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100
1092+++ hardening-patch-5.1.4-0.4.13/ext/session/php_session.h 2006-08-07 11:04:06.000000000 +0200
1093@@ -23,7 +23,7 @@
1094
1095 #include "ext/standard/php_var.h"
1096
1097-#define PHP_SESSION_API 20020330
1098+#define PHP_SESSION_API 20051121
1099
1100 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1101 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1102@@ -32,6 +32,7 @@
1103 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1104 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1105 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1106+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1107
1108 /* default create id function */
1109 PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
1110@@ -45,6 +46,7 @@
1111 int (*s_destroy)(PS_DESTROY_ARGS);
1112 int (*s_gc)(PS_GC_ARGS);
1113 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1114+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1115 } ps_module;
1116
1117 #define PS_GET_MOD_DATA() *mod_data
1118@@ -57,6 +59,7 @@
1119 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1120 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1121 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1122+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1123
1124 #define PS_FUNCS(x) \
1125 PS_OPEN_FUNC(x); \
1126@@ -65,11 +68,12 @@
1127 PS_WRITE_FUNC(x); \
1128 PS_DESTROY_FUNC(x); \
1129 PS_GC_FUNC(x); \
1130- PS_CREATE_SID_FUNC(x)
1131+ PS_CREATE_SID_FUNC(x); \
1132+ PS_VALIDATE_SID_FUNC(x)
1133
1134 #define PS_MOD(x) \
1135 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1136- ps_delete_##x, ps_gc_##x, php_session_create_id
1137+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1138
1139 /* SID enabled module handler definitions */
1140 #define PS_FUNCS_SID(x) \
1141@@ -79,11 +83,12 @@
1142 PS_WRITE_FUNC(x); \
1143 PS_DESTROY_FUNC(x); \
1144 PS_GC_FUNC(x); \
1145- PS_CREATE_SID_FUNC(x)
1146+ PS_CREATE_SID_FUNC(x); \
1147+ PS_VALIDATE_SID(x)
1148
1149 #define PS_MOD_SID(x) \
1150 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1151- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1152+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1153
1154 typedef enum {
1155 php_session_disabled,
1156@@ -120,6 +125,7 @@
1157 zend_bool use_only_cookies;
1158 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1159 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1160+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1161
1162 long hash_func;
1163 long hash_bits_per_character;
1164diff -Nura php-5.1.4/ext/session/session.c hardening-patch-5.1.4-0.4.13/ext/session/session.c
1165--- php-5.1.4/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100
1166+++ hardening-patch-5.1.4-0.4.13/ext/session/session.c 2006-08-07 11:04:06.000000000 +0200
1167@@ -166,6 +166,7 @@
1168 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1169 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1170 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1171+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1172 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1173 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1174 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals)
1175@@ -758,6 +759,15 @@
1176 return;
1177 }
1178
1179+ /* If there is an ID, use session module to verify it */
1180+ if (PS(id)) {
1181+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1182+ efree(PS(id));
1183+ PS(id) = NULL;
1184+ PS(send_cookie) = 1;
1185+ }
1186+ }
1187+
1188 /* If there is no ID, use session module to create one */
1189 if (!PS(id))
1190 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1191@@ -1377,22 +1387,29 @@
1192 }
1193 /* }}} */
1194
1195-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1196+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1197 Sets user-level functions */
1198 PHP_FUNCTION(session_set_save_handler)
1199 {
1200- zval **args[6];
1201- int i;
1202+ zval **args[8];
1203+ int i, numargs;
1204 ps_user *mdata;
1205 char *name;
1206
1207- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1208+ numargs = ZEND_NUM_ARGS();
1209+ args[6] = NULL;
1210+ args[7] = NULL;
1211+
1212+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1213 WRONG_PARAM_COUNT;
1214
1215 if (PS(session_status) != php_session_none)
1216 RETURN_FALSE;
1217
1218- for (i = 0; i < 6; i++) {
1219+ for (i = 0; i < 8; i++) {
1220+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1221+ continue;
1222+ }
1223 if (!zend_is_callable(*args[i], 0, &name)) {
1224 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1225 efree(name);
1226@@ -1405,7 +1422,11 @@
1227
1228 mdata = emalloc(sizeof(*mdata));
1229
1230- for (i = 0; i < 6; i++) {
1231+ for (i = 0; i < 8; i++) {
1232+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1233+ mdata->names[i] = NULL;
1234+ continue;
1235+ }
1236 ZVAL_ADDREF(*args[i]);
1237 mdata->names[i] = *args[i];
1238 }
1239diff -Nura php-5.1.4/ext/session/tests/014.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/014.phpt
1240--- php-5.1.4/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200
1241+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/014.phpt 2006-08-07 11:04:06.000000000 +0200
1242@@ -5,6 +5,7 @@
1243 --INI--
1244 session.use_trans_sid=1
1245 session.use_cookies=0
1246+session.use_strict_mode=0
1247 session.cache_limiter=
1248 register_globals=1
1249 session.bug_compat_42=1
1250diff -Nura php-5.1.4/ext/session/tests/015.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/015.phpt
1251--- php-5.1.4/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200
1252+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/015.phpt 2006-08-07 11:04:06.000000000 +0200
1253@@ -5,6 +5,7 @@
1254 --INI--
1255 session.use_trans_sid=1
1256 session.use_cookies=0
1257+session.use_strict_mode=0
1258 session.cache_limiter=
1259 arg_separator.output=&
1260 session.name=PHPSESSID
1261diff -Nura php-5.1.4/ext/session/tests/018.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/018.phpt
1262--- php-5.1.4/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200
1263+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/018.phpt 2006-08-07 11:04:06.000000000 +0200
1264@@ -4,6 +4,7 @@
1265 <?php include('skipif.inc'); ?>
1266 --INI--
1267 session.use_cookies=0
1268+session.use_strict_mode=0
1269 session.cache_limiter=
1270 session.use_trans_sid=1
1271 session.name=PHPSESSID
1272diff -Nura php-5.1.4/ext/session/tests/019.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/019.phpt
1273--- php-5.1.4/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200
1274+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/019.phpt 2006-08-07 11:04:06.000000000 +0200
1275@@ -4,6 +4,7 @@
1276 <?php include('skipif.inc'); ?>
1277 --INI--
1278 session.use_cookies=0
1279+session.use_strict_mode=0
1280 session.cache_limiter=
1281 register_globals=1
1282 session.serialize_handler=php
1283diff -Nura php-5.1.4/ext/session/tests/020.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/020.phpt
1284--- php-5.1.4/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200
1285+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/020.phpt 2006-08-07 11:04:06.000000000 +0200
1286@@ -4,6 +4,7 @@
1287 <?php include('skipif.inc'); ?>
1288 --INI--
1289 session.use_cookies=0
1290+session.use_strict_mode=0
1291 session.cache_limiter=
1292 session.use_trans_sid=1
1293 arg_separator.output=&amp;
1294diff -Nura php-5.1.4/ext/session/tests/021.phpt hardening-patch-5.1.4-0.4.13/ext/session/tests/021.phpt
1295--- php-5.1.4/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200
1296+++ hardening-patch-5.1.4-0.4.13/ext/session/tests/021.phpt 2006-08-07 11:04:06.000000000 +0200
1297@@ -4,6 +4,7 @@
1298 <?php include('skipif.inc'); ?>
1299 --INI--
1300 session.use_cookies=0
1301+session.use_strict_mode=0
1302 session.cache_limiter=
1303 session.use_trans_sid=1
1304 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1305diff -Nura php-5.1.4/ext/sqlite/sess_sqlite.c hardening-patch-5.1.4-0.4.13/ext/sqlite/sess_sqlite.c
1306--- php-5.1.4/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100
1307+++ hardening-patch-5.1.4-0.4.13/ext/sqlite/sess_sqlite.c 2006-08-07 11:04:06.000000000 +0200
1308@@ -185,6 +185,76 @@
1309 return SQLITE_RETVAL(rv);
1310 }
1311
1312+PS_VALIDATE_SID_FUNC(sqlite)
1313+{
1314+ PS_SQLITE_DATA;
1315+ char *query;
1316+ const char *tail;
1317+ sqlite_vm *vm;
1318+ int colcount, result;
1319+ const char **rowdata, **colnames;
1320+ char *error;
1321+ size_t len;
1322+ const char *p;
1323+ char c;
1324+ int ret = FAILURE;
1325+
1326+ for (p = key; (c = *p); p++) {
1327+ /* valid characters are a..z,A..Z,0..9 */
1328+ if (!((c >= 'a' && c <= 'z')
1329+ || (c >= 'A' && c <= 'Z')
1330+ || (c >= '0' && c <= '9')
1331+ || c == ','
1332+ || c == '-')) {
1333+ return FAILURE;
1334+ break;
1335+ }
1336+ }
1337+
1338+ len = p - key;
1339+
1340+ if (len == 0)
1341+ return FAILURE;
1342+
1343+ if (!PS(use_strict_mode)) {
1344+ return SUCCESS;
1345+ }
1346+
1347+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
1348+ if (query == NULL) {
1349+ /* no memory */
1350+ return FAILURE;
1351+ }
1352+
1353+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
1354+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error);
1355+ sqlite_freemem(error);
1356+ sqlite_freemem(query);
1357+ return FAILURE;
1358+ }
1359+
1360+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
1361+ case SQLITE_ROW:
1362+ if (rowdata[0] != NULL) {
1363+ ret = SUCCESS;
1364+ }
1365+ break;
1366+ default:
1367+ sqlite_freemem(error);
1368+ error = NULL;
1369+ }
1370+
1371+ if (SQLITE_OK != sqlite_finalize(vm, &error)) {
1372+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error);
1373+ sqlite_freemem(error);
1374+ error = NULL;
1375+ }
1376+
1377+ sqlite_freemem(query);
1378+
1379+ return ret;
1380+}
1381+
1382 #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
1383
1384 /*
1385diff -Nura php-5.1.4/ext/sqlite/sqlite.c hardening-patch-5.1.4-0.4.13/ext/sqlite/sqlite.c
1386--- php-5.1.4/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200
1387+++ hardening-patch-5.1.4-0.4.13/ext/sqlite/sqlite.c 2006-08-07 11:04:06.000000000 +0200
1388@@ -1530,6 +1530,19 @@
1389 db->last_err_code = ret;
1390
1391 if (ret != SQLITE_OK) {
1392+#if HARDENING_PATCH
1393+ char *query_copy;
1394+ int i;
1395+
1396+ query_copy = estrdup(sql);
1397+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1398+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
1399+ efree(query_copy);
1400+ if (HG(hphp_sql_bailout_on_error)) {
1401+ sqlite_freemem(errtext);
1402+ zend_bailout();
1403+ }
1404+#endif
1405 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
1406 if (errmsg) {
1407 ZVAL_STRING(errmsg, errtext, 1);
1408diff -Nura php-5.1.4/ext/standard/array.c hardening-patch-5.1.4-0.4.13/ext/standard/array.c
1409--- php-5.1.4/ext/standard/array.c 2006-04-12 21:30:52.000000000 +0200
1410+++ hardening-patch-5.1.4-0.4.13/ext/standard/array.c 2006-08-07 11:04:07.000000000 +0200
1411@@ -1295,6 +1295,32 @@
1412 }
1413 }
1414 }
1415+
1416+ if (var_name[0] == 'H') {
1417+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1418+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1419+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1420+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1421+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1422+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1423+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1424+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1425+ return 0;
1426+ }
1427+ } else if (var_name[0] == '_') {
1428+ if ((strcmp(var_name, "_COOKIE")==0)||
1429+ (strcmp(var_name, "_ENV")==0)||
1430+ (strcmp(var_name, "_FILES")==0)||
1431+ (strcmp(var_name, "_GET")==0)||
1432+ (strcmp(var_name, "_POST")==0)||
1433+ (strcmp(var_name, "_REQUEST")==0)||
1434+ (strcmp(var_name, "_SESSION")==0)||
1435+ (strcmp(var_name, "_SERVER")==0)) {
1436+ return 0;
1437+ }
1438+ } else if (strcmp(var_name, "GLOBALS")==0) {
1439+ return 0;
1440+ }
1441
1442 return 1;
1443 }
1444diff -Nura php-5.1.4/ext/standard/basic_functions.c hardening-patch-5.1.4-0.4.13/ext/standard/basic_functions.c
1445--- php-5.1.4/ext/standard/basic_functions.c 2006-04-03 15:46:11.000000000 +0200
1446+++ hardening-patch-5.1.4-0.4.13/ext/standard/basic_functions.c 2006-08-07 11:04:07.000000000 +0200
1447@@ -151,12 +151,14 @@
1448 typedef struct _php_shutdown_function_entry {
1449 zval **arguments;
1450 int arg_count;
1451+ zend_bool created_by_eval;
1452 } php_shutdown_function_entry;
1453
1454 typedef struct _user_tick_function_entry {
1455 zval **arguments;
1456 int arg_count;
1457 int calling;
1458+ zend_bool created_by_eval;
1459 } user_tick_function_entry;
1460
1461 /* some prototypes for local functions */
1462@@ -188,6 +190,8 @@
1463 PHP_FE(get_html_translation_table, NULL)
1464 PHP_FE(sha1, NULL)
1465 PHP_FE(sha1_file, NULL)
1466+ PHP_FE(sha256, NULL)
1467+ PHP_FE(sha256_file, NULL)
1468 PHP_NAMED_FE(md5,php_if_md5, NULL)
1469 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1470 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1471@@ -632,7 +636,7 @@
1472 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1473
1474 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1475- PHP_FE(realpath, NULL)
1476+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1477 #endif
1478
1479 #ifdef HAVE_FNMATCH
1480@@ -2034,7 +2038,7 @@
1481 break;
1482
1483 case 3: /*save to a file */
1484- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
1485+ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
1486 if (!stream)
1487 return FAILURE;
1488 php_stream_write(stream, message, strlen(message));
1489@@ -2279,6 +2283,13 @@
1490 {
1491 zval retval;
1492 char *function_name = NULL;
1493+#if HARDENING_PATCH
1494+ zend_uint orig_code_type = EG(in_code_type);
1495+
1496+ if (shutdown_function_entry->created_by_eval) {
1497+ EG(in_code_type) = ZEND_EVAL_CODE;
1498+ }
1499+#endif
1500
1501 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1502 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1503@@ -2294,6 +2305,9 @@
1504 if (function_name) {
1505 efree(function_name);
1506 }
1507+#if HARDENING_PATCH
1508+ EG(in_code_type) = orig_code_type;
1509+#endif
1510 return 0;
1511 }
1512
1513@@ -2301,6 +2315,13 @@
1514 {
1515 zval retval;
1516 zval *function = tick_fe->arguments[0];
1517+#if HARDENING_PATCH
1518+ zend_uint orig_code_type = EG(in_code_type);
1519+
1520+ if (tick_fe->created_by_eval) {
1521+ EG(in_code_type) = ZEND_EVAL_CODE;
1522+ }
1523+#endif
1524
1525 /* Prevent reentrant calls to the same user ticks function */
1526 if (! tick_fe->calling) {
1527@@ -2332,6 +2353,9 @@
1528
1529 tick_fe->calling = 0;
1530 }
1531+#if HARDENING_PATCH
1532+ EG(in_code_type) = orig_code_type;
1533+#endif
1534 }
1535
1536 static void run_user_tick_functions(int tick_count)
1537@@ -2395,6 +2419,13 @@
1538 }
1539
1540 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
1541+#if HARDENING_PATCH
1542+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1543+ shutdown_function_entry.created_by_eval = 1;
1544+ } else {
1545+ shutdown_function_entry.created_by_eval = 0;
1546+ }
1547+#endif
1548
1549 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1550 efree(shutdown_function_entry.arguments);
1551@@ -2979,6 +3010,13 @@
1552 }
1553
1554 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1555+#if HARDENING_PATCH
1556+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1557+ tick_fe.created_by_eval = 1;
1558+ } else {
1559+ tick_fe.created_by_eval = 0;
1560+ }
1561+#endif
1562
1563 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1564 efree(tick_fe.arguments);
1565@@ -3282,6 +3320,35 @@
1566 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1567 }
1568
1569+ if (new_key[0] == 'H') {
1570+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1571+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1572+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1573+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1574+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1575+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1576+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1577+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1578+ efree(new_key);
1579+ return 0;
1580+ }
1581+ } else if (new_key[0] == '_') {
1582+ if ((strcmp(new_key, "_COOKIE")==0)||
1583+ (strcmp(new_key, "_ENV")==0)||
1584+ (strcmp(new_key, "_FILES")==0)||
1585+ (strcmp(new_key, "_GET")==0)||
1586+ (strcmp(new_key, "_POST")==0)||
1587+ (strcmp(new_key, "_REQUEST")==0)||
1588+ (strcmp(new_key, "_SESSION")==0)||
1589+ (strcmp(new_key, "_SERVER")==0)) {
1590+ efree(new_key);
1591+ return 0;
1592+ }
1593+ } else if (strcmp(new_key, "GLOBALS")==0) {
1594+ efree(new_key);
1595+ return 0;
1596+ }
1597+
1598 zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC);
1599 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1600
1601diff -Nura php-5.1.4/ext/standard/config.m4 hardening-patch-5.1.4-0.4.13/ext/standard/config.m4
1602--- php-5.1.4/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100
1603+++ hardening-patch-5.1.4-0.4.13/ext/standard/config.m4 2006-08-07 11:04:07.000000000 +0200
1604@@ -203,7 +203,7 @@
1605 if test "$ac_cv_crypt_blowfish" = "yes"; then
1606 ac_result=1
1607 else
1608- ac_result=0
1609+ ac_result=1
1610 fi
1611 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1612 ])
1613@@ -489,7 +489,7 @@
1614 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1615 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1616 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
1617- filters.c proc_open.c streamsfuncs.c http.c)
1618+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
1619
1620 PHP_ADD_MAKEFILE_FRAGMENT
1621
1622diff -Nura php-5.1.4/ext/standard/config.w32 hardening-patch-5.1.4-0.4.13/ext/standard/config.w32
1623--- php-5.1.4/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100
1624+++ hardening-patch-5.1.4-0.4.13/ext/standard/config.w32 2006-08-07 11:04:07.000000000 +0200
1625@@ -16,5 +16,5 @@
1626 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
1627 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
1628 user_filters.c uuencode.c filters.c proc_open.c \
1629- streamsfuncs.c http.c", false /* never shared */);
1630+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
1631
1632diff -Nura php-5.1.4/ext/standard/crypt_blowfish.c hardening-patch-5.1.4-0.4.13/ext/standard/crypt_blowfish.c
1633--- php-5.1.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1634+++ hardening-patch-5.1.4-0.4.13/ext/standard/crypt_blowfish.c 2006-08-07 11:04:07.000000000 +0200
1635@@ -0,0 +1,748 @@
1636+/*
1637+ * This code comes from John the Ripper password cracker, with reentrant
1638+ * and crypt(3) interfaces added, but optimizations specific to password
1639+ * cracking removed.
1640+ *
1641+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1642+ * placed in the public domain.
1643+ *
1644+ * There's absolutely no warranty.
1645+ *
1646+ * It is my intent that you should be able to use this on your system,
1647+ * as a part of a software package, or anywhere else to improve security,
1648+ * ensure compatibility, or for any other purpose. I would appreciate
1649+ * it if you give credit where it is due and keep your modifications in
1650+ * the public domain as well, but I don't require that in order to let
1651+ * you place this code and any modifications you make under a license
1652+ * of your choice.
1653+ *
1654+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1655+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1656+ * ideas. The password hashing algorithm was designed by David Mazieres
1657+ * <dm at lcs.mit.edu>.
1658+ *
1659+ * There's a paper on the algorithm that explains its design decisions:
1660+ *
1661+ * http://www.usenix.org/events/usenix99/provos.html
1662+ *
1663+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1664+ * Blowfish library (I can't be sure if I would think of something if I
1665+ * hadn't seen his code).
1666+ */
1667+
1668+#include <string.h>
1669+
1670+#include <errno.h>
1671+#ifndef __set_errno
1672+#define __set_errno(val) errno = (val)
1673+#endif
1674+
1675+#undef __CONST
1676+#ifdef __GNUC__
1677+#define __CONST __const
1678+#else
1679+#define __CONST
1680+#endif
1681+
1682+#ifdef __i386__
1683+#define BF_ASM 0
1684+#define BF_SCALE 1
1685+#elif defined(__alpha__) || defined(__hppa__)
1686+#define BF_ASM 0
1687+#define BF_SCALE 1
1688+#else
1689+#define BF_ASM 0
1690+#define BF_SCALE 0
1691+#endif
1692+
1693+typedef unsigned int BF_word;
1694+
1695+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1696+#define BF_N 16
1697+
1698+typedef BF_word BF_key[BF_N + 2];
1699+
1700+typedef struct {
1701+ BF_word S[4][0x100];
1702+ BF_key P;
1703+} BF_ctx;
1704+
1705+/*
1706+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1707+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1708+ */
1709+static BF_word BF_magic_w[6] = {
1710+ 0x4F727068, 0x65616E42, 0x65686F6C,
1711+ 0x64657253, 0x63727944, 0x6F756274
1712+};
1713+
1714+/*
1715+ * P-box and S-box tables initialized with digits of Pi.
1716+ */
1717+static BF_ctx BF_init_state = {
1718+ {
1719+ {
1720+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1721+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1722+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1723+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1724+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1725+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1726+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1727+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1728+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1729+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1730+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1731+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1732+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1733+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1734+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1735+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1736+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1737+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1738+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1739+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1740+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1741+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1742+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1743+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1744+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1745+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1746+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1747+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1748+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1749+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1750+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1751+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1752+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1753+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1754+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1755+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1756+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1757+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1758+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1759+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1760+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1761+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1762+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1763+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1764+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1765+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1766+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1767+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1768+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1769+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1770+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1771+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1772+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1773+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1774+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1775+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1776+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1777+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1778+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1779+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1780+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1781+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1782+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1783+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1784+ }, {
1785+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1786+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1787+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1788+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1789+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1790+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1791+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1792+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1793+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1794+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1795+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1796+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1797+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1798+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1799+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1800+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1801+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1802+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1803+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1804+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1805+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1806+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1807+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1808+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1809+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1810+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1811+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1812+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1813+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1814+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1815+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1816+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1817+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1818+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1819+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1820+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1821+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1822+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1823+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1824+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1825+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1826+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1827+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1828+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1829+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1830+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1831+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1832+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1833+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1834+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1835+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1836+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1837+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1838+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1839+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1840+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1841+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1842+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1843+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1844+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1845+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1846+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1847+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1848+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1849+ }, {
1850+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1851+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1852+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1853+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1854+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1855+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1856+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1857+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1858+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1859+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1860+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1861+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1862+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1863+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1864+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1865+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1866+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1867+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1868+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1869+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1870+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1871+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1872+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1873+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1874+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1875+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1876+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1877+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1878+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1879+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1880+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1881+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1882+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1883+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1884+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1885+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1886+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1887+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1888+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1889+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1890+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1891+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1892+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1893+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1894+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1895+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1896+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1897+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1898+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1899+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1900+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1901+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1902+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1903+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1904+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1905+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1906+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1907+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1908+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1909+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1910+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1911+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1912+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1913+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1914+ }, {
1915+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1916+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1917+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1918+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1919+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1920+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1921+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1922+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1923+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1924+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1925+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1926+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1927+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1928+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1929+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1930+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1931+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1932+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1933+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1934+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1935+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1936+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1937+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1938+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1939+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1940+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1941+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1942+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1943+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1944+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1945+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1946+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1947+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1948+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1949+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1950+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1951+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1952+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1953+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1954+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1955+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1956+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1957+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1958+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1959+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1960+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1961+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1962+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1963+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1964+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1965+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1966+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1967+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1968+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1969+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1970+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1971+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1972+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1973+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1974+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1975+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1976+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1977+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1978+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1979+ }
1980+ }, {
1981+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1982+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1983+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1984+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1985+ 0x9216d5d9, 0x8979fb1b
1986+ }
1987+};
1988+
1989+static unsigned char BF_itoa64[64 + 1] =
1990+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1991+
1992+static unsigned char BF_atoi64[0x60] = {
1993+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1994+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1995+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1996+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1997+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1998+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1999+};
2000+
2001+/*
2002+ * This may be optimized out if built with function inlining and no BF_ASM.
2003+ */
2004+static void clean(void *data, int size)
2005+{
2006+#if BF_ASM
2007+ extern void _BF_clean(void *data);
2008+#endif
2009+ memset(data, 0, size);
2010+#if BF_ASM
2011+ _BF_clean(data);
2012+#endif
2013+}
2014+
2015+#define BF_safe_atoi64(dst, src) \
2016+{ \
2017+ tmp = (unsigned char)(src); \
2018+ if (tmp == '$') break; \
2019+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
2020+ tmp = BF_atoi64[tmp]; \
2021+ if (tmp > 63) return -1; \
2022+ (dst) = tmp; \
2023+}
2024+
2025+static int BF_decode(BF_word *dst, __CONST char *src, int size)
2026+{
2027+ unsigned char *dptr = (unsigned char *)dst;
2028+ unsigned char *end = dptr + size;
2029+ unsigned char *sptr = (unsigned char *)src;
2030+ unsigned int tmp, c1, c2, c3, c4;
2031+
2032+ do {
2033+ BF_safe_atoi64(c1, *sptr++);
2034+ BF_safe_atoi64(c2, *sptr++);
2035+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
2036+ if (dptr >= end) break;
2037+
2038+ BF_safe_atoi64(c3, *sptr++);
2039+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
2040+ if (dptr >= end) break;
2041+
2042+ BF_safe_atoi64(c4, *sptr++);
2043+ *dptr++ = ((c3 & 0x03) << 6) | c4;
2044+ } while (dptr < end);
2045+
2046+ while (dptr < end)
2047+ *dptr++ = 0;
2048+
2049+ return 0;
2050+}
2051+
2052+static void BF_encode(char *dst, __CONST BF_word *src, int size)
2053+{
2054+ unsigned char *sptr = (unsigned char *)src;
2055+ unsigned char *end = sptr + size;
2056+ unsigned char *dptr = (unsigned char *)dst;
2057+ unsigned int c1, c2;
2058+
2059+ do {
2060+ c1 = *sptr++;
2061+ *dptr++ = BF_itoa64[c1 >> 2];
2062+ c1 = (c1 & 0x03) << 4;
2063+ if (sptr >= end) {
2064+ *dptr++ = BF_itoa64[c1];
2065+ break;
2066+ }
2067+
2068+ c2 = *sptr++;
2069+ c1 |= c2 >> 4;
2070+ *dptr++ = BF_itoa64[c1];
2071+ c1 = (c2 & 0x0f) << 2;
2072+ if (sptr >= end) {
2073+ *dptr++ = BF_itoa64[c1];
2074+ break;
2075+ }
2076+
2077+ c2 = *sptr++;
2078+ c1 |= c2 >> 6;
2079+ *dptr++ = BF_itoa64[c1];
2080+ *dptr++ = BF_itoa64[c2 & 0x3f];
2081+ } while (sptr < end);
2082+}
2083+
2084+static void BF_swap(BF_word *x, int count)
2085+{
2086+ static int endianness_check = 1;
2087+ char *is_little_endian = (char *)&endianness_check;
2088+ BF_word tmp;
2089+
2090+ if (*is_little_endian)
2091+ do {
2092+ tmp = *x;
2093+ tmp = (tmp << 16) | (tmp >> 16);
2094+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
2095+ } while (--count);
2096+}
2097+
2098+#if BF_SCALE
2099+/* Architectures which can shift addresses left by 2 bits with no extra cost */
2100+#define BF_ROUND(L, R, N) \
2101+ tmp1 = L & 0xFF; \
2102+ tmp2 = L >> 8; \
2103+ tmp2 &= 0xFF; \
2104+ tmp3 = L >> 16; \
2105+ tmp3 &= 0xFF; \
2106+ tmp4 = L >> 24; \
2107+ tmp1 = data.ctx.S[3][tmp1]; \
2108+ tmp2 = data.ctx.S[2][tmp2]; \
2109+ tmp3 = data.ctx.S[1][tmp3]; \
2110+ tmp3 += data.ctx.S[0][tmp4]; \
2111+ tmp3 ^= tmp2; \
2112+ R ^= data.ctx.P[N + 1]; \
2113+ tmp3 += tmp1; \
2114+ R ^= tmp3;
2115+#else
2116+/* Architectures with no complicated addressing modes supported */
2117+#define BF_INDEX(S, i) \
2118+ (*((BF_word *)(((unsigned char *)S) + (i))))
2119+#define BF_ROUND(L, R, N) \
2120+ tmp1 = L & 0xFF; \
2121+ tmp1 <<= 2; \
2122+ tmp2 = L >> 6; \
2123+ tmp2 &= 0x3FC; \
2124+ tmp3 = L >> 14; \
2125+ tmp3 &= 0x3FC; \
2126+ tmp4 = L >> 22; \
2127+ tmp4 &= 0x3FC; \
2128+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
2129+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
2130+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
2131+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
2132+ tmp3 ^= tmp2; \
2133+ R ^= data.ctx.P[N + 1]; \
2134+ tmp3 += tmp1; \
2135+ R ^= tmp3;
2136+#endif
2137+
2138+/*
2139+ * Encrypt one block, BF_N is hardcoded here.
2140+ */
2141+#define BF_ENCRYPT \
2142+ L ^= data.ctx.P[0]; \
2143+ BF_ROUND(L, R, 0); \
2144+ BF_ROUND(R, L, 1); \
2145+ BF_ROUND(L, R, 2); \
2146+ BF_ROUND(R, L, 3); \
2147+ BF_ROUND(L, R, 4); \
2148+ BF_ROUND(R, L, 5); \
2149+ BF_ROUND(L, R, 6); \
2150+ BF_ROUND(R, L, 7); \
2151+ BF_ROUND(L, R, 8); \
2152+ BF_ROUND(R, L, 9); \
2153+ BF_ROUND(L, R, 10); \
2154+ BF_ROUND(R, L, 11); \
2155+ BF_ROUND(L, R, 12); \
2156+ BF_ROUND(R, L, 13); \
2157+ BF_ROUND(L, R, 14); \
2158+ BF_ROUND(R, L, 15); \
2159+ tmp4 = R; \
2160+ R = L; \
2161+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2162+
2163+#if BF_ASM
2164+#define BF_body() \
2165+ _BF_body_r(&data.ctx);
2166+#else
2167+#define BF_body() \
2168+ L = R = 0; \
2169+ ptr = data.ctx.P; \
2170+ do { \
2171+ ptr += 2; \
2172+ BF_ENCRYPT; \
2173+ *(ptr - 2) = L; \
2174+ *(ptr - 1) = R; \
2175+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2176+\
2177+ ptr = data.ctx.S[0]; \
2178+ do { \
2179+ ptr += 2; \
2180+ BF_ENCRYPT; \
2181+ *(ptr - 2) = L; \
2182+ *(ptr - 1) = R; \
2183+ } while (ptr < &data.ctx.S[3][0xFF]);
2184+#endif
2185+
2186+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2187+{
2188+ __CONST char *ptr = key;
2189+ int i, j;
2190+ BF_word tmp;
2191+
2192+ for (i = 0; i < BF_N + 2; i++) {
2193+ tmp = 0;
2194+ for (j = 0; j < 4; j++) {
2195+ tmp <<= 8;
2196+ tmp |= *ptr;
2197+
2198+ if (!*ptr) ptr = key; else ptr++;
2199+ }
2200+
2201+ expanded[i] = tmp;
2202+ initial[i] = BF_init_state.P[i] ^ tmp;
2203+ }
2204+}
2205+
2206+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2207+ char *output, int size)
2208+{
2209+#if BF_ASM
2210+ extern void _BF_body_r(BF_ctx *ctx);
2211+#endif
2212+ struct {
2213+ BF_ctx ctx;
2214+ BF_key expanded_key;
2215+ union {
2216+ BF_word salt[4];
2217+ BF_word output[6];
2218+ } binary;
2219+ } data;
2220+ BF_word L, R;
2221+ BF_word tmp1, tmp2, tmp3, tmp4;
2222+ BF_word *ptr;
2223+ BF_word count;
2224+ int i;
2225+
2226+ if (size < 7 + 22 + 31 + 1) {
2227+ __set_errno(ERANGE);
2228+ return NULL;
2229+ }
2230+
2231+ if (setting[0] != '$' ||
2232+ setting[1] != '2' ||
2233+ setting[2] != 'a' ||
2234+ setting[3] != '$' ||
2235+ setting[4] < '0' || setting[4] > '3' ||
2236+ setting[5] < '0' || setting[5] > '9' ||
2237+ setting[6] != '$') {
2238+ __set_errno(EINVAL);
2239+ return NULL;
2240+ }
2241+
2242+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2243+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2244+ clean(data.binary.salt, sizeof(data.binary.salt));
2245+ __set_errno(EINVAL);
2246+ return NULL;
2247+ }
2248+
2249+ BF_swap(data.binary.salt, 4);
2250+
2251+ BF_set_key(key, data.expanded_key, data.ctx.P);
2252+
2253+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2254+
2255+ L = R = 0;
2256+ for (i = 0; i < BF_N + 2; i += 2) {
2257+ L ^= data.binary.salt[i & 2];
2258+ R ^= data.binary.salt[(i & 2) + 1];
2259+ BF_ENCRYPT;
2260+ data.ctx.P[i] = L;
2261+ data.ctx.P[i + 1] = R;
2262+ }
2263+
2264+ ptr = data.ctx.S[0];
2265+ do {
2266+ ptr += 4;
2267+ L ^= data.binary.salt[(BF_N + 2) & 3];
2268+ R ^= data.binary.salt[(BF_N + 3) & 3];
2269+ BF_ENCRYPT;
2270+ *(ptr - 4) = L;
2271+ *(ptr - 3) = R;
2272+
2273+ L ^= data.binary.salt[(BF_N + 4) & 3];
2274+ R ^= data.binary.salt[(BF_N + 5) & 3];
2275+ BF_ENCRYPT;
2276+ *(ptr - 2) = L;
2277+ *(ptr - 1) = R;
2278+ } while (ptr < &data.ctx.S[3][0xFF]);
2279+
2280+ do {
2281+ data.ctx.P[0] ^= data.expanded_key[0];
2282+ data.ctx.P[1] ^= data.expanded_key[1];
2283+ data.ctx.P[2] ^= data.expanded_key[2];
2284+ data.ctx.P[3] ^= data.expanded_key[3];
2285+ data.ctx.P[4] ^= data.expanded_key[4];
2286+ data.ctx.P[5] ^= data.expanded_key[5];
2287+ data.ctx.P[6] ^= data.expanded_key[6];
2288+ data.ctx.P[7] ^= data.expanded_key[7];
2289+ data.ctx.P[8] ^= data.expanded_key[8];
2290+ data.ctx.P[9] ^= data.expanded_key[9];
2291+ data.ctx.P[10] ^= data.expanded_key[10];
2292+ data.ctx.P[11] ^= data.expanded_key[11];
2293+ data.ctx.P[12] ^= data.expanded_key[12];
2294+ data.ctx.P[13] ^= data.expanded_key[13];
2295+ data.ctx.P[14] ^= data.expanded_key[14];
2296+ data.ctx.P[15] ^= data.expanded_key[15];
2297+ data.ctx.P[16] ^= data.expanded_key[16];
2298+ data.ctx.P[17] ^= data.expanded_key[17];
2299+
2300+ BF_body();
2301+
2302+ tmp1 = data.binary.salt[0];
2303+ tmp2 = data.binary.salt[1];
2304+ tmp3 = data.binary.salt[2];
2305+ tmp4 = data.binary.salt[3];
2306+ data.ctx.P[0] ^= tmp1;
2307+ data.ctx.P[1] ^= tmp2;
2308+ data.ctx.P[2] ^= tmp3;
2309+ data.ctx.P[3] ^= tmp4;
2310+ data.ctx.P[4] ^= tmp1;
2311+ data.ctx.P[5] ^= tmp2;
2312+ data.ctx.P[6] ^= tmp3;
2313+ data.ctx.P[7] ^= tmp4;
2314+ data.ctx.P[8] ^= tmp1;
2315+ data.ctx.P[9] ^= tmp2;
2316+ data.ctx.P[10] ^= tmp3;
2317+ data.ctx.P[11] ^= tmp4;
2318+ data.ctx.P[12] ^= tmp1;
2319+ data.ctx.P[13] ^= tmp2;
2320+ data.ctx.P[14] ^= tmp3;
2321+ data.ctx.P[15] ^= tmp4;
2322+ data.ctx.P[16] ^= tmp1;
2323+ data.ctx.P[17] ^= tmp2;
2324+
2325+ BF_body();
2326+ } while (--count);
2327+
2328+ for (i = 0; i < 6; i += 2) {
2329+ L = BF_magic_w[i];
2330+ R = BF_magic_w[i + 1];
2331+
2332+ count = 64;
2333+ do {
2334+ BF_ENCRYPT;
2335+ } while (--count);
2336+
2337+ data.binary.output[i] = L;
2338+ data.binary.output[i + 1] = R;
2339+ }
2340+
2341+ memcpy(output, setting, 7 + 22 - 1);
2342+ output[7 + 22 - 1] = BF_itoa64[(int)
2343+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2344+
2345+/* This has to be bug-compatible with the original implementation, so
2346+ * only encode 23 of the 24 bytes. :-) */
2347+ BF_swap(data.binary.output, 6);
2348+ BF_encode(&output[7 + 22], data.binary.output, 23);
2349+ output[7 + 22 + 31] = '\0';
2350+
2351+/* Overwrite the most obvious sensitive data we have on the stack. Note
2352+ * that this does not guarantee there's no sensitive data left on the
2353+ * stack and/or in registers; I'm not aware of portable code that does. */
2354+ clean(&data, sizeof(data));
2355+
2356+ return output;
2357+}
2358+
2359+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2360+ __CONST char *input, int size, char *output, int output_size)
2361+{
2362+ if (size < 16 || output_size < 7 + 22 + 1 ||
2363+ (count && (count < 4 || count > 31))) {
2364+ if (output_size > 0) output[0] = '\0';
2365+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2366+ return NULL;
2367+ }
2368+
2369+ if (!count) count = 5;
2370+
2371+ output[0] = '$';
2372+ output[1] = '2';
2373+ output[2] = 'a';
2374+ output[3] = '$';
2375+ output[4] = '0' + count / 10;
2376+ output[5] = '0' + count % 10;
2377+ output[6] = '$';
2378+
2379+ BF_encode(&output[7], (BF_word *)input, 16);
2380+ output[7 + 22] = '\0';
2381+
2382+ return output;
2383+}
2384diff -Nura php-5.1.4/ext/standard/crypt.c hardening-patch-5.1.4-0.4.13/ext/standard/crypt.c
2385--- php-5.1.4/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100
2386+++ hardening-patch-5.1.4-0.4.13/ext/standard/crypt.c 2006-08-07 11:04:07.000000000 +0200
2387@@ -100,6 +100,8 @@
2388 return SUCCESS;
2389 }
2390
2391+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2392+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2393
2394 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2395
2396@@ -135,7 +137,14 @@
2397
2398 /* The automatic salt generation only covers standard DES and md5-crypt */
2399 if(!*salt) {
2400-#if PHP_MD5_CRYPT
2401+#if PHP_BLOWFISH_CRYPT
2402+ char randat[16];
2403+ int i;
2404+
2405+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2406+
2407+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2408+#elif PHP_MD5_CRYPT
2409 strcpy(salt, "$1$");
2410 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2411 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2412@@ -145,8 +154,24 @@
2413 salt[2] = '\0';
2414 #endif
2415 }
2416-
2417- RETVAL_STRING(crypt(str, salt), 1);
2418+
2419+ if (salt[0] == '$' &&
2420+ salt[1] == '2' &&
2421+ salt[2] == 'a' &&
2422+ salt[3] == '$' &&
2423+ salt[4] >= '0' && salt[4] <= '3' &&
2424+ salt[5] >= '0' && salt[5] <= '9' &&
2425+ salt[6] == '$') {
2426+
2427+ char output[PHP_MAX_SALT_LEN+1];
2428+
2429+ output[0] = 0;
2430+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2431+ RETVAL_STRING(output, 1);
2432+
2433+ } else {
2434+ RETVAL_STRING(crypt(str, salt), 1);
2435+ }
2436 }
2437 /* }}} */
2438 #endif
2439diff -Nura php-5.1.4/ext/standard/dl.c hardening-patch-5.1.4-0.4.13/ext/standard/dl.c
2440--- php-5.1.4/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100
2441+++ hardening-patch-5.1.4-0.4.13/ext/standard/dl.c 2006-08-07 11:04:07.000000000 +0200
2442@@ -164,8 +164,35 @@
2443 RETURN_FALSE;
2444 }
2445 module_entry = get_module();
2446+
2447+ /* check if Hardening-Patch is installed */
2448+ if (module_entry->zend_api < 1000000000) {
2449+ php_error_docref(NULL TSRMLS_CC, error_type,
2450+ "%s: Unable to initialize module\n"
2451+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2452+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2453+ "These options need to match\n",
2454+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2455+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2456+ DL_UNLOAD(handle);
2457+ RETURN_FALSE;
2458+ }
2459+
2460+ /* check if correct Hardening-Patch is installed */
2461+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2462+ php_error_docref(NULL TSRMLS_CC, error_type,
2463+ "%s: Unable to initialize module\n"
2464+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2465+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2466+ "These options need to match\n",
2467+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2468+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2469+ DL_UNLOAD(handle);
2470+ RETURN_FALSE;
2471+ }
2472+
2473 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2474- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2475+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2476 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2477 struct pre_4_1_0_module_entry {
2478 char *name;
2479@@ -199,7 +226,7 @@
2480 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2481 } else {
2482 name = module_entry->name;
2483- zend_api = module_entry->zend_api;
2484+ zend_api = module_entry->real_zend_api;
2485 zend_debug = module_entry->zend_debug;
2486 zts = module_entry->zts;
2487 }
2488diff -Nura php-5.1.4/ext/standard/file.c hardening-patch-5.1.4-0.4.13/ext/standard/file.c
2489--- php-5.1.4/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200
2490+++ hardening-patch-5.1.4-0.4.13/ext/standard/file.c 2006-08-07 11:04:07.000000000 +0200
2491@@ -2302,7 +2302,7 @@
2492 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2493 /* {{{ proto string realpath(string path)
2494 Return the resolved path */
2495-PHP_FUNCTION(realpath)
2496+PHP_FUNCTION(real_path)
2497 {
2498 zval **path;
2499 char resolved_path_buff[MAXPATHLEN];
2500diff -Nura php-5.1.4/ext/standard/file.h hardening-patch-5.1.4-0.4.13/ext/standard/file.h
2501--- php-5.1.4/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100
2502+++ hardening-patch-5.1.4-0.4.13/ext/standard/file.h 2006-08-07 11:04:07.000000000 +0200
2503@@ -61,7 +61,7 @@
2504 PHP_FUNCTION(fd_set);
2505 PHP_FUNCTION(fd_isset);
2506 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
2507-PHP_FUNCTION(realpath);
2508+PHP_FUNCTION(real_path);
2509 PHP_FUNCTION(fnmatch);
2510 #endif
2511 PHP_NAMED_FUNCTION(php_if_ftruncate);
2512diff -Nura php-5.1.4/ext/standard/filestat.c hardening-patch-5.1.4-0.4.13/ext/standard/filestat.c
2513--- php-5.1.4/ext/standard/filestat.c 2006-04-25 10:41:02.000000000 +0200
2514+++ hardening-patch-5.1.4-0.4.13/ext/standard/filestat.c 2006-08-07 11:04:07.000000000 +0200
2515@@ -634,7 +634,7 @@
2516 }
2517
2518 if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) {
2519- if (php_check_open_basedir(local TSRMLS_CC)) {
2520+ if (php_check_open_basedir(local TSRMLS_CC) || (PG(safe_mode) && !php_checkuid_ex(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS))) {
2521 RETURN_FALSE;
2522 }
2523 }
2524diff -Nura php-5.1.4/ext/standard/head.c hardening-patch-5.1.4-0.4.13/ext/standard/head.c
2525--- php-5.1.4/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100
2526+++ hardening-patch-5.1.4-0.4.13/ext/standard/head.c 2006-08-07 11:04:07.000000000 +0200
2527@@ -45,7 +45,7 @@
2528 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2529 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2530 return;
2531-
2532+
2533 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2534 }
2535 /* }}} */
2536diff -Nura php-5.1.4/ext/standard/info.c hardening-patch-5.1.4-0.4.13/ext/standard/info.c
2537--- php-5.1.4/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200
2538+++ hardening-patch-5.1.4-0.4.13/ext/standard/info.c 2006-08-07 11:04:07.000000000 +0200
2539@@ -154,7 +154,7 @@
2540 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
2541 if (!sapi_module.phpinfo_as_text) {
2542 PUTS("<pre>");
2543- zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
2544+ zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
2545 PUTS("</pre>");
2546 } else {
2547 zend_print_zval_r(*tmp, 0 TSRMLS_CC);
2548@@ -411,7 +411,7 @@
2549
2550 if (flag & PHP_INFO_GENERAL) {
2551 char *zend_version = get_zend_version();
2552- char temp_api[10];
2553+ char temp_api[11];
2554 char *logo_guid;
2555
2556 php_uname = php_get_uname('a');
2557@@ -434,11 +434,22 @@
2558 PUTS("\" alt=\"PHP Logo\" /></a>");
2559 }
2560
2561+#if HARDENING_PATCH
2562+ if (!sapi_module.phpinfo_as_text) {
2563+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2564+ } else {
2565+ char temp_ver[40];
2566+
2567+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2568+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2569+ }
2570+#else
2571 if (!sapi_module.phpinfo_as_text) {
2572 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2573 } else {
2574 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2575- }
2576+ }
2577+#endif
2578 php_info_print_box_end();
2579 php_info_print_table_start();
2580 php_info_print_table_row(2, "System", php_uname );
2581diff -Nura php-5.1.4/ext/standard/mail.c hardening-patch-5.1.4-0.4.13/ext/standard/mail.c
2582--- php-5.1.4/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100
2583+++ hardening-patch-5.1.4-0.4.13/ext/standard/mail.c 2006-08-07 11:42:21.000000000 +0200
2584@@ -78,6 +78,25 @@
2585 }
2586 /* }}} */
2587
2588+/* {{{ hphp_strcasestr */
2589+char *hphp_strcasestr(char *haystack, char *needle)
2590+{
2591+ unsigned char *t, *h, *n;
2592+
2593+ h = (unsigned char *) haystack;
2594+conts:
2595+ while (*h) {
2596+ n = (unsigned char *) needle;
2597+ for (t=h++; *n && *h; t++, n++) {
2598+ if (toupper(*t) != toupper(*n)) goto conts;
2599+ }
2600+ return ((char*)h-1);
2601+ }
2602+
2603+ return (NULL);
2604+}
2605+/* }}} */
2606+
2607 /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
2608 Send an email message */
2609 PHP_FUNCTION(mail)
2610@@ -104,6 +123,44 @@
2611 return;
2612 }
2613
2614+ if (HG(hphp_mailprotect) > 0) {
2615+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) {
2616+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped");
2617+ RETURN_FALSE;
2618+ }
2619+
2620+ /* check for spam attempts with buggy webforms */
2621+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) {
2622+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped");
2623+ RETURN_FALSE;
2624+ }
2625+
2626+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) {
2627+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped");
2628+ RETURN_FALSE;
2629+ }
2630+
2631+ if (HG(hphp_mailprotect) > 1) {
2632+ /* search for to, cc or bcc headers */
2633+ if (headers_len > 0 && headers != NULL) {
2634+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) {
2635+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter.");
2636+ RETURN_FALSE;
2637+ }
2638+
2639+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) {
2640+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter.");
2641+ RETURN_FALSE;
2642+ }
2643+
2644+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) {
2645+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter.");
2646+ RETURN_FALSE;
2647+ }
2648+ }
2649+ }
2650+ }
2651+
2652 if (to_len > 0) {
2653 to_r = estrndup(to, to_len);
2654 for (; to_len; to_len--) {
2655diff -Nura php-5.1.4/ext/standard/php_standard.h hardening-patch-5.1.4-0.4.13/ext/standard/php_standard.h
2656--- php-5.1.4/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100
2657+++ hardening-patch-5.1.4-0.4.13/ext/standard/php_standard.h 2006-08-07 11:04:07.000000000 +0200
2658@@ -28,6 +28,7 @@
2659 #include "php_mail.h"
2660 #include "md5.h"
2661 #include "sha1.h"
2662+#include "sha256.h"
2663 #include "html.h"
2664 #include "exec.h"
2665 #include "file.h"
2666diff -Nura php-5.1.4/ext/standard/sha256.c hardening-patch-5.1.4-0.4.13/ext/standard/sha256.c
2667--- php-5.1.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2668+++ hardening-patch-5.1.4-0.4.13/ext/standard/sha256.c 2006-08-07 11:04:07.000000000 +0200
2669@@ -0,0 +1,388 @@
2670+/*
2671+ +----------------------------------------------------------------------+
2672+ | PHP Version 5 |
2673+ +----------------------------------------------------------------------+
2674+ | Copyright (c) 1997-2004 The PHP Group |
2675+ +----------------------------------------------------------------------+
2676+ | This source file is subject to version 3.0 of the PHP license, |
2677+ | that is bundled with this package in the file LICENSE, and is |
2678+ | available through the world-wide-web at the following url: |
2679+ | http://www.php.net/license/3_0.txt. |
2680+ | If you did not receive a copy of the PHP license and are unable to |
2681+ | obtain it through the world-wide-web, please send a note to |
2682+ | license@php.net so we can mail you a copy immediately. |
2683+ +----------------------------------------------------------------------+
2684+ | Author: Stefan Esser <sesser@php.net> |
2685+ +----------------------------------------------------------------------+
2686+*/
2687+
2688+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2689+
2690+#include "php.h"
2691+
2692+/* This code is heavily based on the PHP md5/sha1 implementations */
2693+
2694+#include "sha256.h"
2695+
2696+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2697+{
2698+ int i;
2699+
2700+ for (i = 0; i < 32; i++) {
2701+ sprintf(sha256str, "%02x", digest[i]);
2702+ sha256str += 2;
2703+ }
2704+
2705+ *sha256str = '\0';
2706+}
2707+
2708+/* {{{ proto string sha256(string str [, bool raw_output])
2709+ Calculate the sha256 hash of a string */
2710+PHP_FUNCTION(sha256)
2711+{
2712+ char *arg;
2713+ int arg_len;
2714+ zend_bool raw_output = 0;
2715+ char sha256str[65];
2716+ PHP_SHA256_CTX context;
2717+ unsigned char digest[32];
2718+
2719+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2720+ return;
2721+ }
2722+
2723+ sha256str[0] = '\0';
2724+ PHP_SHA256Init(&context);
2725+ PHP_SHA256Update(&context, arg, arg_len);
2726+ PHP_SHA256Final(digest, &context);
2727+ if (raw_output) {
2728+ RETURN_STRINGL(digest, 32, 1);
2729+ } else {
2730+ make_sha256_digest(sha256str, digest);
2731+ RETVAL_STRING(sha256str, 1);
2732+ }
2733+
2734+}
2735+
2736+/* }}} */
2737+
2738+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2739+ Calculate the sha256 hash of given filename */
2740+PHP_FUNCTION(sha256_file)
2741+{
2742+ char *arg;
2743+ int arg_len;
2744+ zend_bool raw_output = 0;
2745+ char sha256str[65];
2746+ unsigned char buf[1024];
2747+ unsigned char digest[32];
2748+ PHP_SHA256_CTX context;
2749+ int n;
2750+ php_stream *stream;
2751+
2752+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2753+ return;
2754+ }
2755+
2756+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
2757+ if (!stream) {
2758+ RETURN_FALSE;
2759+ }
2760+
2761+ PHP_SHA256Init(&context);
2762+
2763+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
2764+ PHP_SHA256Update(&context, buf, n);
2765+ }
2766+
2767+ PHP_SHA256Final(digest, &context);
2768+
2769+ php_stream_close(stream);
2770+
2771+ if (n<0) {
2772+ RETURN_FALSE;
2773+ }
2774+
2775+ if (raw_output) {
2776+ RETURN_STRINGL(digest, 32, 1);
2777+ } else {
2778+ make_sha256_digest(sha256str, digest);
2779+ RETVAL_STRING(sha256str, 1);
2780+ }
2781+}
2782+/* }}} */
2783+
2784+
2785+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2786+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2787+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2788+
2789+static unsigned char PADDING[64] =
2790+{
2791+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2792+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2793+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2794+};
2795+
2796+/* F, G, H and I are basic SHA256 functions.
2797+ */
2798+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2799+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2800+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2801+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2802+
2803+/* ROTATE_RIGHT rotates x right n bits.
2804+ */
2805+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2806+
2807+/* W[i]
2808+ */
2809+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2810+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2811+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2812+
2813+/* ROUND function of sha256
2814+ */
2815+
2816+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2817+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2818+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2819+ (d) += t1; \
2820+ }
2821+
2822+
2823+/* {{{ PHP_SHA256Init
2824+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2825+ */
2826+static void PHP_SHA256Init(PHP_SHA256_CTX * context)
2827+{
2828+ context->count[0] = context->count[1] = 0;
2829+ /* Load magic initialization constants.
2830+ */
2831+ context->state[0] = 0x6a09e667;
2832+ context->state[1] = 0xbb67ae85;
2833+ context->state[2] = 0x3c6ef372;
2834+ context->state[3] = 0xa54ff53a;
2835+ context->state[4] = 0x510e527f;
2836+ context->state[5] = 0x9b05688c;
2837+ context->state[6] = 0x1f83d9ab;
2838+ context->state[7] = 0x5be0cd19;
2839+}
2840+/* }}} */
2841+
2842+/* {{{ PHP_SHA256Update
2843+ SHA256 block update operation. Continues an SHA256 message-digest
2844+ operation, processing another message block, and updating the
2845+ context.
2846+ */
2847+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2848+ unsigned int inputLen)
2849+{
2850+ unsigned int i, index, partLen;
2851+
2852+ /* Compute number of bytes mod 64 */
2853+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2854+
2855+ /* Update number of bits */
2856+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2857+ < ((php_uint32) inputLen << 3))
2858+ context->count[1]++;
2859+ context->count[1] += ((php_uint32) inputLen >> 29);
2860+
2861+ partLen = 64 - index;
2862+
2863+ /* Transform as many times as possible.
2864+ */
2865+ if (inputLen >= partLen) {
2866+ memcpy
2867+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2868+ SHA256Transform(context->state, context->buffer);
2869+
2870+ for (i = partLen; i + 63 < inputLen; i += 64)
2871+ SHA256Transform(context->state, &input[i]);
2872+
2873+ index = 0;
2874+ } else
2875+ i = 0;
2876+
2877+ /* Buffer remaining input */
2878+ memcpy
2879+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2880+ inputLen - i);
2881+}
2882+/* }}} */
2883+
2884+/* {{{ PHP_SHA256Final
2885+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2886+ the message digest and zeroizing the context.
2887+ */
2888+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2889+{
2890+ unsigned char bits[8];
2891+ unsigned int index, padLen;
2892+
2893+ /* Save number of bits */
2894+ bits[7] = context->count[0] & 0xFF;
2895+ bits[6] = (context->count[0] >> 8) & 0xFF;
2896+ bits[5] = (context->count[0] >> 16) & 0xFF;
2897+ bits[4] = (context->count[0] >> 24) & 0xFF;
2898+ bits[3] = context->count[1] & 0xFF;
2899+ bits[2] = (context->count[1] >> 8) & 0xFF;
2900+ bits[1] = (context->count[1] >> 16) & 0xFF;
2901+ bits[0] = (context->count[1] >> 24) & 0xFF;
2902+
2903+ /* Pad out to 56 mod 64.
2904+ */
2905+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2906+ padLen = (index < 56) ? (56 - index) : (120 - index);
2907+ PHP_SHA256Update(context, PADDING, padLen);
2908+
2909+ /* Append length (before padding) */
2910+ PHP_SHA256Update(context, bits, 8);
2911+
2912+ /* Store state in digest */
2913+ SHA256Encode(digest, context->state, 32);
2914+
2915+ /* Zeroize sensitive information.
2916+ */
2917+ memset((unsigned char*) context, 0, sizeof(*context));
2918+}
2919+/* }}} */
2920+
2921+/* {{{ SHA256Transform
2922+ * SHA256 basic transformation. Transforms state based on block.
2923+ */
2924+static void SHA256Transform(state, block)
2925+php_uint32 state[8];
2926+const unsigned char block[64];
2927+{
2928+ php_uint32 a = state[0], b = state[1], c = state[2];
2929+ php_uint32 d = state[3], e = state[4], f = state[5];
2930+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2931+
2932+ SHA256Decode(x, block, 64);
2933+
2934+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2935+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2936+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2937+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2938+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2939+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2940+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2941+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2942+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2943+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2944+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2945+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2946+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2947+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2948+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2949+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2950+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2951+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2952+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2953+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2954+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2955+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2956+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2957+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2958+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2959+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2960+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2961+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2962+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2963+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2964+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2965+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2966+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2967+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2968+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2969+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2970+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2971+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2972+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2973+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2974+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2975+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2976+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2977+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2978+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2979+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2980+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2981+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2982+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2983+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2984+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2985+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2986+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2987+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2988+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2989+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2990+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2991+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2992+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2993+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2994+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2995+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2996+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2997+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2998+
2999+ state[0] += a;
3000+ state[1] += b;
3001+ state[2] += c;
3002+ state[3] += d;
3003+ state[4] += e;
3004+ state[5] += f;
3005+ state[6] += g;
3006+ state[7] += h;
3007+
3008+ /* Zeroize sensitive information. */
3009+ memset((unsigned char*) x, 0, sizeof(x));
3010+}
3011+/* }}} */
3012+
3013+/* {{{ SHA256Encode
3014+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
3015+ a multiple of 4.
3016+ */
3017+static void SHA256Encode(output, input, len)
3018+unsigned char *output;
3019+php_uint32 *input;
3020+unsigned int len;
3021+{
3022+ unsigned int i, j;
3023+
3024+ for (i = 0, j = 0; j < len; i++, j += 4) {
3025+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
3026+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
3027+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
3028+ output[j + 3] = (unsigned char) (input[i] & 0xff);
3029+ }
3030+}
3031+/* }}} */
3032+
3033+/* {{{ SHA256Decode
3034+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
3035+ a multiple of 4.
3036+ */
3037+static void SHA256Decode(output, input, len)
3038+php_uint32 *output;
3039+const unsigned char *input;
3040+unsigned int len;
3041+{
3042+ unsigned int i, j;
3043+
3044+ for (i = 0, j = 0; j < len; i++, j += 4)
3045+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
3046+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
3047+}
3048+/* }}} */
3049+
3050+/*
3051+ * Local variables:
3052+ * tab-width: 4
3053+ * c-basic-offset: 4
3054+ * End:
3055+ * vim600: sw=4 ts=4 fdm=marker
3056+ * vim<600: sw=4 ts=4
3057+ */
3058diff -Nura php-5.1.4/ext/standard/sha256.h hardening-patch-5.1.4-0.4.13/ext/standard/sha256.h
3059--- php-5.1.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
3060+++ hardening-patch-5.1.4-0.4.13/ext/standard/sha256.h 2006-08-07 11:04:07.000000000 +0200
3061@@ -0,0 +1,40 @@
3062+/*
3063+ +----------------------------------------------------------------------+
3064+ | PHP Version 5 |
3065+ +----------------------------------------------------------------------+
3066+ | Copyright (c) 1997-2004 The PHP Group |
3067+ +----------------------------------------------------------------------+
3068+ | This source file is subject to version 3.0 of the PHP license, |
3069+ | that is bundled with this package in the file LICENSE, and is |
3070+ | available through the world-wide-web at the following url: |
3071+ | http://www.php.net/license/3_0.txt. |
3072+ | If you did not receive a copy of the PHP license and are unable to |
3073+ | obtain it through the world-wide-web, please send a note to |
3074+ | license@php.net so we can mail you a copy immediately. |
3075+ +----------------------------------------------------------------------+
3076+ | Author: Stefan Esser <sesser@php.net> |
3077+ +----------------------------------------------------------------------+
3078+*/
3079+
3080+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
3081+
3082+#ifndef SHA256_H
3083+#define SHA256_H
3084+
3085+#include "ext/standard/basic_functions.h"
3086+
3087+/* SHA1 context. */
3088+typedef struct {
3089+ php_uint32 state[8]; /* state (ABCD) */
3090+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
3091+ unsigned char buffer[64]; /* input buffer */
3092+} PHP_SHA256_CTX;
3093+
3094+static void PHP_SHA256Init(PHP_SHA256_CTX *);
3095+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
3096+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
3097+
3098+PHP_FUNCTION(sha256);
3099+PHP_FUNCTION(sha256_file);
3100+
3101+#endif
3102diff -Nura php-5.1.4/ext/standard/string.c hardening-patch-5.1.4-0.4.13/ext/standard/string.c
3103--- php-5.1.4/ext/standard/string.c 2006-04-25 14:48:41.000000000 +0200
3104+++ hardening-patch-5.1.4-0.4.13/ext/standard/string.c 2006-08-07 11:04:07.000000000 +0200
3105@@ -632,7 +632,8 @@
3106 {
3107 const char *text, *breakchar = "\n";
3108 char *newtext;
3109- int textlen, breakcharlen = 1, newtextlen, alloced, chk;
3110+ int textlen, breakcharlen = 1, newtextlen, chk;
3111+ size_t alloced;
3112 long current = 0, laststart = 0, lastspace = 0;
3113 long linelength = 75;
3114 zend_bool docut = 0;
3115@@ -4194,7 +4195,7 @@
3116 zval **input_str; /* Input string */
3117 zval **mult; /* Multiplier */
3118 char *result; /* Resulting string */
3119- int result_len; /* Length of the resulting string */
3120+ size_t result_len; /* Length of the resulting string */
3121
3122 if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) {
3123 WRONG_PARAM_COUNT;
3124@@ -4219,11 +4220,7 @@
3125
3126 /* Initialize the result string */
3127 result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult);
3128- if (result_len < 1 || result_len > 2147483647) {
3129- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes");
3130- RETURN_FALSE;
3131- }
3132- result = (char *)emalloc(result_len + 1);
3133+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1);
3134
3135 /* Heavy optimization for situations where input string is 1 byte long */
3136 if (Z_STRLEN_PP(input_str) == 1) {
3137diff -Nura php-5.1.4/ext/standard/syslog.c hardening-patch-5.1.4-0.4.13/ext/standard/syslog.c
3138--- php-5.1.4/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100
3139+++ hardening-patch-5.1.4-0.4.13/ext/standard/syslog.c 2006-08-07 11:04:07.000000000 +0200
3140@@ -42,6 +42,7 @@
3141 */
3142 PHP_MINIT_FUNCTION(syslog)
3143 {
3144+#if !HARDENING_PATCH
3145 /* error levels */
3146 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
3147 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
3148@@ -97,6 +98,7 @@
3149 /* AIX doesn't have LOG_PERROR */
3150 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
3151 #endif
3152+#endif
3153 BG(syslog_device)=NULL;
3154
3155 return SUCCESS;
3156diff -Nura php-5.1.4/ext/varfilter/config.m4 hardening-patch-5.1.4-0.4.13/ext/varfilter/config.m4
3157--- php-5.1.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
3158+++ hardening-patch-5.1.4-0.4.13/ext/varfilter/config.m4 2006-08-07 11:04:07.000000000 +0200
3159@@ -0,0 +1,11 @@
3160+dnl
3161+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
3162+dnl
3163+
3164+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
3165+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
3166+
3167+if test "$PHP_VARFILTER" != "no"; then
3168+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
3169+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
3170+fi
3171diff -Nura php-5.1.4/ext/varfilter/CREDITS hardening-patch-5.1.4-0.4.13/ext/varfilter/CREDITS
3172--- php-5.1.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
3173+++ hardening-patch-5.1.4-0.4.13/ext/varfilter/CREDITS 2006-08-07 11:04:07.000000000 +0200
3174@@ -0,0 +1,2 @@
3175+varfilter
3176+Stefan Esser
3177\ Kein Zeilenumbruch am Dateiende.
3178diff -Nura php-5.1.4/ext/varfilter/php_varfilter.h hardening-patch-5.1.4-0.4.13/ext/varfilter/php_varfilter.h
3179--- php-5.1.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
3180+++ hardening-patch-5.1.4-0.4.13/ext/varfilter/php_varfilter.h 2006-08-07 11:04:07.000000000 +0200
3181@@ -0,0 +1,144 @@
3182+/*
3183+ +----------------------------------------------------------------------+
3184+ | Hardened-PHP Project's varfilter extension |
3185+ +----------------------------------------------------------------------+
3186+ | Copyright (c) 2004-2005 Stefan Esser |
3187+ +----------------------------------------------------------------------+
3188+ | This source file is subject to version 2.02 of the PHP license, |
3189+ | that is bundled with this package in the file LICENSE, and is |
3190+ | available at through the world-wide-web at |
3191+ | http://www.php.net/license/2_02.txt. |
3192+ | If you did not receive a copy of the PHP license and are unable to |
3193+ | obtain it through the world-wide-web, please send a note to |
3194+ | license@php.net so we can mail you a copy immediately. |
3195+ +----------------------------------------------------------------------+
3196+ | Author: Stefan Esser <sesser@hardened-php.net> |
3197+ +----------------------------------------------------------------------+
3198+
3199+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
3200+*/
3201+
3202+#ifndef PHP_VARFILTER_H
3203+#define PHP_VARFILTER_H
3204+
3205+extern zend_module_entry varfilter_module_entry;
3206+#define phpext_varfilter_ptr &varfilter_module_entry
3207+
3208+#ifdef PHP_WIN32
3209+#define PHP_VARFILTER_API __declspec(dllexport)
3210+#else
3211+#define PHP_VARFILTER_API
3212+#endif
3213+
3214+#ifdef ZTS
3215+#include "TSRM.h"
3216+#endif
3217+
3218+#include "SAPI.h"
3219+
3220+#include "php_variables.h"
3221+
3222+#ifdef ZEND_ENGINE_2
3223+#define HASH_HTTP_GET_VARS 0x2095733f
3224+#define HASH_HTTP_POST_VARS 0xbfee1265
3225+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
3226+#define HASH_HTTP_ENV_VARS 0x1fe186a8
3227+#define HASH_HTTP_SERVER_VARS 0xc987afd6
3228+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
3229+#define HASH_HTTP_POST_FILES 0x98eb1ddc
3230+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
3231+#else
3232+#define HASH_HTTP_GET_VARS 0x8d8645bd
3233+#define HASH_HTTP_POST_VARS 0x7c699bf3
3234+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
3235+#define HASH_HTTP_ENV_VARS 0x84da3016
3236+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
3237+#define HASH_HTTP_SESSION_VARS 0x322906f5
3238+#define HASH_HTTP_POST_FILES 0xe4e4ce70
3239+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
3240+#endif
3241+
3242+PHP_MINIT_FUNCTION(varfilter);
3243+PHP_MSHUTDOWN_FUNCTION(varfilter);
3244+PHP_RINIT_FUNCTION(varfilter);
3245+PHP_RSHUTDOWN_FUNCTION(varfilter);
3246+PHP_MINFO_FUNCTION(varfilter);
3247+
3248+
3249+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3250+/* request variables */
3251+ long max_request_variables;
3252+ long cur_request_variables;
3253+ long max_varname_length;
3254+ long max_totalname_length;
3255+ long max_value_length;
3256+ long max_array_depth;
3257+ long max_array_index_length;
3258+ zend_bool disallow_nul;
3259+/* cookie variables */
3260+ long max_cookie_vars;
3261+ long cur_cookie_vars;
3262+ long max_cookie_name_length;
3263+ long max_cookie_totalname_length;
3264+ long max_cookie_value_length;
3265+ long max_cookie_array_depth;
3266+ long max_cookie_array_index_length;
3267+ zend_bool disallow_cookie_nul;
3268+/* get variables */
3269+ long max_get_vars;
3270+ long cur_get_vars;
3271+ long max_get_name_length;
3272+ long max_get_totalname_length;
3273+ long max_get_value_length;
3274+ long max_get_array_depth;
3275+ long max_get_array_index_length;
3276+ zend_bool disallow_get_nul;
3277+/* post variables */
3278+ long max_post_vars;
3279+ long cur_post_vars;
3280+ long max_post_name_length;
3281+ long max_post_totalname_length;
3282+ long max_post_value_length;
3283+ long max_post_array_depth;
3284+ long max_post_array_index_length;
3285+ zend_bool disallow_post_nul;
3286+/* fileupload */
3287+ long max_uploads;
3288+ long cur_uploads;
3289+ zend_bool disallow_elf_files;
3290+ char *verification_script;
3291+
3292+ zend_bool no_more_variables;
3293+ zend_bool no_more_get_variables;
3294+ zend_bool no_more_post_variables;
3295+ zend_bool no_more_cookie_variables;
3296+ zend_bool no_more_uploads;
3297+
3298+ZEND_END_MODULE_GLOBALS(varfilter)
3299+
3300+
3301+#ifdef ZTS
3302+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3303+#else
3304+#define VARFILTER_G(v) (varfilter_globals.v)
3305+#endif
3306+
3307+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3308+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3309+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3310+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3311+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3312+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3313+
3314+
3315+
3316+#endif /* PHP_VARFILTER_H */
3317+
3318+
3319+/*
3320+ * Local variables:
3321+ * tab-width: 4
3322+ * c-basic-offset: 4
3323+ * indent-tabs-mode: t
3324+ * End:
3325+ */
3326diff -Nura php-5.1.4/ext/varfilter/varfilter.c hardening-patch-5.1.4-0.4.13/ext/varfilter/varfilter.c
3327--- php-5.1.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3328+++ hardening-patch-5.1.4-0.4.13/ext/varfilter/varfilter.c 2006-08-07 11:05:27.000000000 +0200
3329@@ -0,0 +1,915 @@
3330+/*
3331+ +----------------------------------------------------------------------+
3332+ | Hardened-PHP Project's varfilter extension |
3333+ +----------------------------------------------------------------------+
3334+ | Copyright (c) 2004-2005 Stefan Esser |
3335+ +----------------------------------------------------------------------+
3336+ | This source file is subject to version 2.02 of the PHP license, |
3337+ | that is bundled with this package in the file LICENSE, and is |
3338+ | available at through the world-wide-web at |
3339+ | http://www.php.net/license/2_02.txt. |
3340+ | If you did not receive a copy of the PHP license and are unable to |
3341+ | obtain it through the world-wide-web, please send a note to |
3342+ | license@php.net so we can mail you a copy immediately. |
3343+ +----------------------------------------------------------------------+
3344+ | Author: Stefan Esser <sesser@hardened-php.net> |
3345+ +----------------------------------------------------------------------+
3346+
3347+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3348+*/
3349+
3350+#ifdef HAVE_CONFIG_H
3351+#include "config.h"
3352+#endif
3353+
3354+#include "php.h"
3355+#include "php_ini.h"
3356+#include "ext/standard/info.h"
3357+#include "php_varfilter.h"
3358+#include "hardening_patch.h"
3359+
3360+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3361+
3362+/* True global resources - no need for thread safety here */
3363+static int le_varfilter;
3364+
3365+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3366+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3367+static zend_bool hooked = 0;
3368+
3369+/* {{{ varfilter_module_entry
3370+ */
3371+zend_module_entry varfilter_module_entry = {
3372+#if ZEND_MODULE_API_NO >= 20010901
3373+ STANDARD_MODULE_HEADER,
3374+#endif
3375+ "varfilter",
3376+ NULL,
3377+ PHP_MINIT(varfilter),
3378+ PHP_MSHUTDOWN(varfilter),
3379+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3380+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3381+ PHP_MINFO(varfilter),
3382+#if ZEND_MODULE_API_NO >= 20010901
3383+ "0.4.13", /* Replace with version number for your extension */
3384+#endif
3385+ STANDARD_MODULE_PROPERTIES
3386+};
3387+/* }}} */
3388+
3389+#ifdef COMPILE_DL_VARFILTER
3390+ZEND_GET_MODULE(varfilter)
3391+#endif
3392+
3393+/* {{{ PHP_INI
3394+ */
3395+PHP_INI_BEGIN()
3396+ /* for backward compatibility */
3397+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3398+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3399+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3400+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3401+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3402+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3403+
3404+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3405+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3406+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3407+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3408+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3409+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3410+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3411+
3412+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3413+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3414+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3415+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3416+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3417+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
3418+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3419+
3420+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3421+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3422+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3423+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3424+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3425+ STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
3426+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3427+
3428+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3429+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3430+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3431+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3432+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3433+ STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
3434+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3435+
3436+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3437+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3438+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3439+
3440+
3441+PHP_INI_END()
3442+/* }}} */
3443+
3444+/* {{{ php_varfilter_init_globals
3445+ */
3446+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3447+{
3448+ varfilter_globals->max_request_variables = 200;
3449+ varfilter_globals->max_varname_length = 64;
3450+ varfilter_globals->max_value_length = 10000;
3451+ varfilter_globals->max_array_depth = 100;
3452+ varfilter_globals->max_totalname_length = 256;
3453+ varfilter_globals->max_array_index_length = 64;
3454+ varfilter_globals->disallow_nul = 1;
3455+
3456+ varfilter_globals->max_cookie_vars = 100;
3457+ varfilter_globals->max_cookie_name_length = 64;
3458+ varfilter_globals->max_cookie_totalname_length = 256;
3459+ varfilter_globals->max_cookie_value_length = 10000;
3460+ varfilter_globals->max_cookie_array_depth = 100;
3461+ varfilter_globals->max_cookie_array_index_length = 64;
3462+ varfilter_globals->disallow_cookie_nul = 1;
3463+
3464+ varfilter_globals->max_get_vars = 100;
3465+ varfilter_globals->max_get_name_length = 64;
3466+ varfilter_globals->max_get_totalname_length = 256;
3467+ varfilter_globals->max_get_value_length = 512;
3468+ varfilter_globals->max_get_array_depth = 50;
3469+ varfilter_globals->max_get_array_index_length = 64;
3470+ varfilter_globals->disallow_get_nul = 1;
3471+
3472+ varfilter_globals->max_post_vars = 200;
3473+ varfilter_globals->max_post_name_length = 64;
3474+ varfilter_globals->max_post_totalname_length = 256;
3475+ varfilter_globals->max_post_value_length = 65000;
3476+ varfilter_globals->max_post_array_depth = 100;
3477+ varfilter_globals->max_post_array_index_length = 64;
3478+ varfilter_globals->disallow_post_nul = 1;
3479+
3480+ varfilter_globals->max_uploads = 25;
3481+ varfilter_globals->disallow_elf_files = 1;
3482+ varfilter_globals->verification_script = NULL;
3483+
3484+ varfilter_globals->no_more_variables = 0;
3485+ varfilter_globals->no_more_get_variables = 0;
3486+ varfilter_globals->no_more_post_variables = 0;
3487+ varfilter_globals->no_more_cookie_variables = 0;
3488+ varfilter_globals->no_more_uploads = 0;
3489+
3490+ varfilter_globals->cur_request_variables = 0;
3491+ varfilter_globals->cur_get_vars = 0;
3492+ varfilter_globals->cur_post_vars = 0;
3493+ varfilter_globals->cur_cookie_vars = 0;
3494+
3495+ varfilter_globals->cur_uploads = 0;
3496+
3497+}
3498+/* }}} */
3499+
3500+
3501+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3502+{
3503+ HashTable *svars;
3504+ int retval, failure=0;
3505+
3506+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3507+
3508+ svars = Z_ARRVAL_P(track_vars_array);
3509+
3510+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3511+ if (retval == SUCCESS) failure = 1;
3512+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3513+ if (retval == SUCCESS) failure = 1;
3514+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3515+ if (retval == SUCCESS) failure = 1;
3516+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3517+ if (retval == SUCCESS) failure = 1;
3518+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3519+ if (retval == SUCCESS) failure = 1;
3520+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3521+ if (retval == SUCCESS) failure = 1;
3522+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3523+ if (retval == SUCCESS) failure = 1;
3524+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX);
3525+ if (retval == SUCCESS) failure = 1;
3526+
3527+ if (failure) {
3528+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3529+ }
3530+}
3531+
3532+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3533+{
3534+ int retval = SAPI_HEADER_ADD, i;
3535+ char *tmp;
3536+
3537+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3538+
3539+ tmp = sapi_header->header;
3540+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3541+ if (tmp[0] == 0) {
3542+ char *fname = get_active_function_name(TSRMLS_C);
3543+
3544+ if (!fname) {
3545+ fname = "unknown";
3546+ }
3547+
3548+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3549+ sapi_header->header_len = i;
3550+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3551+ char *fname = get_active_function_name(TSRMLS_C);
3552+
3553+ if (!fname) {
3554+ fname = "unknown";
3555+ }
3556+
3557+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3558+ sapi_header->header_len = i;
3559+ tmp[0] = 0;
3560+ }
3561+ }
3562+ }
3563+
3564+ if (orig_header_handler) {
3565+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3566+ }
3567+
3568+ return retval;
3569+}
3570+
3571+/* {{{ PHP_MINIT_FUNCTION
3572+ */
3573+PHP_MINIT_FUNCTION(varfilter)
3574+{
3575+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3576+ REGISTER_INI_ENTRIES();
3577+
3578+ if (!hooked) {
3579+ void *temp;
3580+ hooked = 1;
3581+
3582+ temp = (void *)sapi_module.register_server_variables;
3583+ if (temp != varfilter_register_server_variables) {
3584+ orig_register_server_variables = temp;
3585+ }
3586+ temp = (void *)sapi_module.header_handler;
3587+ if (temp != varfilter_header_handler) {
3588+ orig_header_handler = temp;
3589+ }
3590+ }
3591+
3592+ sapi_register_input_filter(varfilter_input_filter);
3593+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3594+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3595+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3596+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3597+
3598+ sapi_module.header_handler = varfilter_header_handler;
3599+ sapi_module.register_server_variables = varfilter_register_server_variables;
3600+
3601+
3602+ return SUCCESS;
3603+}
3604+/* }}} */
3605+
3606+/* {{{ PHP_MSHUTDOWN_FUNCTION
3607+ */
3608+PHP_MSHUTDOWN_FUNCTION(varfilter)
3609+{
3610+ UNREGISTER_INI_ENTRIES();
3611+
3612+ return SUCCESS;
3613+}
3614+/* }}} */
3615+
3616+/* Remove if there's nothing to do at request start */
3617+/* {{{ PHP_RINIT_FUNCTION
3618+ */
3619+PHP_RINIT_FUNCTION(varfilter)
3620+{
3621+ VARFILTER_G(cur_request_variables) = 0;
3622+ VARFILTER_G(cur_get_vars) = 0;
3623+ VARFILTER_G(cur_post_vars) = 0;
3624+ VARFILTER_G(cur_cookie_vars) = 0;
3625+
3626+ VARFILTER_G(cur_uploads) = 0;
3627+
3628+ VARFILTER_G(no_more_variables) = 0;
3629+ VARFILTER_G(no_more_get_variables) = 0;
3630+ VARFILTER_G(no_more_post_variables) = 0;
3631+ VARFILTER_G(no_more_cookie_variables) = 0;
3632+ VARFILTER_G(no_more_uploads) = 0;
3633+
3634+ return SUCCESS;
3635+}
3636+/* }}} */
3637+
3638+/* Remove if there's nothing to do at request end */
3639+/* {{{ PHP_RSHUTDOWN_FUNCTION
3640+ */
3641+PHP_RSHUTDOWN_FUNCTION(varfilter)
3642+{
3643+ return SUCCESS;
3644+}
3645+/* }}} */
3646+
3647+/* {{{ PHP_MINFO_FUNCTION
3648+ */
3649+PHP_MINFO_FUNCTION(varfilter)
3650+{
3651+ php_info_print_table_start();
3652+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3653+ php_info_print_table_end();
3654+
3655+ DISPLAY_INI_ENTRIES();
3656+}
3657+/* }}} */
3658+
3659+/* {{{ normalize_varname
3660+ */
3661+static void normalize_varname(char *varname)
3662+{
3663+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3664+
3665+ /* overjump leading space */
3666+ while (*s == ' ') {
3667+ s++;
3668+ }
3669+
3670+ /* and remove it */
3671+ if (s != varname) {
3672+ memmove(varname, s, strlen(s)+1);
3673+ }
3674+
3675+ for (p=varname; *p && *p != '['; p++) {
3676+ switch(*p) {
3677+ case ' ':
3678+ case '.':
3679+ *p='_';
3680+ break;
3681+ }
3682+ }
3683+
3684+ /* find index */
3685+ index = strchr(varname, '[');
3686+ if (index) {
3687+ index++;
3688+ s=index;
3689+ } else {
3690+ return;
3691+ }
3692+
3693+ /* done? */
3694+ while (index) {
3695+
3696+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3697+ index++;
3698+ }
3699+ indexend = strchr(index, ']');
3700+ indexend = indexend ? indexend + 1 : index + strlen(index);
3701+
3702+ if (s != index) {
3703+ memmove(s, index, strlen(index)+1);
3704+ s += indexend-index;
3705+ } else {
3706+ s = indexend;
3707+ }
3708+
3709+ if (*s == '[') {
3710+ s++;
3711+ index = s;
3712+ } else {
3713+ index = NULL;
3714+ }
3715+ }
3716+ *s++='\0';
3717+}
3718+/* }}} */
3719+
3720+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3721+ */
3722+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3723+{
3724+ char *index, *prev_index = NULL, *var;
3725+ unsigned int var_len, total_len, depth = 0;
3726+
3727+ var = estrdup(varname);
3728+
3729+ /* Normalize the variable name */
3730+ normalize_varname(var);
3731+
3732+ /* Find length of variable name */
3733+ index = strchr(var, '[');
3734+ total_len = strlen(var);
3735+ var_len = index ? index-var : total_len;
3736+
3737+ /* Drop this variable if it exceeds the varname/total length limit */
3738+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3739+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3740+ goto return_failure;
3741+ }
3742+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3743+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3744+ goto return_failure;
3745+ }
3746+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3747+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3748+
3749+ goto return_failure;
3750+ }
3751+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3752+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3753+ goto return_failure;
3754+ }
3755+
3756+ /* Find out array depth */
3757+ while (index) {
3758+ unsigned int index_length;
3759+
3760+ depth++;
3761+ index = strchr(index+1, '[');
3762+
3763+ if (prev_index) {
3764+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3765+
3766+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3767+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3768+ goto return_failure;
3769+ }
3770+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3771+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3772+ goto return_failure;
3773+ }
3774+ prev_index = index;
3775+ }
3776+
3777+ }
3778+
3779+ /* Drop this variable if it exceeds the array depth limit */
3780+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3781+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3782+ goto return_failure;
3783+ }
3784+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3785+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3786+ goto return_failure;
3787+ }
3788+
3789+
3790+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3791+ /* This is to protect several silly scripts that do globalizing themself */
3792+
3793+ switch (var_len) {
3794+ case 18:
3795+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3796+ break;
3797+ case 17:
3798+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3799+ break;
3800+ case 16:
3801+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3802+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3803+ break;
3804+ case 15:
3805+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3806+ break;
3807+ case 14:
3808+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3809+ break;
3810+ case 13:
3811+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3812+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3813+ break;
3814+ case 8:
3815+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3816+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3817+ break;
3818+ case 7:
3819+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3820+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3821+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3822+ break;
3823+ case 6:
3824+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3825+ break;
3826+ case 5:
3827+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3828+ break;
3829+ case 4:
3830+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3831+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3832+ break;
3833+ }
3834+
3835+ efree(var);
3836+ return SUCCESS;
3837+protected_varname2:
3838+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3839+return_failure:
3840+ efree(var);
3841+ return FAILURE;
3842+}
3843+/* }}} */
3844+
3845+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3846+ */
3847+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3848+{
3849+ /* Drop if no more variables flag is set */
3850+ if (VARFILTER_G(no_more_uploads)) {
3851+ return FAILURE;
3852+ }
3853+ /* Drop this fileupload if the limit is reached */
3854+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3855+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3856+ VARFILTER_G(no_more_uploads) = 1;
3857+ return FAILURE;
3858+ }
3859+
3860+ return SUCCESS;
3861+}
3862+/* }}} */
3863+
3864+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3865+ */
3866+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3867+{
3868+
3869+ if (VARFILTER_G(disallow_elf_files)) {
3870+
3871+ if (offset == 0 && buffer_len > 10) {
3872+
3873+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3874+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3875+ return FAILURE;
3876+ }
3877+ }
3878+
3879+ }
3880+
3881+ return SUCCESS;
3882+}
3883+/* }}} */
3884+
3885+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3886+ */
3887+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3888+{
3889+ int retval = SUCCESS;
3890+
3891+ if (VARFILTER_G(verification_script)) {
3892+ char cmd[8192];
3893+ FILE *in;
3894+ int first=1;
3895+
3896+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3897+
3898+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3899+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3900+ return FAILURE;
3901+ }
3902+
3903+ retval = FAILURE;
3904+
3905+ /* read and forget the result */
3906+ while (1) {
3907+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3908+ if (readbytes<=0) {
3909+ break;
3910+ }
3911+ if (first) {
3912+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3913+ first = 0;
3914+ }
3915+ }
3916+ pclose(in);
3917+ }
3918+
3919+ if (retval != SUCCESS) {
3920+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3921+ return FAILURE;
3922+ }
3923+
3924+ VARFILTER_G(cur_uploads)++;
3925+ return SUCCESS;
3926+}
3927+/* }}} */
3928+
3929+/* {{{ SAPI_INPUT_FILTER_FUNC
3930+ */
3931+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3932+{
3933+ char *index, *prev_index = NULL;
3934+ unsigned int var_len, total_len, depth = 0;
3935+
3936+ /* Drop this variable if the limit was reached */
3937+ switch (arg) {
3938+ case PARSE_GET:
3939+ if (VARFILTER_G(no_more_get_variables)) {
3940+ return 0;
3941+ }
3942+ break;
3943+ case PARSE_POST:
3944+ if (VARFILTER_G(no_more_post_variables)) {
3945+ return 0;
3946+ }
3947+ break;
3948+ case PARSE_COOKIE:
3949+ if (VARFILTER_G(no_more_cookie_variables)) {
3950+ return 0;
3951+ }
3952+ break;
3953+ default: /* we do not want to protect parse_str() and friends */
3954+ if (new_val_len) {
3955+ *new_val_len = val_len;
3956+ }
3957+ return 1;
3958+ }
3959+ if (VARFILTER_G(no_more_variables)) {
3960+ return 0;
3961+ }
3962+
3963+ /* Drop this variable if the limit is now reached */
3964+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3965+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3966+ VARFILTER_G(no_more_variables) = 1;
3967+ return 0;
3968+ }
3969+ switch (arg) {
3970+ case PARSE_GET:
3971+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3972+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3973+ VARFILTER_G(no_more_get_variables) = 1;
3974+ return 0;
3975+ }
3976+ break;
3977+ case PARSE_COOKIE:
3978+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3979+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3980+ VARFILTER_G(no_more_cookie_variables) = 1;
3981+ return 0;
3982+ }
3983+ break;
3984+ case PARSE_POST:
3985+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3986+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3987+ VARFILTER_G(no_more_post_variables) = 1;
3988+ return 0;
3989+ }
3990+ break;
3991+ }
3992+
3993+
3994+ /* Drop this variable if it exceeds the value length limit */
3995+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3996+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3997+ return 0;
3998+ }
3999+ switch (arg) {
4000+ case PARSE_GET:
4001+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
4002+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
4003+ return 0;
4004+ }
4005+ break;
4006+ case PARSE_COOKIE:
4007+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
4008+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
4009+ return 0;
4010+ }
4011+ break;
4012+ case PARSE_POST:
4013+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
4014+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
4015+ return 0;
4016+ }
4017+ break;
4018+ }
4019+
4020+ /* Normalize the variable name */
4021+ normalize_varname(var);
4022+
4023+ /* Find length of variable name */
4024+ index = strchr(var, '[');
4025+ total_len = strlen(var);
4026+ var_len = index ? index-var : total_len;
4027+
4028+ /* Drop this variable if it exceeds the varname/total length limit */
4029+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
4030+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
4031+ return 0;
4032+ }
4033+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
4034+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
4035+ return 0;
4036+ }
4037+ switch (arg) {
4038+ case PARSE_GET:
4039+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
4040+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
4041+ return 0;
4042+ }
4043+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
4044+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
4045+ return 0;
4046+ }
4047+ break;
4048+ case PARSE_COOKIE:
4049+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
4050+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
4051+ return 0;
4052+ }
4053+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
4054+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
4055+ return 0;
4056+ }
4057+ break;
4058+ case PARSE_POST:
4059+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
4060+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
4061+ return 0;
4062+ }
4063+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
4064+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
4065+ return 0;
4066+ }
4067+ break;
4068+ }
4069+
4070+ /* Find out array depth */
4071+ while (index) {
4072+ unsigned int index_length;
4073+
4074+ depth++;
4075+ index = strchr(index+1, '[');
4076+
4077+ if (prev_index) {
4078+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
4079+
4080+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
4081+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
4082+ return 0;
4083+ }
4084+ switch (arg) {
4085+ case PARSE_GET:
4086+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
4087+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
4088+ return 0;
4089+ }
4090+ break;
4091+ case PARSE_COOKIE:
4092+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
4093+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
4094+ return 0;
4095+ }
4096+ break;
4097+ case PARSE_POST:
4098+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
4099+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
4100+ return 0;
4101+ }
4102+ break;
4103+ }
4104+ prev_index = index;
4105+ }
4106+
4107+ }
4108+
4109+ /* Drop this variable if it exceeds the array depth limit */
4110+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
4111+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
4112+ return 0;
4113+ }
4114+ switch (arg) {
4115+ case PARSE_GET:
4116+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
4117+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
4118+ return 0;
4119+ }
4120+ break;
4121+ case PARSE_COOKIE:
4122+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
4123+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
4124+ return 0;
4125+ }
4126+ break;
4127+ case PARSE_POST:
4128+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
4129+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
4130+ return 0;
4131+ }
4132+ break;
4133+ }
4134+
4135+ /* Check if variable value is truncated by a \0 */
4136+
4137+ if (val && *val && val_len != strlen(*val)) {
4138+
4139+ if (VARFILTER_G(disallow_nul)) {
4140+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
4141+ return 0;
4142+ }
4143+ switch (arg) {
4144+ case PARSE_GET:
4145+ if (VARFILTER_G(disallow_get_nul)) {
4146+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
4147+ return 0;
4148+ }
4149+ break;
4150+ case PARSE_COOKIE:
4151+ if (VARFILTER_G(disallow_cookie_nul)) {
4152+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
4153+ return 0;
4154+ }
4155+ break;
4156+ case PARSE_POST:
4157+ if (VARFILTER_G(disallow_post_nul)) {
4158+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
4159+ return 0;
4160+ }
4161+ break;
4162+ }
4163+ }
4164+
4165+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
4166+ /* This is to protect several silly scripts that do globalizing themself */
4167+
4168+ switch (var_len) {
4169+ case 18:
4170+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
4171+ break;
4172+ case 17:
4173+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
4174+ break;
4175+ case 16:
4176+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
4177+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
4178+ break;
4179+ case 15:
4180+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
4181+ break;
4182+ case 14:
4183+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
4184+ break;
4185+ case 13:
4186+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
4187+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
4188+ break;
4189+ case 8:
4190+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
4191+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
4192+ break;
4193+ case 7:
4194+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
4195+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
4196+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
4197+ break;
4198+ case 6:
4199+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
4200+ break;
4201+ case 5:
4202+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
4203+ break;
4204+ case 4:
4205+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
4206+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
4207+ break;
4208+ }
4209+
4210+ /* Okay let PHP register this variable */
4211+ VARFILTER_G(cur_request_variables)++;
4212+ switch (arg) {
4213+ case PARSE_GET:
4214+ VARFILTER_G(cur_get_vars)++;
4215+ break;
4216+ case PARSE_COOKIE:
4217+ VARFILTER_G(cur_cookie_vars)++;
4218+ break;
4219+ case PARSE_POST:
4220+ VARFILTER_G(cur_post_vars)++;
4221+ break;
4222+ }
4223+
4224+ if (new_val_len) {
4225+ *new_val_len = val_len;
4226+ }
4227+
4228+ return 1;
4229+protected_varname:
4230+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
4231+ return 0;
4232+}
4233+/* }}} */
4234+
4235+/*
4236+ * Local variables:
4237+ * tab-width: 4
4238+ * c-basic-offset: 4
4239+ * End:
4240+ * vim600: noet sw=4 ts=4 fdm=marker
4241+ * vim<600: noet sw=4 ts=4
4242+ */
4243+
4244+
4245diff -Nura php-5.1.4/ext/wddx/wddx.c hardening-patch-5.1.4-0.4.13/ext/wddx/wddx.c
4246--- php-5.1.4/ext/wddx/wddx.c 2006-04-23 18:02:05.000000000 +0200
4247+++ hardening-patch-5.1.4-0.4.13/ext/wddx/wddx.c 2006-08-07 11:04:07.000000000 +0200
4248@@ -399,9 +399,9 @@
4249 break;
4250
4251 default:
4252- if (iscntrl((int)*(unsigned char *)p)) {
4253+ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) {
4254 FLUSH_BUF();
4255- sprintf(control_buf, WDDX_CHAR, *p);
4256+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p);
4257 php_wddx_add_chunk(packet, control_buf);
4258 } else
4259 buf[l++] = *p;
4260@@ -751,7 +751,7 @@
4261 } else if (!strcmp(name, EL_CHAR)) {
4262 int i;
4263
4264- for (i = 0; atts[i]; i++) {
4265+ if (atts) for (i = 0; atts[i]; i++) {
4266 if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
4267 char tmp_buf[2];
4268
4269@@ -771,7 +771,7 @@
4270 } else if (!strcmp(name, EL_BOOLEAN)) {
4271 int i;
4272
4273- for (i = 0; atts[i]; i++) {
4274+ if (atts) for (i = 0; atts[i]; i++) {
4275 if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
4276 ent.type = ST_BOOLEAN;
4277 SET_STACK_VARNAME;
4278@@ -812,7 +812,7 @@
4279 } else if (!strcmp(name, EL_VAR)) {
4280 int i;
4281
4282- for (i = 0; atts[i]; i++) {
4283+ if (atts) for (i = 0; atts[i]; i++) {
4284 if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
4285 char *decoded;
4286 int decoded_len;
4287@@ -829,7 +829,7 @@
4288 MAKE_STD_ZVAL(ent.data);
4289 array_init(ent.data);
4290
4291- for (i = 0; atts[i]; i++) {
4292+ if (atts) for (i = 0; atts[i]; i++) {
4293 if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
4294 zval *tmp;
4295 char *key;
4296@@ -869,7 +869,7 @@
4297 ent.varname = NULL;
4298 ent.data = NULL;
4299
4300- for (i = 0; atts[i]; i++) {
4301+ if (atts) for (i = 0; atts[i]; i++) {
4302 if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
4303 char *decoded;
4304 int decoded_len;
4305diff -Nura php-5.1.4/main/fopen_wrappers.c hardening-patch-5.1.4-0.4.13/main/fopen_wrappers.c
4306--- php-5.1.4/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100
4307+++ hardening-patch-5.1.4-0.4.13/main/fopen_wrappers.c 2006-08-07 11:04:07.000000000 +0200
4308@@ -114,14 +114,20 @@
4309 }
4310 }
4311
4312+ resolved_name_len = strlen(resolved_name);
4313 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
4314- resolved_name_len = strlen(resolved_name);
4315 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
4316 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
4317 resolved_name[++resolved_name_len] = '\0';
4318 }
4319 }
4320
4321+ if (resolved_name_len == resolved_basedir_len - 1) {
4322+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4323+ resolved_basedir_len--;
4324+ }
4325+ }
4326+
4327 /* Check the path */
4328 #if defined(PHP_WIN32) || defined(NETWARE)
4329 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4330@@ -154,6 +160,21 @@
4331 char *pathbuf;
4332 char *ptr;
4333 char *end;
4334+ char path_copy[MAXPATHLEN];
4335+ int path_len;
4336+
4337+ /* Special case path ends with a trailing slash */
4338+ path_len = strlen(path);
4339+ if (path_len >= MAXPATHLEN) {
4340+ errno = EPERM; /* we deny permission to open it */
4341+ return -1;
4342+ }
4343+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4344+ memcpy(path_copy, path, path_len+1);
4345+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4346+ path_copy[path_len] = '\0';
4347+ path = (const char *)&path_copy;
4348+ }
4349
4350 pathbuf = estrdup(PG(open_basedir));
4351
4352diff -Nura php-5.1.4/main/hardened_globals.h hardening-patch-5.1.4-0.4.13/main/hardened_globals.h
4353--- php-5.1.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4354+++ hardening-patch-5.1.4-0.4.13/main/hardened_globals.h 2006-08-07 11:04:07.000000000 +0200
4355@@ -0,0 +1,63 @@
4356+/*
4357+ +----------------------------------------------------------------------+
4358+ | Hardening-Patch for PHP |
4359+ +----------------------------------------------------------------------+
4360+ | Copyright (c) 2004-2005 Stefan Esser |
4361+ +----------------------------------------------------------------------+
4362+ | This source file is subject to version 2.02 of the PHP license, |
4363+ | that is bundled with this package in the file LICENSE, and is |
4364+ | available at through the world-wide-web at |
4365+ | http://www.php.net/license/2_02.txt. |
4366+ | If you did not receive a copy of the PHP license and are unable to |
4367+ | obtain it through the world-wide-web, please send a note to |
4368+ | license@php.net so we can mail you a copy immediately. |
4369+ +----------------------------------------------------------------------+
4370+ | Author: Stefan Esser <sesser@hardened-php.net> |
4371+ +----------------------------------------------------------------------+
4372+ */
4373+
4374+#ifndef HARDENED_GLOBALS_H
4375+#define HARDENED_GLOBALS_H
4376+
4377+typedef struct _hardened_globals hardened_globals_struct;
4378+
4379+#ifdef ZTS
4380+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4381+extern int hardened_globals_id;
4382+#else
4383+# define HG(v) (hardened_globals.v)
4384+extern struct _hardened_globals hardened_globals;
4385+#endif
4386+
4387+
4388+struct _hardened_globals {
4389+#if HARDENING_PATCH_MM_PROTECT
4390+ unsigned int canary_1;
4391+ unsigned int canary_2;
4392+#endif
4393+#if HARDENING_PATCH_LL_PROTECT
4394+ unsigned int canary_3;
4395+ unsigned int canary_4;
4396+ unsigned int ll_canary_inited;
4397+#endif
4398+ zend_bool hphp_sql_bailout_on_error;
4399+ zend_bool hphp_multiheader;
4400+ unsigned long hphp_mailprotect;
4401+ HashTable *eval_whitelist;
4402+ HashTable *eval_blacklist;
4403+ HashTable *func_whitelist;
4404+ HashTable *func_blacklist;
4405+ HashTable *include_whitelist;
4406+ HashTable *include_blacklist;
4407+ unsigned int dummy;
4408+};
4409+
4410+
4411+#endif /* HARDENED_GLOBALS_H */
4412+
4413+/*
4414+ * Local variables:
4415+ * tab-width: 4
4416+ * c-basic-offset: 4
4417+ * End:
4418+ */
4419diff -Nura php-5.1.4/main/hardening_patch.c hardening-patch-5.1.4-0.4.13/main/hardening_patch.c
4420--- php-5.1.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4421+++ hardening-patch-5.1.4-0.4.13/main/hardening_patch.c 2006-08-07 11:04:07.000000000 +0200
4422@@ -0,0 +1,430 @@
4423+/*
4424+ +----------------------------------------------------------------------+
4425+ | Hardening Patch for PHP |
4426+ +----------------------------------------------------------------------+
4427+ | Copyright (c) 2004-2005 Stefan Esser |
4428+ +----------------------------------------------------------------------+
4429+ | This source file is subject to version 2.02 of the PHP license, |
4430+ | that is bundled with this package in the file LICENSE, and is |
4431+ | available at through the world-wide-web at |
4432+ | http://www.php.net/license/2_02.txt. |
4433+ | If you did not receive a copy of the PHP license and are unable to |
4434+ | obtain it through the world-wide-web, please send a note to |
4435+ | license@php.net so we can mail you a copy immediately. |
4436+ +----------------------------------------------------------------------+
4437+ | Author: Stefan Esser <sesser@hardened-php.net> |
4438+ +----------------------------------------------------------------------+
4439+ */
4440+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4441+
4442+#include "php.h"
4443+
4444+#include <stdio.h>
4445+#include <stdlib.h>
4446+
4447+#if HAVE_UNISTD_H
4448+#include <unistd.h>
4449+#endif
4450+#include "SAPI.h"
4451+#include "php_globals.h"
4452+
4453+#if HARDENING_PATCH
4454+
4455+#ifdef HAVE_SYS_SOCKET_H
4456+#include <sys/socket.h>
4457+#endif
4458+
4459+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4460+#undef AF_UNIX
4461+#endif
4462+
4463+#if defined(AF_UNIX)
4464+#include <sys/un.h>
4465+#endif
4466+
4467+#define SYSLOG_PATH "/dev/log"
4468+
4469+#include "snprintf.h"
4470+
4471+#include "hardening_patch.h"
4472+
4473+#ifdef ZTS
4474+#include "hardened_globals.h"
4475+int hardened_globals_id;
4476+#else
4477+struct _hardened_globals hardened_globals;
4478+#endif
4479+
4480+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4481+{
4482+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4483+}
4484+
4485+
4486+PHPAPI void hardened_startup()
4487+{
4488+#ifdef ZTS
4489+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4490+#else
4491+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4492+#endif
4493+}
4494+
4495+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4496+{
4497+ HG(canary_1) = php_canary();
4498+ HG(canary_2) = php_canary();
4499+}
4500+
4501+char *loglevel2string(int loglevel)
4502+{
4503+ switch (loglevel) {
4504+ case S_FILES:
4505+ return "FILES";
4506+ case S_INCLUDE:
4507+ return "INCLUDE";
4508+ case S_MEMORY:
4509+ return "MEMORY";
4510+ case S_MISC:
4511+ return "MISC";
4512+ case S_SQL:
4513+ return "SQL";
4514+ case S_EXECUTOR:
4515+ return "EXECUTOR";
4516+ case S_VARS:
4517+ return "VARS";
4518+ default:
4519+ return "UNKNOWN";
4520+ }
4521+}
4522+
4523+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4524+{
4525+#if defined(AF_UNIX)
4526+ int s, r, i=0;
4527+ struct sockaddr_un saun;
4528+ char buf[4096+64];
4529+ char error[4096+100];
4530+ char *ip_address;
4531+ char *fname;
4532+ int lineno;
4533+ va_list ap;
4534+ TSRMLS_FETCH();
4535+
4536+ if (EG(hphp_log_use_x_forwarded_for)) {
4537+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4538+ if (ip_address == NULL) {
4539+ ip_address = "X-FORWARDED-FOR not set";
4540+ }
4541+ } else {
4542+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4543+ if (ip_address == NULL) {
4544+ ip_address = "REMOTE_ADDR not set";
4545+ }
4546+ }
4547+
4548+
4549+ va_start(ap, fmt);
4550+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4551+ va_end(ap);
4552+ while (error[i]) {
4553+ if (error[i] < 32) error[i] = '.';
4554+ i++;
4555+ }
4556+
4557+ if (zend_is_executing(TSRMLS_C)) {
4558+ lineno = zend_get_executed_lineno(TSRMLS_C);
4559+ fname = zend_get_executed_filename(TSRMLS_C);
4560+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4561+ } else {
4562+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4563+ if (fname==NULL) {
4564+ fname = "unknown";
4565+ }
4566+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4567+ }
4568+
4569+ /* Syslog-Logging disabled? */
4570+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4571+ goto log_sapi;
4572+ }
4573+
4574+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4575+
4576+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4577+ if (s == -1) {
4578+ goto log_sapi;
4579+ }
4580+
4581+ memset(&saun, 0, sizeof(saun));
4582+ saun.sun_family = AF_UNIX;
4583+ strcpy(saun.sun_path, SYSLOG_PATH);
4584+ /*saun.sun_len = sizeof(saun);*/
4585+
4586+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4587+ if (r) {
4588+ close(s);
4589+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4590+ if (s == -1) {
4591+ goto log_sapi;
4592+ }
4593+
4594+ memset(&saun, 0, sizeof(saun));
4595+ saun.sun_family = AF_UNIX;
4596+ strcpy(saun.sun_path, SYSLOG_PATH);
4597+ /*saun.sun_len = sizeof(saun);*/
4598+
4599+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4600+ if (r) {
4601+ close(s);
4602+ goto log_sapi;
4603+ }
4604+ }
4605+ send(s, error, strlen(error), 0);
4606+
4607+ close(s);
4608+
4609+log_sapi:
4610+ /* SAPI Logging activated? */
4611+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4612+ sapi_module.log_message(buf);
4613+ }
4614+
4615+log_script:
4616+ /* script logging activaed? */
4617+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4618+ char cmd[8192], *cmdpos, *bufpos;
4619+ FILE *in;
4620+ int space;
4621+
4622+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4623+ space = sizeof(cmd) - strlen(cmd);
4624+ cmdpos = cmd + strlen(cmd);
4625+ bufpos = buf;
4626+ if (space <= 1) return;
4627+ while (space > 2 && *bufpos) {
4628+ if (*bufpos == '\'') {
4629+ if (space<=5) break;
4630+ *cmdpos++ = '\'';
4631+ *cmdpos++ = '\\';
4632+ *cmdpos++ = '\'';
4633+ *cmdpos++ = '\'';
4634+ bufpos++;
4635+ space-=4;
4636+ } else {
4637+ *cmdpos++ = *bufpos++;
4638+ space--;
4639+ }
4640+ }
4641+ *cmdpos++ = '\'';
4642+ *cmdpos = 0;
4643+
4644+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4645+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4646+ return;
4647+ }
4648+ /* read and forget the result */
4649+ while (1) {
4650+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4651+ if (readbytes<=0) {
4652+ break;
4653+ }
4654+ }
4655+ pclose(in);
4656+ }
4657+
4658+#endif
4659+}
4660+#endif
4661+
4662+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4663+
4664+/* will be replaced later with more compatible method */
4665+PHPAPI unsigned int php_canary()
4666+{
4667+ time_t t;
4668+ unsigned int canary;
4669+ int fd;
4670+
4671+ fd = open("/dev/urandom", 0);
4672+ if (fd != -1) {
4673+ int r = read(fd, &canary, sizeof(canary));
4674+ close(fd);
4675+ if (r == sizeof(canary)) {
4676+ return (canary);
4677+ }
4678+ }
4679+ /* not good but we never want to do this */
4680+ time(&t);
4681+ canary = *(unsigned int *)&t + getpid() << 16;
4682+ return (canary);
4683+}
4684+#endif
4685+
4686+#if HARDENING_PATCH_INC_PROTECT
4687+
4688+PHPAPI int php_is_valid_include(zval *z)
4689+{
4690+ char *filename;
4691+ int len, i;
4692+ TSRMLS_FETCH();
4693+
4694+ /* must be of type string */
4695+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4696+ return (0);
4697+ }
4698+
4699+ /* short cut */
4700+ filename = z->value.str.val;
4701+ len = z->value.str.len;
4702+
4703+ /* 1. must be shorter than MAXPATHLEN */
4704+ if (len > MAXPATHLEN) {
4705+ char *fname = estrndup(filename, len);
4706+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4707+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4708+ efree(fname);
4709+ return (0);
4710+ }
4711+
4712+ /* 2. must not be cutted */
4713+ if (len != strlen(filename)) {
4714+ char *fname = estrndup(filename, len);
4715+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4716+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4717+ efree(fname);
4718+ return (0);
4719+ }
4720+
4721+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4722+ if (strstr(filename, "://")) {
4723+ char *fname = estrndup(filename, len);
4724+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4725+
4726+ /* no black or whitelist then disallow all */
4727+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4728+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4729+ efree(fname);
4730+ return (0);
4731+ }
4732+
4733+ /* whitelist is stronger than blacklist */
4734+ if (HG(include_whitelist)) {
4735+ char *s, *t, *h, *index;
4736+ uint indexlen;
4737+ ulong numindex;
4738+
4739+ s = filename;
4740+
4741+ do {
4742+ zend_bool isOk = 0;
4743+ int tlen;
4744+
4745+ t = h = strstr(s, "://");
4746+ if (h == NULL) break;
4747+
4748+
4749+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4750+ t--;
4751+ }
4752+
4753+ tlen = strlen(t);
4754+
4755+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4756+ do {
4757+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4758+
4759+ if (r==HASH_KEY_NON_EXISTANT) {
4760+ break;
4761+ }
4762+ if (r==HASH_KEY_IS_STRING) {
4763+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4764+ if (strncmp(t, index, indexlen-1)==0) {
4765+ isOk = 1;
4766+ break;
4767+ }
4768+ }
4769+ }
4770+
4771+ zend_hash_move_forward(HG(include_whitelist));
4772+ } while (1);
4773+
4774+ /* not found in whitelist */
4775+ if (!isOk) {
4776+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4777+ efree(fname);
4778+ return 0;
4779+ }
4780+
4781+ s = h + 3;
4782+ } while (1);
4783+ } else {
4784+ /* okay then handle the blacklist */
4785+ char *s, *t, *h, *index;
4786+ uint indexlen;
4787+ ulong numindex;
4788+
4789+ s = filename;
4790+
4791+ do {
4792+ int tlen;
4793+
4794+ t = h = strstr(s, "://");
4795+ if (h == NULL) break;
4796+
4797+
4798+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4799+ t--;
4800+ }
4801+
4802+ tlen = strlen(t);
4803+
4804+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4805+ do {
4806+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4807+
4808+ if (r==HASH_KEY_NON_EXISTANT) {
4809+ break;
4810+ }
4811+ if (r==HASH_KEY_IS_STRING) {
4812+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4813+ if (strncmp(t, index, indexlen-1)==0) {
4814+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4815+ efree(fname);
4816+ return 0;
4817+ }
4818+ }
4819+ }
4820+
4821+ zend_hash_move_forward(HG(include_blacklist));
4822+ } while (1);
4823+
4824+ s = h + 3;
4825+ } while (1);
4826+ }
4827+
4828+ efree(fname);
4829+ }
4830+
4831+ /* 4. must not be an uploaded file */
4832+ if (SG(rfc1867_uploaded_files)) {
4833+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4834+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4835+ return (0);
4836+ }
4837+ }
4838+
4839+ /* passed all tests */
4840+ return (1);
4841+}
4842+
4843+#endif
4844+
4845+/*
4846+ * Local variables:
4847+ * tab-width: 4
4848+ * c-basic-offset: 4
4849+ * End:
4850+ * vim600: sw=4 ts=4 fdm=marker
4851+ * vim<600: sw=4 ts=4
4852+ */
4853diff -Nura php-5.1.4/main/hardening_patch.h hardening-patch-5.1.4-0.4.13/main/hardening_patch.h
4854--- php-5.1.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4855+++ hardening-patch-5.1.4-0.4.13/main/hardening_patch.h 2006-08-07 11:05:42.000000000 +0200
4856@@ -0,0 +1,46 @@
4857+/*
4858+ +----------------------------------------------------------------------+
4859+ | Hardening Patch for PHP |
4860+ +----------------------------------------------------------------------+
4861+ | Copyright (c) 2004-2005 Stefan Esser |
4862+ +----------------------------------------------------------------------+
4863+ | This source file is subject to version 2.02 of the PHP license, |
4864+ | that is bundled with this package in the file LICENSE, and is |
4865+ | available at through the world-wide-web at |
4866+ | http://www.php.net/license/2_02.txt. |
4867+ | If you did not receive a copy of the PHP license and are unable to |
4868+ | obtain it through the world-wide-web, please send a note to |
4869+ | license@php.net so we can mail you a copy immediately. |
4870+ +----------------------------------------------------------------------+
4871+ | Author: Stefan Esser <sesser@hardened-php.net> |
4872+ +----------------------------------------------------------------------+
4873+ */
4874+
4875+#ifndef HARDENING_PATCH_H
4876+#define HARDENING_PATCH_H
4877+
4878+#include "zend.h"
4879+
4880+#if HARDENING_PATCH
4881+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4882+PHPAPI void hardened_startup();
4883+#define HARDENING_PATCH_VERSION "0.4.13"
4884+
4885+#endif
4886+
4887+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4888+PHPAPI unsigned int php_canary();
4889+#endif
4890+
4891+#if HARDENING_PATCH_INC_PROTECT
4892+PHPAPI int php_is_valid_include(zval *z);
4893+#endif
4894+
4895+#endif /* HARDENING_PATCH_H */
4896+
4897+/*
4898+ * Local variables:
4899+ * tab-width: 4
4900+ * c-basic-offset: 4
4901+ * End:
4902+ */
4903diff -Nura php-5.1.4/main/hardening_patch.m4 hardening-patch-5.1.4-0.4.13/main/hardening_patch.m4
4904--- php-5.1.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4905+++ hardening-patch-5.1.4-0.4.13/main/hardening_patch.m4 2006-08-07 11:04:07.000000000 +0200
4906@@ -0,0 +1,95 @@
4907+dnl
4908+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4909+dnl
4910+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4911+dnl
4912+
4913+AC_ARG_ENABLE(hardening-patch-mm-protect,
4914+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4915+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4916+],[
4917+ DO_HARDENING_PATCH_MM_PROTECT=yes
4918+])
4919+
4920+AC_ARG_ENABLE(hardening-patch-ll-protect,
4921+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4922+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4923+],[
4924+ DO_HARDENING_PATCH_LL_PROTECT=yes
4925+])
4926+
4927+AC_ARG_ENABLE(hardening-patch-inc-protect,
4928+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4929+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4930+],[
4931+ DO_HARDENING_PATCH_INC_PROTECT=yes
4932+])
4933+
4934+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4935+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4936+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4937+],[
4938+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4939+])
4940+
4941+AC_ARG_ENABLE(hardening-patch-hash-protect,
4942+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4943+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4944+],[
4945+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4946+])
4947+
4948+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4949+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4950+
4951+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4952+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4953+
4954+AC_MSG_CHECKING(whether to protect include/require statements)
4955+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4956+
4957+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4958+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4959+
4960+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4961+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4962+
4963+
4964+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4965+
4966+
4967+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4968+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4969+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4970+else
4971+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4972+fi
4973+
4974+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4975+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4976+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4977+else
4978+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4979+fi
4980+
4981+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4982+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4983+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4984+else
4985+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4986+fi
4987+
4988+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4989+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4990+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4991+else
4992+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4993+fi
4994+
4995+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4996+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4997+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4998+else
4999+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
5000+fi
5001+
5002diff -Nura php-5.1.4/main/main.c hardening-patch-5.1.4-0.4.13/main/main.c
5003--- php-5.1.4/main/main.c 2006-04-12 14:49:39.000000000 +0200
5004+++ hardening-patch-5.1.4-0.4.13/main/main.c 2006-08-07 11:04:07.000000000 +0200
5005@@ -85,6 +85,10 @@
5006
5007 #include "SAPI.h"
5008 #include "rfc1867.h"
5009+#if HARDENING_PATCH
5010+#include "hardened_globals.h"
5011+#endif
5012+
5013 /* }}} */
5014
5015 #ifndef ZTS
5016@@ -109,10 +113,33 @@
5017 */
5018 static PHP_INI_MH(OnChangeMemoryLimit)
5019 {
5020+#if HARDENING_PATCH
5021+ long orig_memory_limit;
5022+
5023+ if (entry->modified) {
5024+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
5025+ } else {
5026+ orig_memory_limit = 1<<30;
5027+ }
5028+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
5029+ orig_memory_limit = 1<<30;
5030+ }
5031+#endif
5032 if (new_value) {
5033 PG(memory_limit) = zend_atoi(new_value, new_value_length);
5034+#if HARDENING_PATCH
5035+ if (PG(memory_limit) > orig_memory_limit) {
5036+ PG(memory_limit) = orig_memory_limit;
5037+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
5038+ return FAILURE;
5039+ }
5040+#endif
5041 } else {
5042+#if HARDENING_PATCH
5043+ PG(memory_limit) = orig_memory_limit;
5044+#else
5045 PG(memory_limit) = 1<<30; /* effectively, no limit */
5046+#endif
5047 }
5048 return zend_set_memory_limit(PG(memory_limit));
5049 }
5050@@ -1095,6 +1122,13 @@
5051 sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
5052 }
5053
5054+ /* Disable realpath cache if safe_mode or open_basedir are set */
5055+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
5056+ CWDG(realpath_cache_disable) = 1;
5057+ } else {
5058+ CWDG(realpath_cache_disable) = 0;
5059+ }
5060+
5061 if (PG(output_handler) && PG(output_handler)[0]) {
5062 php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC);
5063 } else if (PG(output_buffering)) {
5064@@ -1222,6 +1256,9 @@
5065
5066 zend_try {
5067 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
5068+#if HARDENING_PATCH
5069+ hardened_clear_mm_canaries(TSRMLS_C);
5070+#endif
5071 } zend_end_try();
5072
5073 zend_try {
5074@@ -1393,6 +1430,10 @@
5075 tsrm_ls = ts_resource(0);
5076 #endif
5077
5078+#if HARDENING_PATCH
5079+ hardened_startup();
5080+#endif
5081+
5082 module_shutdown = 0;
5083 module_startup = 1;
5084 sapi_initialize_empty_request(TSRMLS_C);
5085@@ -1406,6 +1447,12 @@
5086
5087 php_output_startup();
5088
5089+#if HARDENING_PATCH_INC_PROTECT
5090+ zuf.is_valid_include = php_is_valid_include;
5091+#endif
5092+#if HARDENING_PATCH
5093+ zuf.security_log_function = php_security_log;
5094+#endif
5095 zuf.error_function = php_error_cb;
5096 zuf.printf_function = php_printf;
5097 zuf.write_function = php_body_write_wrapper;
5098@@ -1476,7 +1523,9 @@
5099
5100 /* Disable realpath cache if safe_mode or open_basedir are set */
5101 if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
5102- CWDG(realpath_cache_size_limit) = 0;
5103+ CWDG(realpath_cache_disable) = 1;
5104+ } else {
5105+ CWDG(realpath_cache_disable) = 0;
5106 }
5107
5108 /* initialize stream wrappers registry
5109@@ -1517,6 +1566,10 @@
5110 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
5111 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);
5112 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
5113+#if HARDENING_PATCH
5114+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
5115+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
5116+#endif
5117 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
5118 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
5119 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
5120diff -Nura php-5.1.4/main/php_config.h.in hardening-patch-5.1.4-0.4.13/main/php_config.h.in
5121--- php-5.1.4/main/php_config.h.in 2006-05-12 16:41:13.000000000 +0200
5122+++ hardening-patch-5.1.4-0.4.13/main/php_config.h.in 2006-08-07 11:04:07.000000000 +0200
5123@@ -788,6 +788,39 @@
5124 /* Enabling BIND8 compatibility for Panther */
5125 #undef BIND_8_COMPAT
5126
5127+/* Hardening-Patch for PHP */
5128+#undef HARDENING_PATCH
5129+
5130+/* Memory Manager Protection */
5131+#undef HARDENING_PATCH_MM_PROTECT
5132+
5133+/* Memory Manager Protection */
5134+#undef HARDENING_PATCH_MM_PROTECT
5135+
5136+/* Linked List Protection */
5137+#undef HARDENING_PATCH_LL_PROTECT
5138+
5139+/* Linked List Protection */
5140+#undef HARDENING_PATCH_LL_PROTECT
5141+
5142+/* Include/Require Protection */
5143+#undef HARDENING_PATCH_INC_PROTECT
5144+
5145+/* Include/Require Protection */
5146+#undef HARDENING_PATCH_INC_PROTECT
5147+
5148+/* Fmt String Protection */
5149+#undef HARDENING_PATCH_FMT_PROTECT
5150+
5151+/* Fmt String Protection */
5152+#undef HARDENING_PATCH_FMT_PROTECT
5153+
5154+/* HashTable DTOR Protection */
5155+#undef HARDENING_PATCH_HASH_PROTECT
5156+
5157+/* HashTable DTOR Protection */
5158+#undef HARDENING_PATCH_HASH_PROTECT
5159+
5160 /* Whether you have AOLserver */
5161 #undef HAVE_AOLSERVER
5162
5163@@ -1131,6 +1164,12 @@
5164 /* Define if you have the getaddrinfo function */
5165 #undef HAVE_GETADDRINFO
5166
5167+/* Whether realpath is broken */
5168+#undef PHP_BROKEN_REALPATH
5169+
5170+/* Whether realpath is broken */
5171+#undef PHP_BROKEN_REALPATH
5172+
5173 /* Whether system headers declare timezone */
5174 #undef HAVE_DECLARED_TIMEZONE
5175
5176diff -Nura php-5.1.4/main/php.h hardening-patch-5.1.4-0.4.13/main/php.h
5177--- php-5.1.4/main/php.h 2006-03-07 23:37:53.000000000 +0100
5178+++ hardening-patch-5.1.4-0.4.13/main/php.h 2006-08-07 11:04:07.000000000 +0200
5179@@ -35,11 +35,19 @@
5180 #include "zend_qsort.h"
5181 #include "php_compat.h"
5182
5183+
5184 #include "zend_API.h"
5185
5186 #undef sprintf
5187 #define sprintf php_sprintf
5188
5189+#if HARDENING_PATCH
5190+#if HAVE_REALPATH
5191+#undef realpath
5192+#define realpath php_realpath
5193+#endif
5194+#endif
5195+
5196 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
5197 #undef PHP_DEBUG
5198 #define PHP_DEBUG ZEND_DEBUG
5199@@ -338,6 +346,7 @@
5200 #define PHP_FUNCTION ZEND_FUNCTION
5201 #define PHP_METHOD ZEND_METHOD
5202
5203+#define PHP_STATIC_FE ZEND_STATIC_FE
5204 #define PHP_NAMED_FE ZEND_NAMED_FE
5205 #define PHP_FE ZEND_FE
5206 #define PHP_DEP_FE ZEND_DEP_FE
5207@@ -447,6 +456,10 @@
5208 #endif
5209 #endif /* !XtOffsetOf */
5210
5211+#if HARDENING_PATCH
5212+#include "hardening_patch.h"
5213+#endif
5214+
5215 #endif
5216
5217 /*
5218diff -Nura php-5.1.4/main/php_open_temporary_file.c hardening-patch-5.1.4-0.4.13/main/php_open_temporary_file.c
5219--- php-5.1.4/main/php_open_temporary_file.c 2006-01-01 13:50:17.000000000 +0100
5220+++ hardening-patch-5.1.4-0.4.13/main/php_open_temporary_file.c 2006-08-07 11:04:07.000000000 +0200
5221@@ -114,17 +114,16 @@
5222
5223 path_len = strlen(path);
5224
5225- if (!(opened_path = emalloc(MAXPATHLEN))) {
5226- return -1;
5227- }
5228-
5229 if (!path_len || IS_SLASH(path[path_len - 1])) {
5230 trailing_slash = "";
5231 } else {
5232 trailing_slash = "/";
5233 }
5234
5235- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx);
5236+ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) {
5237+ efree(opened_path);
5238+ return -1;
5239+ }
5240
5241 #ifdef PHP_WIN32
5242 if (GetTempFileName(path, pfx, 0, opened_path)) {
5243diff -Nura php-5.1.4/main/php_variables.c hardening-patch-5.1.4-0.4.13/main/php_variables.c
5244--- php-5.1.4/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200
5245+++ hardening-patch-5.1.4-0.4.13/main/php_variables.c 2006-08-07 11:04:07.000000000 +0200
5246@@ -73,6 +73,10 @@
5247 symtable1 = Z_ARRVAL_P(track_vars_array);
5248 } else if (PG(register_globals)) {
5249 symtable1 = EG(active_symbol_table);
5250+ /* GLOBALS hijack attempt, reject parameter */
5251+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) {
5252+ symtable1 = NULL;
5253+ }
5254 }
5255 if (!symtable1) {
5256 /* Nothing to do */
5257@@ -513,7 +517,7 @@
5258 */
5259 static inline void php_register_server_variables(TSRMLS_D)
5260 {
5261- zval *array_ptr = NULL;
5262+ zval *array_ptr = NULL, *vptr;
5263 /* turn off magic_quotes while importing server variables */
5264 int magic_quotes_gpc = PG(magic_quotes_gpc);
5265
5266diff -Nura php-5.1.4/main/rfc1867.c hardening-patch-5.1.4-0.4.13/main/rfc1867.c
5267--- php-5.1.4/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100
5268+++ hardening-patch-5.1.4-0.4.13/main/rfc1867.c 2006-08-07 11:04:07.000000000 +0200
5269@@ -132,6 +132,7 @@
5270 #define UPLOAD_ERROR_D 4 /* No file uploaded */
5271 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
5272 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
5273+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
5274
5275 void php_rfc1867_register_constants(TSRMLS_D)
5276 {
5277@@ -142,6 +143,7 @@
5278 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
5279 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
5280 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
5281+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
5282 }
5283
5284 static void normalize_protected_variable(char *varname TSRMLS_DC)
5285@@ -854,6 +856,7 @@
5286 char buff[FILLUNIT];
5287 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
5288 int blen=0, wlen=0;
5289+ unsigned long offset;
5290
5291 zend_llist_clean(&header);
5292
5293@@ -970,7 +973,11 @@
5294 tmp++;
5295 }
5296 }
5297-
5298+
5299+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
5300+ skip_upload = 1;
5301+ }
5302+
5303 total_bytes = cancel_upload = 0;
5304
5305 if (!skip_upload) {
5306@@ -994,6 +1001,11 @@
5307 cancel_upload = UPLOAD_ERROR_D;
5308 }
5309
5310+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
5311+ cancel_upload = UPLOAD_ERROR_X;
5312+ }
5313+
5314+ offset = 0;
5315 end = 0;
5316 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
5317 {
5318@@ -1008,6 +1020,10 @@
5319 #endif
5320 cancel_upload = UPLOAD_ERROR_B;
5321 } else if (blen > 0) {
5322+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
5323+ cancel_upload = UPLOAD_ERROR_X;
5324+ }
5325+
5326 wlen = write(fd, buff, blen);
5327
5328 if (wlen < blen) {
5329@@ -1036,6 +1052,10 @@
5330 }
5331 #endif
5332
5333+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5334+ cancel_upload = UPLOAD_ERROR_X;
5335+ }
5336+
5337 if (cancel_upload) {
5338 if (temp_filename) {
5339 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5340diff -Nura php-5.1.4/main/SAPI.c hardening-patch-5.1.4-0.4.13/main/SAPI.c
5341--- php-5.1.4/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100
5342+++ hardening-patch-5.1.4-0.4.13/main/SAPI.c 2006-08-07 11:04:07.000000000 +0200
5343@@ -870,6 +870,36 @@
5344 post_entry->content_type_len+1);
5345 }
5346
5347+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))
5348+{
5349+ sapi_module.input_filter = input_filter;
5350+ return SUCCESS;
5351+}
5352+
5353+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5354+{
5355+ sapi_module.upload_varname_filter = upload_varname_filter;
5356+ return SUCCESS;
5357+}
5358+
5359+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5360+{
5361+ sapi_module.pre_upload_filter = pre_upload_filter;
5362+ return SUCCESS;
5363+}
5364+
5365+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
5366+{
5367+ sapi_module.upload_content_filter = upload_content_filter;
5368+ return SUCCESS;
5369+}
5370+
5371+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5372+{
5373+ sapi_module.post_upload_filter = post_upload_filter;
5374+ return SUCCESS;
5375+}
5376+
5377
5378 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
5379 {
5380@@ -884,11 +914,6 @@
5381 return SUCCESS;
5382 }
5383
5384-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))
5385-{
5386- sapi_module.input_filter = input_filter;
5387- return SUCCESS;
5388-}
5389
5390 SAPI_API int sapi_flush(TSRMLS_D)
5391 {
5392diff -Nura php-5.1.4/main/SAPI.h hardening-patch-5.1.4-0.4.13/main/SAPI.h
5393--- php-5.1.4/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100
5394+++ hardening-patch-5.1.4-0.4.13/main/SAPI.h 2006-08-07 11:04:07.000000000 +0200
5395@@ -190,6 +190,10 @@
5396 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5397 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));
5398
5399+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5400+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
5401+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5402+
5403 SAPI_API int sapi_flush(TSRMLS_D);
5404 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5405 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
5406@@ -254,6 +258,11 @@
5407 int (*get_target_gid)(gid_t * TSRMLS_DC);
5408
5409 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5410+
5411+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5412+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5413+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5414+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5415
5416 void (*ini_defaults)(HashTable *configuration_hash);
5417 int phpinfo_as_text;
5418@@ -279,7 +288,11 @@
5419
5420 #define SAPI_DEFAULT_MIMETYPE "text/html"
5421 #define SAPI_DEFAULT_CHARSET ""
5422+#if HARDENING_PATCH
5423+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5424+#else
5425 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5426+#endif
5427
5428 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5429 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5430@@ -287,6 +300,11 @@
5431 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5432 #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)
5433
5434+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5435+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5436+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
5437+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5438+
5439 BEGIN_EXTERN_C()
5440 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5441 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5442diff -Nura php-5.1.4/main/snprintf.c hardening-patch-5.1.4-0.4.13/main/snprintf.c
5443--- php-5.1.4/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100
5444+++ hardening-patch-5.1.4-0.4.13/main/snprintf.c 2006-08-07 11:04:07.000000000 +0200
5445@@ -1014,7 +1014,11 @@
5446
5447
5448 case 'n':
5449+#if HARDENING_PATCH_FMT_PROTECT
5450+ php_security_log(S_MISC, "'n' specifier within format string");
5451+#else
5452 *(va_arg(ap, int *)) = cc;
5453+#endif
5454 goto skip_output;
5455
5456 /*
5457diff -Nura php-5.1.4/main/spprintf.c hardening-patch-5.1.4-0.4.13/main/spprintf.c
5458--- php-5.1.4/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100
5459+++ hardening-patch-5.1.4-0.4.13/main/spprintf.c 2006-08-07 11:04:07.000000000 +0200
5460@@ -630,7 +630,11 @@
5461
5462
5463 case 'n':
5464+#if HARDENING_PATCH_FMT_PROTECT
5465+ php_security_log(S_MISC, "'n' specifier within format string");
5466+#else
5467 *(va_arg(ap, int *)) = xbuf->len;
5468+#endif
5469 goto skip_output;
5470
5471 /*
5472diff -Nura php-5.1.4/pear/Makefile.frag hardening-patch-5.1.4-0.4.13/pear/Makefile.frag
5473--- php-5.1.4/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100
5474+++ hardening-patch-5.1.4-0.4.13/pear/Makefile.frag 2006-08-07 11:04:07.000000000 +0200
5475@@ -3,7 +3,7 @@
5476 peardir=$(PEAR_INSTALLDIR)
5477
5478 # Skip all php.ini files altogether
5479-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0
5480+PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar
5481
5482 install-pear-installer: $(SAPI_CLI_PATH)
5483 @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)"
5484diff -Nura php-5.1.4/php.ini-dist hardening-patch-5.1.4-0.4.13/php.ini-dist
5485--- php-5.1.4/php.ini-dist 2006-02-09 00:43:48.000000000 +0100
5486+++ hardening-patch-5.1.4-0.4.13/php.ini-dist 2006-08-07 11:04:07.000000000 +0200
5487@@ -1197,6 +1197,209 @@
5488 ; instead of original one.
5489 soap.wsdl_cache_ttl=86400
5490
5491+[hardening-patch]
5492+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5493+; Hardening-Patch's logging ;
5494+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5495+
5496+;
5497+; hphp.log.syslog - Configures level for alerts reported through syslog
5498+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5499+; hphp.log.script - Configures level for alerts reported through external script
5500+;
5501+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5502+; Or each number up to get desired Hardening-Patch's reporting level
5503+;
5504+; S_ALL - All alerts
5505+; S_MEMORY - All canary violations and the safe unlink protection use this class
5506+; S_VARS - All variable filters trigger this class
5507+; S_FILES - All violation of uploaded files filter use this class
5508+; S_INCLUDE - The protection against malicious include filenames use this class
5509+; S_SQL - Failed SQL queries in MySQL are logged with this class
5510+; S_EXECUTOR - The execution depth protection uses this logging class
5511+; S_MISC - All other log messages (f.e. format string protection) use this class
5512+;
5513+; Example:
5514+;
5515+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5516+; memory alerts through syslog and SQL+Include alerts fo the script
5517+;
5518+;hphp.log.syslog = S_MEMORY
5519+;hphp.log.sapi = S_ALL & ~S_MEMORY
5520+;hphp.log.script = S_INCLUDE | S_SQL
5521+;
5522+; Syslog logging:
5523+;
5524+; - Facility configuration: one of the following facilities
5525+;
5526+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5527+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5528+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5529+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5530+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5531+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5532+; LOG_PERROR
5533+;
5534+; - Priority configuration: one of the followinf priorities
5535+;
5536+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5537+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5538+;
5539+hphp.log.syslog.priority = LOG_ALERT
5540+hphp.log.syslog.facility = LOG_USER
5541+;
5542+; Script logging:
5543+;
5544+;hphp.log.script.name = /home/hphp/log_script
5545+;
5546+; Alert configuration:
5547+;
5548+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5549+;
5550+;hphp.log.use-x-forwarded-for = On
5551+;
5552+
5553+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5554+; Hardening-Patch's Executor options ;
5555+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5556+
5557+; Execution depth limit
5558+;hphp.executor.max_depth = 8000
5559+
5560+; White-/blacklist for function calls during normal execution
5561+;hphp.executor.func.whitelist = ord,chr
5562+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5563+
5564+; White-/blacklist for function calls during eval() execution
5565+;hphp.executor.eval.whitelist = ord,chr
5566+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5567+
5568+; White-/blacklist for URLs allowes in include filenames
5569+;
5570+; - When both options are not set all URLs are forbidden
5571+;
5572+; - When both options are set whitelist is taken and blacklist ignored
5573+;
5574+; - An entry in the lists is either a URL sheme like: http, https
5575+; or the beginning of an URL like: php://input
5576+;
5577+;hphp.executor.include.whitelist = cookietest
5578+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5579+
5580+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5581+; Hardening-Patch's REQUEST variable filters ;
5582+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5583+
5584+; Limits the number of REQUEST variables
5585+hphp.request.max_vars = 200
5586+
5587+; Limits the length of variable names (without indices)
5588+hphp.request.max_varname_length = 64
5589+
5590+; Limits the length of complete variable names (with indices)
5591+hphp.request.max_totalname_length = 256
5592+
5593+; Limits the length of array indices
5594+hphp.request.max_array_index_length = 64
5595+
5596+; Limits the depth of arrays
5597+hphp.request.max_array_depth = 100
5598+
5599+; Limits the length of variable values
5600+hphp.request.max_value_length = 65000
5601+
5602+; Disallow ASCII-NUL characters in input
5603+hphp.request.disallow_nul = 1
5604+
5605+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5606+; Hardening-Patch's COOKIE variable filters ;
5607+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5608+
5609+; Limits the number of COOKIE variables
5610+hphp.cookie.max_vars = 100
5611+
5612+; Limits the length of variable names (without indices)
5613+hphp.cookie.max_name_length = 64
5614+
5615+; Limits the length of complete variable names (with indices)
5616+hphp.cookie.max_totalname_length = 256
5617+
5618+; Limits the length of array indices
5619+hphp.cookie.max_array_index_length = 64
5620+
5621+; Limits the depth of arrays
5622+hphp.cookie.max_array_depth = 100
5623+
5624+; Limits the length of variable values
5625+hphp.cookie.max_value_length = 10000
5626+
5627+; Disallow ASCII-NUL characters in input
5628+hphp.cookie.disallow_nul = 1
5629+
5630+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5631+; Hardening-Patch's GET variable filters ;
5632+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5633+
5634+; Limits the number of COOKIE variables
5635+hphp.get.max_vars = 100
5636+
5637+; Limits the length of variable names (without indices)
5638+hphp.get.max_name_length = 64
5639+
5640+; Limits the length of complete variable names (with indices)
5641+hphp.get.max_totalname_length = 256
5642+
5643+; Limits the length of array indices
5644+hphp.get.max_array_index_length = 64
5645+
5646+; Limits the depth of arrays
5647+hphp.get.max_array_depth = 50
5648+
5649+; Limits the length of variable values
5650+hphp.get.max_value_length = 512
5651+
5652+; Disallow ASCII-NUL characters in input
5653+hphp.get.disallow_nul = 1
5654+
5655+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5656+; Hardening-Patch's POST variable filters ;
5657+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5658+
5659+; Limits the number of POST variables
5660+hphp.post.max_vars = 200
5661+
5662+; Limits the length of variable names (without indices)
5663+hphp.post.max_name_length = 64
5664+
5665+; Limits the length of complete variable names (with indices)
5666+hphp.post.max_totalname_length = 256
5667+
5668+; Limits the length of array indices
5669+hphp.post.max_array_index_length = 64
5670+
5671+; Limits the depth of arrays
5672+hphp.post.max_array_depth = 100
5673+
5674+; Limits the length of variable values
5675+hphp.post.max_value_length = 65000
5676+
5677+; Disallow ASCII-NUL characters in input
5678+hphp.post.disallow_nul = 1
5679+
5680+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5681+; Hardening-Patch's fileupload variable filters ;
5682+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5683+
5684+; Limits the number of uploadable files
5685+hphp.upload.max_uploads = 25
5686+
5687+; Filter out the upload of ELF executables
5688+hphp.upload.disallow_elf_files = On
5689+
5690+; External filterscript for upload verification
5691+;hphp.upload.verification_script = /home/hphp/verify_script
5692+
5693+
5694 ; Local Variables:
5695 ; tab-width: 4
5696 ; End:
5697diff -Nura php-5.1.4/php.ini-recommended hardening-patch-5.1.4-0.4.13/php.ini-recommended
5698--- php-5.1.4/php.ini-recommended 2006-02-09 00:43:48.000000000 +0100
5699+++ hardening-patch-5.1.4-0.4.13/php.ini-recommended 2006-08-07 11:04:07.000000000 +0200
5700@@ -1255,6 +1255,209 @@
5701 ; instead of original one.
5702 soap.wsdl_cache_ttl=86400
5703
5704+[hardening-patch]
5705+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5706+; Hardening-Patch's logging ;
5707+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5708+
5709+;
5710+; hphp.log.syslog - Configures level for alerts reported through syslog
5711+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5712+; hphp.log.script - Configures level for alerts reported through external script
5713+;
5714+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5715+; Or each number up to get desired Hardening-Patch's reporting level
5716+;
5717+; S_ALL - All alerts
5718+; S_MEMORY - All canary violations and the safe unlink protection use this class
5719+; S_VARS - All variable filters trigger this class
5720+; S_FILES - All violation of uploaded files filter use this class
5721+; S_INCLUDE - The protection against malicious include filenames use this class
5722+; S_SQL - Failed SQL queries in MySQL are logged with this class
5723+; S_EXECUTOR - The execution depth protection uses this logging class
5724+; S_MISC - All other log messages (f.e. format string protection) use this class
5725+;
5726+; Example:
5727+;
5728+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5729+; memory alerts through syslog and SQL+Include alerts fo the script
5730+;
5731+;hphp.log.syslog = S_MEMORY
5732+;hphp.log.sapi = S_ALL & ~S_MEMORY
5733+;hphp.log.script = S_INCLUDE | S_SQL
5734+;
5735+; Syslog logging:
5736+;
5737+; - Facility configuration: one of the following facilities
5738+;
5739+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5740+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5741+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5742+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5743+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5744+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5745+; LOG_PERROR
5746+;
5747+; - Priority configuration: one of the followinf priorities
5748+;
5749+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5750+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5751+;
5752+hphp.log.syslog.priority = LOG_ALERT
5753+hphp.log.syslog.facility = LOG_USER
5754+;
5755+; Script logging:
5756+;
5757+;hphp.log.script.name = /home/hphp/log_script
5758+;
5759+; Alert configuration:
5760+;
5761+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5762+;
5763+;hphp.log.use-x-forwarded-for = On
5764+;
5765+
5766+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5767+; Hardening-Patch's Executor options ;
5768+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5769+
5770+; Execution depth limit
5771+;hphp.executor.max_depth = 8000
5772+
5773+; White-/blacklist for function calls during normal execution
5774+;hphp.executor.func.whitelist = ord,chr
5775+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5776+
5777+; White-/blacklist for function calls during eval() execution
5778+;hphp.executor.eval.whitelist = ord,chr
5779+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5780+
5781+; White-/blacklist for URLs allowes in include filenames
5782+;
5783+; - When both options are not set all URLs are forbidden
5784+;
5785+; - When both options are set whitelist is taken and blacklist ignored
5786+;
5787+; - An entry in the lists is either a URL sheme like: http, https
5788+; or the beginning of an URL like: php://input
5789+;
5790+;hphp.executor.include.whitelist = cookietest
5791+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5792+
5793+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5794+; Hardening-Patch's REQUEST variable filters ;
5795+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5796+
5797+; Limits the number of REQUEST variables
5798+hphp.request.max_vars = 200
5799+
5800+; Limits the length of variable names (without indices)
5801+hphp.request.max_varname_length = 64
5802+
5803+; Limits the length of complete variable names (with indices)
5804+hphp.request.max_totalname_length = 256
5805+
5806+; Limits the length of array indices
5807+hphp.request.max_array_index_length = 64
5808+
5809+; Limits the depth of arrays
5810+hphp.request.max_array_depth = 100
5811+
5812+; Limits the length of variable values
5813+hphp.request.max_value_length = 65000
5814+
5815+; Disallow ASCII-NUL characters in input
5816+hphp.request.disallow_nul = 1
5817+
5818+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5819+; Hardening-Patch's COOKIE variable filters ;
5820+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5821+
5822+; Limits the number of COOKIE variables
5823+hphp.cookie.max_vars = 100
5824+
5825+; Limits the length of variable names (without indices)
5826+hphp.cookie.max_name_length = 64
5827+
5828+; Limits the length of complete variable names (with indices)
5829+hphp.cookie.max_totalname_length = 256
5830+
5831+; Limits the length of array indices
5832+hphp.cookie.max_array_index_length = 64
5833+
5834+; Limits the depth of arrays
5835+hphp.cookie.max_array_depth = 100
5836+
5837+; Limits the length of variable values
5838+hphp.cookie.max_value_length = 10000
5839+
5840+; Disallow ASCII-NUL characters in input
5841+hphp.cookie.disallow_nul = 1
5842+
5843+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5844+; Hardening-Patch's GET variable filters ;
5845+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5846+
5847+; Limits the number of COOKIE variables
5848+hphp.get.max_vars = 100
5849+
5850+; Limits the length of variable names (without indices)
5851+hphp.get.max_name_length = 64
5852+
5853+; Limits the length of complete variable names (with indices)
5854+hphp.get.max_totalname_length = 256
5855+
5856+; Limits the length of array indices
5857+hphp.get.max_array_index_length = 64
5858+
5859+; Limits the depth of arrays
5860+hphp.get.max_array_depth = 50
5861+
5862+; Limits the length of variable values
5863+hphp.get.max_value_length = 512
5864+
5865+; Disallow ASCII-NUL characters in input
5866+hphp.get.disallow_nul = 1
5867+
5868+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5869+; Hardening-Patch's POST variable filters ;
5870+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5871+
5872+; Limits the number of POST variables
5873+hphp.post.max_vars = 200
5874+
5875+; Limits the length of variable names (without indices)
5876+hphp.post.max_name_length = 64
5877+
5878+; Limits the length of complete variable names (with indices)
5879+hphp.post.max_totalname_length = 256
5880+
5881+; Limits the length of array indices
5882+hphp.post.max_array_index_length = 64
5883+
5884+; Limits the depth of arrays
5885+hphp.post.max_array_depth = 100
5886+
5887+; Limits the length of variable values
5888+hphp.post.max_value_length = 65000
5889+
5890+; Disallow ASCII-NUL characters in input
5891+hphp.post.disallow_nul = 1
5892+
5893+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5894+; Hardening-Patch's fileupload variable filters ;
5895+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5896+
5897+; Limits the number of uploadable files
5898+hphp.upload.max_uploads = 25
5899+
5900+; Filter out the upload of ELF executables
5901+hphp.upload.disallow_elf_files = On
5902+
5903+; External filterscript for upload verification
5904+;hphp.upload.verification_script = /home/hphp/verify_script
5905+
5906+
5907 ; Local Variables:
5908 ; tab-width: 4
5909 ; End:
5910diff -Nura php-5.1.4/run-tests.php hardening-patch-5.1.4-0.4.13/run-tests.php
5911--- php-5.1.4/run-tests.php 2006-05-03 23:37:16.000000000 +0200
5912+++ hardening-patch-5.1.4-0.4.13/run-tests.php 2006-08-07 11:04:07.000000000 +0200
5913@@ -161,6 +161,10 @@
5914 'error_reporting=4095',
5915 'display_errors=1',
5916 'log_errors=0',
5917+ 'hphp.executor.include.whitelist=cookietest',
5918+ 'hphp.log.syslog=0',
5919+ 'hphp.log.sapi=0',
5920+ 'hphp.log.script=0',
5921 'html_errors=0',
5922 'track_errors=1',
5923 'report_memleaks=1',
5924diff -Nura php-5.1.4/sapi/apache/mod_php5.c hardening-patch-5.1.4-0.4.13/sapi/apache/mod_php5.c
5925--- php-5.1.4/sapi/apache/mod_php5.c 2006-04-02 19:58:17.000000000 +0200
5926+++ hardening-patch-5.1.4-0.4.13/sapi/apache/mod_php5.c 2006-08-07 11:04:07.000000000 +0200
5927@@ -482,7 +482,7 @@
5928 sapi_apache_get_fd,
5929 sapi_apache_force_http_10,
5930 sapi_apache_get_target_uid,
5931- sapi_apache_get_target_gid
5932+ sapi_apache_get_target_gid,
5933 };
5934 /* }}} */
5935
5936@@ -936,7 +936,11 @@
5937 {
5938 TSRMLS_FETCH();
5939 if (PG(expose_php)) {
5940+#if HARDENING_PATCH
5941+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5942+#else
5943 ap_add_version_component("PHP/" PHP_VERSION);
5944+#endif
5945 }
5946 }
5947 #endif
5948diff -Nura php-5.1.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.4-0.4.13/sapi/apache2filter/sapi_apache2.c
5949--- php-5.1.4/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
5950+++ hardening-patch-5.1.4-0.4.13/sapi/apache2filter/sapi_apache2.c 2006-08-07 11:04:07.000000000 +0200
5951@@ -573,7 +573,11 @@
5952 {
5953 TSRMLS_FETCH();
5954 if (PG(expose_php)) {
5955+#if HARDENING_PATCH
5956+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5957+#else
5958 ap_add_version_component(p, "PHP/" PHP_VERSION);
5959+#endif
5960 }
5961 }
5962
5963diff -Nura php-5.1.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.4-0.4.13/sapi/apache2handler/sapi_apache2.c
5964--- php-5.1.4/sapi/apache2handler/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
5965+++ hardening-patch-5.1.4-0.4.13/sapi/apache2handler/sapi_apache2.c 2006-08-07 11:04:07.000000000 +0200
5966@@ -341,7 +341,11 @@
5967 {
5968 TSRMLS_FETCH();
5969 if (PG(expose_php)) {
5970+#if HARDENING_PATCH
5971+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5972+#else
5973 ap_add_version_component(p, "PHP/" PHP_VERSION);
5974+#endif
5975 }
5976 }
5977
5978diff -Nura php-5.1.4/sapi/cgi/cgi_main.c hardening-patch-5.1.4-0.4.13/sapi/cgi/cgi_main.c
5979--- php-5.1.4/sapi/cgi/cgi_main.c 2006-05-03 21:40:58.000000000 +0200
5980+++ hardening-patch-5.1.4-0.4.13/sapi/cgi/cgi_main.c 2006-08-07 11:04:07.000000000 +0200
5981@@ -1444,10 +1444,18 @@
5982 SG(headers_sent) = 1;
5983 SG(request_info).no_headers = 1;
5984 }
5985+#if HARDENING_PATCH
5986 #if ZEND_DEBUG
5987- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5988+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5989 #else
5990- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5991+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5992+#endif
5993+#else
5994+#if ZEND_DEBUG
5995+ 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());
5996+#else
5997+ 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());
5998+#endif
5999 #endif
6000 php_end_ob_buffers(1 TSRMLS_CC);
6001 exit(0);
6002diff -Nura php-5.1.4/sapi/cli/php_cli.c hardening-patch-5.1.4-0.4.13/sapi/cli/php_cli.c
6003--- php-5.1.4/sapi/cli/php_cli.c 2006-02-21 22:15:13.000000000 +0100
6004+++ hardening-patch-5.1.4-0.4.13/sapi/cli/php_cli.c 2006-08-07 11:04:07.000000000 +0200
6005@@ -753,8 +753,14 @@
6006 goto err;
6007 }
6008
6009+#if HARDENING_PATCH
6010+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
6011+ PHP_VERSION, HARDENING_PATCH_VERSION,
6012+#else
6013 php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
6014- PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
6015+ PHP_VERSION,
6016+#endif
6017+ sapi_module.name, __DATE__, __TIME__,
6018 #if ZEND_DEBUG && defined(HAVE_GCOV)
6019 "(DEBUG GCOV)",
6020 #elif ZEND_DEBUG
6021diff -Nura php-5.1.4/TSRM/TSRM.h hardening-patch-5.1.4-0.4.13/TSRM/TSRM.h
6022--- php-5.1.4/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100
6023+++ hardening-patch-5.1.4-0.4.13/TSRM/TSRM.h 2006-08-07 11:04:07.000000000 +0200
6024@@ -33,6 +33,13 @@
6025 # define TSRM_API
6026 #endif
6027
6028+#if HARDENING_PATCH
6029+# if HAVE_REALPATH
6030+# undef realpath
6031+# define realpath php_realpath
6032+# endif
6033+#endif
6034+
6035 /* Only compile multi-threading functions if we're in ZTS mode */
6036 #ifdef ZTS
6037
6038@@ -88,6 +95,7 @@
6039
6040 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
6041
6042+
6043 #ifdef __cplusplus
6044 extern "C" {
6045 #endif
6046diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.4-0.4.13/TSRM/tsrm_virtual_cwd.c
6047--- php-5.1.4/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100
6048+++ hardening-patch-5.1.4-0.4.13/TSRM/tsrm_virtual_cwd.c 2006-08-07 11:04:07.000000000 +0200
6049@@ -163,6 +163,7 @@
6050 static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
6051 {
6052 CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
6053+ cwd_globals->realpath_cache_disable = 0;
6054 cwd_globals->realpath_cache_size = 0;
6055 cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
6056 cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL;
6057@@ -201,6 +202,176 @@
6058 return p;
6059 }
6060
6061+#if HARDENING_PATCH
6062+CWD_API char *php_realpath(const char *path, char *resolved)
6063+{
6064+ struct stat sb;
6065+ char *p, *q, *s;
6066+ size_t left_len, resolved_len;
6067+ unsigned symlinks;
6068+ int serrno, slen;
6069+ int is_dir = 1;
6070+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
6071+
6072+ serrno = errno;
6073+ symlinks = 0;
6074+ if (path[0] == '/') {
6075+ resolved[0] = '/';
6076+ resolved[1] = '\0';
6077+ if (path[1] == '\0')
6078+ return (resolved);
6079+ resolved_len = 1;
6080+ left_len = strlcpy(left, path + 1, sizeof(left));
6081+ } else {
6082+ if (getcwd(resolved, PATH_MAX) == NULL) {
6083+ strlcpy(resolved, ".", PATH_MAX);
6084+ return (NULL);
6085+ }
6086+ resolved_len = strlen(resolved);
6087+ left_len = strlcpy(left, path, sizeof(left));
6088+ }
6089+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
6090+ errno = ENAMETOOLONG;
6091+ return (NULL);
6092+ }
6093+
6094+ /*
6095+ * Iterate over path components in `left'.
6096+ */
6097+ while (left_len != 0) {
6098+ /*
6099+ * Extract the next path component and adjust `left'
6100+ * and its length.
6101+ */
6102+ p = strchr(left, '/');
6103+ s = p ? p : left + left_len;
6104+ if (s - left >= sizeof(next_token)) {
6105+ errno = ENAMETOOLONG;
6106+ return (NULL);
6107+ }
6108+ memcpy(next_token, left, s - left);
6109+ next_token[s - left] = '\0';
6110+ left_len -= s - left;
6111+ if (p != NULL)
6112+ memmove(left, s + 1, left_len + 1);
6113+ if (resolved[resolved_len - 1] != '/') {
6114+ if (resolved_len + 1 >= PATH_MAX) {
6115+ errno = ENAMETOOLONG;
6116+ return (NULL);
6117+ }
6118+ resolved[resolved_len++] = '/';
6119+ resolved[resolved_len] = '\0';
6120+ }
6121+ if (next_token[0] == '\0')
6122+ continue;
6123+ else if (strcmp(next_token, ".") == 0)
6124+ continue;
6125+ else if (strcmp(next_token, "..") == 0) {
6126+ /*
6127+ * Strip the last path component except when we have
6128+ * single "/"
6129+ */
6130+ if (!is_dir) {
6131+ errno = ENOENT;
6132+ return (NULL);
6133+ }
6134+ if (resolved_len > 1) {
6135+ resolved[resolved_len - 1] = '\0';
6136+ q = strrchr(resolved, '/');
6137+ *q = '\0';
6138+ resolved_len = q - resolved;
6139+ }
6140+ continue;
6141+ }
6142+
6143+ /*
6144+ * Append the next path component and lstat() it. If
6145+ * lstat() fails we still can return successfully if
6146+ * there are no more path components left.
6147+ */
6148+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6149+ if (resolved_len >= PATH_MAX) {
6150+ errno = ENAMETOOLONG;
6151+ return (NULL);
6152+ }
6153+ if (lstat(resolved, &sb) != 0) {
6154+ if (errno == ENOENT) {
6155+ if (p == NULL) {
6156+ errno = serrno;
6157+ return (resolved);
6158+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
6159+ resolved_len = strlcat(resolved, "/", PATH_MAX);
6160+ resolved_len = strlcat(resolved, left, PATH_MAX);
6161+ if (resolved_len >= PATH_MAX) {
6162+ errno = ENAMETOOLONG;
6163+ return (NULL);
6164+ }
6165+ errno = serrno;
6166+ return (resolved);
6167+ }
6168+ }
6169+ return (NULL);
6170+ }
6171+ if (S_ISLNK(sb.st_mode)) {
6172+ if (symlinks++ > MAXSYMLINKS) {
6173+ errno = ELOOP;
6174+ return (NULL);
6175+ }
6176+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6177+ if (slen < 0)
6178+ return (NULL);
6179+ symlink[slen] = '\0';
6180+ if (symlink[0] == '/') {
6181+ resolved[1] = 0;
6182+ resolved_len = 1;
6183+ } else if (resolved_len > 1) {
6184+ /* Strip the last path component. */
6185+ resolved[resolved_len - 1] = '\0';
6186+ q = strrchr(resolved, '/');
6187+ *q = '\0';
6188+ resolved_len = q - resolved;
6189+ }
6190+
6191+ /*
6192+ * If there are any path components left, then
6193+ * append them to symlink. The result is placed
6194+ * in `left'.
6195+ */
6196+ if (p != NULL) {
6197+ if (symlink[slen - 1] != '/') {
6198+ if (slen + 1 >= sizeof(symlink)) {
6199+ errno = ENAMETOOLONG;
6200+ return (NULL);
6201+ }
6202+ symlink[slen] = '/';
6203+ symlink[slen + 1] = 0;
6204+ }
6205+ left_len = strlcat(symlink, left, sizeof(left));
6206+ if (left_len >= sizeof(left)) {
6207+ errno = ENAMETOOLONG;
6208+ return (NULL);
6209+ }
6210+ }
6211+ left_len = strlcpy(left, symlink, sizeof(left));
6212+ } else {
6213+ if (S_ISDIR(sb.st_mode)) {
6214+ is_dir = 1;
6215+ } else {
6216+ is_dir = 0;
6217+ }
6218+ }
6219+ }
6220+
6221+ /*
6222+ * Remove trailing slash except when the resolved pathname
6223+ * is a single "/".
6224+ */
6225+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6226+ resolved[resolved_len - 1] = '\0';
6227+ return (resolved);
6228+}
6229+#endif
6230+
6231 CWD_API void virtual_cwd_startup(void)
6232 {
6233 char cwd[MAXPATHLEN];
6234@@ -381,22 +552,33 @@
6235 #endif
6236 char orig_path[MAXPATHLEN];
6237 int orig_path_len = 0;
6238+ int use_realpath_cache = 1;
6239 realpath_cache_bucket *bucket;
6240 time_t t = 0;
6241 TSRMLS_FETCH();
6242
6243 if (path_length == 0)
6244 return (0);
6245- if (path_length >= MAXPATHLEN)
6246+ if (path_length >= MAXPATHLEN) {
6247+ state->cwd[0] = 0;
6248+ state->cwd_length = 0;
6249 return (1);
6250+ }
6251+
6252+ /* Disable realpath cache if safe_mode or open_basedir are set */
6253+ if (CWDG(realpath_cache_disable)) {
6254+ use_realpath_cache = 0;
6255+ }
6256
6257- if (use_realpath && CWDG(realpath_cache_size_limit)) {
6258+ if (use_realpath && use_realpath_cache) {
6259 if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
6260 memcpy(orig_path, path, path_length+1);
6261 orig_path_len = path_length;
6262 } else {
6263 orig_path_len = path_length + state->cwd_length + 1;
6264 if (orig_path_len >= MAXPATHLEN) {
6265+ state->cwd[0] = 0;
6266+ state->cwd_length = 0;
6267 return 1;
6268 }
6269 memcpy(orig_path, state->cwd, state->cwd_length);
6270@@ -414,6 +596,8 @@
6271 if (verify_path && verify_path(state)) {
6272 CWD_STATE_FREE(state);
6273 *state = old_state;
6274+ state->cwd[0] = 0;
6275+ state->cwd_length = 0;
6276 return 1;
6277 } else {
6278 CWD_STATE_FREE(&old_state);
6279@@ -431,8 +615,9 @@
6280 path = resolved_path;
6281 path_length = strlen(path);
6282 } else {
6283- /* disable for now
6284- return 1; */
6285+ state->cwd[0] = 0;
6286+ state->cwd_length = 0;
6287+ return 1;
6288 }
6289 }
6290 } else { /* Concat current directory with relative path and then run realpath() on it */
6291@@ -441,6 +626,8 @@
6292
6293 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6294 if (!tmp) {
6295+ state->cwd[0] = 0;
6296+ state->cwd_length = 0;
6297 return 1;
6298 }
6299 memcpy(ptr, state->cwd, state->cwd_length);
6300@@ -451,6 +638,8 @@
6301 *ptr = '\0';
6302 if (strlen(tmp) >= MAXPATHLEN) {
6303 free(tmp);
6304+ state->cwd[0] = 0;
6305+ state->cwd_length = 0;
6306 return 1;
6307 }
6308 if (use_realpath) {
6309@@ -458,9 +647,10 @@
6310 path = resolved_path;
6311 path_length = strlen(path);
6312 } else {
6313- /* disable for now
6314 free(tmp);
6315- return 1; */
6316+ state->cwd[0] = 0;
6317+ state->cwd_length = 0;
6318+ return 1;
6319 }
6320 }
6321 free(tmp);
6322@@ -599,7 +789,7 @@
6323 #endif
6324 free(free_path);
6325
6326- if (use_realpath && CWDG(realpath_cache_size_limit)) {
6327+ if (use_realpath && use_realpath_cache) {
6328 realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC);
6329 }
6330
6331diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.4-0.4.13/TSRM/tsrm_virtual_cwd.h
6332--- php-5.1.4/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200
6333+++ hardening-patch-5.1.4-0.4.13/TSRM/tsrm_virtual_cwd.h 2006-08-07 11:04:07.000000000 +0200
6334@@ -127,6 +127,22 @@
6335
6336 typedef int (*verify_path_func)(const cwd_state *);
6337
6338+#ifndef HAVE_STRLCPY
6339+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6340+#undef strlcpy
6341+#define strlcpy php_strlcpy
6342+#endif
6343+
6344+#ifndef HAVE_STRLCAT
6345+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6346+#undef strlcat
6347+#define strlcat php_strlcat
6348+#endif
6349+
6350+
6351+#if HARDENING_PATCH
6352+CWD_API char *php_realpath(const char *path, char *resolved);
6353+#endif
6354 CWD_API void virtual_cwd_startup(void);
6355 CWD_API void virtual_cwd_shutdown(void);
6356 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6357@@ -199,6 +215,7 @@
6358 long realpath_cache_size_limit;
6359 long realpath_cache_ttl;
6360 realpath_cache_bucket *realpath_cache[1024];
6361+ int realpath_cache_disable;
6362 } virtual_cwd_globals;
6363
6364 #ifdef ZTS
6365diff -Nura php-5.1.4/Zend/zend_alloc.c hardening-patch-5.1.4-0.4.13/Zend/zend_alloc.c
6366--- php-5.1.4/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100
6367+++ hardening-patch-5.1.4-0.4.13/Zend/zend_alloc.c 2006-08-07 11:04:07.000000000 +0200
6368@@ -64,6 +64,11 @@
6369 # define END_MAGIC_SIZE 0
6370 #endif
6371
6372+#if HARDENING_PATCH_MM_PROTECT
6373+# define CANARY_SIZE sizeof(unsigned int)
6374+#else
6375+# define CANARY_SIZE 0
6376+#endif
6377
6378 # if MEMORY_LIMIT
6379 # if ZEND_DEBUG
6380@@ -72,7 +77,15 @@
6381 #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0)
6382 # endif
6383
6384-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\
6385+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \
6386+ if (file) { \
6387+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \
6388+ } else { \
6389+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \
6390+ } \
6391+ exit(1); \
6392+ } \
6393+ AG(allocated_memory) += rs;\
6394 if (AG(memory_limit)<AG(allocated_memory)) {\
6395 int php_mem_limit = AG(memory_limit); \
6396 AG(allocated_memory) -= rs; \
6397@@ -105,9 +118,17 @@
6398 if (p==AG(head)) { \
6399 AG(head) = p->pNext; \
6400 } else { \
6401+ if (p != p->pLast->pNext) { \
6402+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6403+ exit(1); \
6404+ } \
6405 p->pLast->pNext = p->pNext; \
6406 } \
6407 if (p->pNext) { \
6408+ if (p != p->pNext->pLast) { \
6409+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6410+ exit(1); \
6411+ } \
6412 p->pNext->pLast = p->pLast; \
6413 }
6414 #else
6415@@ -127,7 +148,7 @@
6416 #endif
6417
6418 #define DECLARE_CACHE_VARS() \
6419- unsigned int real_size; \
6420+ size_t real_size; \
6421 unsigned int cache_index
6422
6423 #define REAL_SIZE(size) ((size+7) & ~0x7)
6424@@ -142,12 +163,22 @@
6425
6426 ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6427 {
6428- zend_mem_header *p;
6429+ zend_mem_header *p = NULL;
6430 DECLARE_CACHE_VARS();
6431 TSRMLS_FETCH();
6432
6433+#if HARDENING_PATCH_MM_PROTECT
6434+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6435+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6436+ exit(1);
6437+ }
6438+#endif
6439 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6440
6441+ if (size > INT_MAX || SIZE < size) {
6442+ goto emalloc_error;
6443+ }
6444+
6445 #if !ZEND_DISABLE_MEMORY_CACHE
6446 if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6447 p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]];
6448@@ -164,6 +195,10 @@
6449 AG(cache_stats)[CACHE_INDEX][1]++;
6450 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6451 #endif
6452+#if HARDENING_PATCH_MM_PROTECT
6453+ p->canary = HG(canary_1);
6454+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6455+#endif
6456 p->size = size;
6457 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6458 } else {
6459@@ -179,11 +214,13 @@
6460 AG(allocated_memory_peak) = AG(allocated_memory);
6461 }
6462 #endif
6463- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6464+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6465 #if !ZEND_DISABLE_MEMORY_CACHE
6466 }
6467 #endif
6468
6469+emalloc_error:
6470+
6471 HANDLE_BLOCK_INTERRUPTIONS();
6472
6473 if (!p) {
6474@@ -210,7 +247,10 @@
6475 # endif
6476 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6477 #endif
6478-
6479+#if HARDENING_PATCH_MM_PROTECT
6480+ p->canary = HG(canary_1);
6481+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6482+#endif
6483 HANDLE_UNBLOCK_INTERRUPTIONS();
6484 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6485 }
6486@@ -238,6 +278,10 @@
6487 }
6488 }
6489
6490+
6491+#if HARDENING_PATCH
6492+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6493+#endif
6494 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
6495 return 0;
6496 }
6497@@ -270,9 +314,25 @@
6498
6499 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6500 {
6501+#if HARDENING_PATCH_MM_PROTECT
6502+ unsigned int canary_2;
6503+#endif
6504 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6505 DECLARE_CACHE_VARS();
6506 TSRMLS_FETCH();
6507+
6508+#if HARDENING_PATCH_MM_PROTECT
6509+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6510+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6511+ if (canary_2 != HG(canary_2)) {
6512+efree_canary_mismatch:
6513+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6514+ exit(1);
6515+ }
6516+ /* to catch double efree()s */
6517+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6518+ p->canary = 0;
6519+#endif
6520
6521 #if defined(ZTS) && TSRM_DEBUG
6522 if (p->thread_id != tsrm_thread_id()) {
6523@@ -313,23 +373,35 @@
6524
6525 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6526 {
6527- void *p;
6528- int final_size = size*nmemb;
6529+ char *p;
6530+ size_t _size = nmemb * size;
6531+
6532+ if (nmemb && (_size/nmemb!=size)) {
6533+#if HARDENING_PATCH
6534+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6535+#endif
6536+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6537+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6538+ kill(getpid(), SIGSEGV);
6539+#else
6540+ exit(1);
6541+#endif
6542+ }
6543
6544- HANDLE_BLOCK_INTERRUPTIONS();
6545- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6546- if (!p) {
6547- HANDLE_UNBLOCK_INTERRUPTIONS();
6548- return (void *) p;
6549+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6550+ if (p) {
6551+ memset(p, 0, _size);
6552 }
6553- memset(p, 0, final_size);
6554- HANDLE_UNBLOCK_INTERRUPTIONS();
6555- return p;
6556+
6557+ return ((void *)p);
6558 }
6559
6560
6561 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6562 {
6563+#if HARDENING_PATCH_MM_PROTECT
6564+ unsigned int canary_2;
6565+#endif
6566 zend_mem_header *p;
6567 zend_mem_header *orig;
6568 DECLARE_CACHE_VARS();
6569@@ -341,6 +413,16 @@
6570
6571 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6572
6573+#if HARDENING_PATCH_MM_PROTECT
6574+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6575+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6576+ if (canary_2 != HG(canary_2)) {
6577+erealloc_canary_mismatch:
6578+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6579+ exit(1);
6580+ }
6581+#endif
6582+
6583 #if defined(ZTS) && TSRM_DEBUG
6584 if (p->thread_id != tsrm_thread_id()) {
6585 void *new_p;
6586@@ -357,6 +439,13 @@
6587 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6588
6589 HANDLE_BLOCK_INTERRUPTIONS();
6590+
6591+ if (size > INT_MAX || SIZE < size) {
6592+ REMOVE_POINTER_FROM_LIST(p);
6593+ p = NULL;
6594+ goto erealloc_error;
6595+ }
6596+
6597 #if MEMORY_LIMIT
6598 CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size));
6599 if (AG(allocated_memory) > AG(allocated_memory_peak)) {
6600@@ -364,7 +453,8 @@
6601 }
6602 #endif
6603 REMOVE_POINTER_FROM_LIST(p);
6604- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6605+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6606+erealloc_error:
6607 if (!p) {
6608 if (!allow_failure) {
6609 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6610@@ -386,6 +476,9 @@
6611 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6612 #endif
6613
6614+#if HARDENING_PATCH_MM_PROTECT
6615+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6616+#endif
6617 p->size = size;
6618
6619 HANDLE_UNBLOCK_INTERRUPTIONS();
6620@@ -460,6 +553,10 @@
6621 {
6622 AG(head) = NULL;
6623
6624+#if HARDENING_PATCH_MM_PROTECT
6625+ HG(canary_1) = zend_canary();
6626+ HG(canary_2) = zend_canary();
6627+#endif
6628 #if MEMORY_LIMIT
6629 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6630 AG(allocated_memory) = 0;
6631diff -Nura php-5.1.4/Zend/zend_alloc.h hardening-patch-5.1.4-0.4.13/Zend/zend_alloc.h
6632--- php-5.1.4/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100
6633+++ hardening-patch-5.1.4-0.4.13/Zend/zend_alloc.h 2006-08-07 11:04:07.000000000 +0200
6634@@ -35,6 +35,9 @@
6635 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6636
6637 typedef struct _zend_mem_header {
6638+#if HARDENING_PATCH_MM_PROTECT
6639+ unsigned int canary;
6640+#endif
6641 #if ZEND_DEBUG
6642 long magic;
6643 char *filename;
6644diff -Nura php-5.1.4/Zend/zend_API.h hardening-patch-5.1.4-0.4.13/Zend/zend_API.h
6645--- php-5.1.4/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100
6646+++ hardening-patch-5.1.4-0.4.13/Zend/zend_API.h 2006-08-07 11:04:07.000000000 +0200
6647@@ -47,6 +47,7 @@
6648 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
6649
6650 #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 },
6651+#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 },
6652
6653 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
6654 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
6655diff -Nura php-5.1.4/Zend/zend_builtin_functions.c hardening-patch-5.1.4-0.4.13/Zend/zend_builtin_functions.c
6656--- php-5.1.4/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200
6657+++ hardening-patch-5.1.4-0.4.13/Zend/zend_builtin_functions.c 2006-08-07 11:04:07.000000000 +0200
6658@@ -53,6 +53,9 @@
6659 static ZEND_FUNCTION(crash);
6660 #endif
6661 #endif
6662+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6663+static ZEND_FUNCTION(heap_overflow);
6664+#endif
6665 static ZEND_FUNCTION(get_included_files);
6666 static ZEND_FUNCTION(is_subclass_of);
6667 static ZEND_FUNCTION(is_a);
6668@@ -113,6 +116,9 @@
6669 ZEND_FE(crash, NULL)
6670 #endif
6671 #endif
6672+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6673+ ZEND_FE(heap_overflow, NULL)
6674+#endif
6675 ZEND_FE(get_included_files, NULL)
6676 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6677 ZEND_FE(is_subclass_of, NULL)
6678@@ -1103,6 +1109,19 @@
6679
6680 #endif /* ZEND_DEBUG */
6681
6682+
6683+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6684+ZEND_FUNCTION(heap_overflow)
6685+{
6686+ char *nowhere = emalloc(10);
6687+
6688+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6689+
6690+ efree(nowhere);
6691+}
6692+#endif
6693+
6694+
6695 /* {{{ proto array get_included_files(void)
6696 Returns an array with the file names that were include_once()'d */
6697 ZEND_FUNCTION(get_included_files)
6698diff -Nura php-5.1.4/Zend/zend.c hardening-patch-5.1.4-0.4.13/Zend/zend.c
6699--- php-5.1.4/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200
6700+++ hardening-patch-5.1.4-0.4.13/Zend/zend.c 2006-08-07 11:04:07.000000000 +0200
6701@@ -55,6 +55,12 @@
6702 ZEND_API void (*zend_unblock_interruptions)(void);
6703 ZEND_API void (*zend_ticks_function)(int ticks);
6704 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6705+#if HARDENING_PATCH
6706+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6707+#endif
6708+#if HARDENING_PATCH_INC_PROTECT
6709+ZEND_API int (*zend_is_valid_include)(zval *z);
6710+#endif
6711 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
6712 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
6713
6714@@ -74,9 +80,391 @@
6715 return SUCCESS;
6716 }
6717
6718+#if HARDENING_PATCH
6719+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6720+{
6721+ if (!new_value) {
6722+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6723+ } else {
6724+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6725+ }
6726+ return SUCCESS;
6727+}
6728+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6729+{
6730+ if (!new_value) {
6731+ EG(hphp_log_syslog_facility) = LOG_USER;
6732+ } else {
6733+ EG(hphp_log_syslog_facility) = atoi(new_value);
6734+ }
6735+ return SUCCESS;
6736+}
6737+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6738+{
6739+ if (!new_value) {
6740+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6741+ } else {
6742+ EG(hphp_log_syslog_priority) = atoi(new_value);
6743+ }
6744+ return SUCCESS;
6745+}
6746+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6747+{
6748+ if (!new_value) {
6749+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6750+ } else {
6751+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6752+ }
6753+ return SUCCESS;
6754+}
6755+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6756+{
6757+ if (!new_value) {
6758+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
6759+ } else {
6760+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6761+ }
6762+ return SUCCESS;
6763+}
6764+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6765+{
6766+ if (EG(hphp_log_scriptname)) {
6767+ pefree(EG(hphp_log_scriptname),1);
6768+ }
6769+ EG(hphp_log_scriptname) = NULL;
6770+ if (new_value) {
6771+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6772+ }
6773+ return SUCCESS;
6774+}
6775+
6776+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6777+{
6778+ char *s = NULL, *e, *val;
6779+ unsigned long dummy = 1;
6780+
6781+ if (!new_value) {
6782+include_whitelist_destroy:
6783+ if (HG(include_whitelist)) {
6784+ zend_hash_destroy(HG(include_whitelist));
6785+ pefree(HG(include_whitelist),1);
6786+ }
6787+ HG(include_whitelist) = NULL;
6788+ return SUCCESS;
6789+ }
6790+ if (!(*new_value)) {
6791+ goto include_whitelist_destroy;
6792+ }
6793+
6794+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6795+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6796+
6797+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6798+ e = val;
6799+
6800+ while (*e) {
6801+ switch (*e) {
6802+ case ' ':
6803+ case ',':
6804+ if (s) {
6805+ *e = '\0';
6806+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6807+ s = NULL;
6808+ }
6809+ break;
6810+ default:
6811+ if (!s) {
6812+ s = e;
6813+ }
6814+ break;
6815+ }
6816+ e++;
6817+ }
6818+ if (s) {
6819+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6820+ }
6821+ efree(val);
6822+
6823+ return SUCCESS;
6824+}
6825+
6826+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6827+{
6828+ char *s = NULL, *e, *val;
6829+ unsigned long dummy = 1;
6830+
6831+ if (!new_value) {
6832+include_blacklist_destroy:
6833+ if (HG(include_blacklist)) {
6834+ zend_hash_destroy(HG(include_blacklist));
6835+ pefree(HG(include_blacklist),1);
6836+ }
6837+ HG(include_blacklist) = NULL;
6838+ return SUCCESS;
6839+ }
6840+ if (!(*new_value)) {
6841+ goto include_blacklist_destroy;
6842+ }
6843+
6844+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6845+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6846+
6847+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6848+ e = val;
6849+
6850+ while (*e) {
6851+ switch (*e) {
6852+ case ' ':
6853+ case ',':
6854+ if (s) {
6855+ *e = '\0';
6856+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6857+ s = NULL;
6858+ }
6859+ break;
6860+ default:
6861+ if (!s) {
6862+ s = e;
6863+ }
6864+ break;
6865+ }
6866+ e++;
6867+ }
6868+ if (s) {
6869+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6870+ }
6871+ efree(val);
6872+
6873+ return SUCCESS;
6874+}
6875+
6876+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6877+{
6878+ char *s = NULL, *e, *val;
6879+ unsigned long dummy = 1;
6880+
6881+ if (!new_value) {
6882+eval_whitelist_destroy:
6883+ if (HG(eval_whitelist)) {
6884+ zend_hash_destroy(HG(eval_whitelist));
6885+ pefree(HG(eval_whitelist),1);
6886+ }
6887+ HG(eval_whitelist) = NULL;
6888+ return SUCCESS;
6889+ }
6890+ if (!(*new_value)) {
6891+ goto eval_whitelist_destroy;
6892+ }
6893+
6894+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6895+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6896+
6897+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6898+ e = val;
6899+
6900+ while (*e) {
6901+ switch (*e) {
6902+ case ' ':
6903+ case ',':
6904+ if (s) {
6905+ *e = '\0';
6906+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6907+ s = NULL;
6908+ }
6909+ break;
6910+ default:
6911+ if (!s) {
6912+ s = e;
6913+ }
6914+ break;
6915+ }
6916+ e++;
6917+ }
6918+ if (s) {
6919+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6920+ }
6921+ efree(val);
6922+
6923+ return SUCCESS;
6924+}
6925+
6926+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6927+{
6928+ char *s = NULL, *e, *val;
6929+ unsigned long dummy = 1;
6930+
6931+ if (!new_value) {
6932+eval_blacklist_destroy:
6933+ if (HG(eval_blacklist)) {
6934+ zend_hash_destroy(HG(eval_blacklist));
6935+ pefree(HG(eval_blacklist), 1);
6936+ }
6937+ HG(eval_blacklist) = NULL;
6938+ return SUCCESS;
6939+ }
6940+ if (!(*new_value)) {
6941+ goto eval_blacklist_destroy;
6942+ }
6943+
6944+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6945+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6946+
6947+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6948+ e = val;
6949+
6950+ while (*e) {
6951+ switch (*e) {
6952+ case ' ':
6953+ case ',':
6954+ if (s) {
6955+ *e = '\0';
6956+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6957+ s = NULL;
6958+ }
6959+ break;
6960+ default:
6961+ if (!s) {
6962+ s = e;
6963+ }
6964+ break;
6965+ }
6966+ e++;
6967+ }
6968+ if (s) {
6969+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6970+ }
6971+ efree(val);
6972+
6973+
6974+ return SUCCESS;
6975+}
6976+
6977+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6978+{
6979+ char *s = NULL, *e, *val;
6980+ unsigned long dummy = 1;
6981+
6982+ if (!new_value) {
6983+func_whitelist_destroy:
6984+ if (HG(func_whitelist)) {
6985+ zend_hash_destroy(HG(func_whitelist));
6986+ pefree(HG(func_whitelist),1);
6987+ }
6988+ HG(func_whitelist) = NULL;
6989+ return SUCCESS;
6990+ }
6991+ if (!(*new_value)) {
6992+ goto func_whitelist_destroy;
6993+ }
6994+
6995+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6996+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6997+
6998+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6999+ e = val;
7000+
7001+ while (*e) {
7002+ switch (*e) {
7003+ case ' ':
7004+ case ',':
7005+ if (s) {
7006+ *e = '\0';
7007+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7008+ s = NULL;
7009+ }
7010+ break;
7011+ default:
7012+ if (!s) {
7013+ s = e;
7014+ }
7015+ break;
7016+ }
7017+ e++;
7018+ }
7019+ if (s) {
7020+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7021+ }
7022+ efree(val);
7023+
7024+ return SUCCESS;
7025+}
7026+
7027+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
7028+{
7029+ char *s = NULL, *e, *val;
7030+ unsigned long dummy = 1;
7031+
7032+ if (!new_value) {
7033+func_blacklist_destroy:
7034+ if (HG(func_blacklist)) {
7035+ zend_hash_destroy(HG(func_blacklist));
7036+ pefree(HG(func_blacklist),1);
7037+ }
7038+ HG(func_blacklist) = NULL;
7039+ return SUCCESS;
7040+ }
7041+ if (!(*new_value)) {
7042+ goto func_blacklist_destroy;
7043+ }
7044+
7045+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
7046+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
7047+
7048+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7049+ e = val;
7050+
7051+ while (*e) {
7052+ switch (*e) {
7053+ case ' ':
7054+ case ',':
7055+ if (s) {
7056+ *e = '\0';
7057+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7058+ s = NULL;
7059+ }
7060+ break;
7061+ default:
7062+ if (!s) {
7063+ s = e;
7064+ }
7065+ break;
7066+ }
7067+ e++;
7068+ }
7069+ if (s) {
7070+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7071+ }
7072+ efree(val);
7073+
7074+
7075+ return SUCCESS;
7076+}
7077+
7078+#endif
7079
7080 ZEND_INI_BEGIN()
7081 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
7082+#if HARDENING_PATCH
7083+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
7084+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
7085+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
7086+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
7087+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
7088+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
7089+ STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for", "0", ZEND_INI_SYSTEM, OnUpdateBool, hphp_log_use_x_forwarded_for, zend_executor_globals, executor_globals)
7090+
7091+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
7092+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
7093+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
7094+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
7095+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
7096+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
7097+
7098+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
7099+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
7100+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
7101+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals)
7102+#endif
7103 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
7104 #ifdef ZEND_MULTIBYTE
7105 STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
7106@@ -501,9 +889,13 @@
7107 EG(user_error_handler) = NULL;
7108 EG(user_exception_handler) = NULL;
7109 EG(in_execution) = 0;
7110+ EG(in_code_type) = 0;
7111 EG(in_autoload) = NULL;
7112 EG(current_execute_data) = NULL;
7113 EG(current_module) = NULL;
7114+#if HARDENING_PATCH
7115+ EG(hphp_log_scriptname) = NULL;
7116+#endif
7117 }
7118
7119
7120@@ -574,6 +966,14 @@
7121 extern zend_scanner_globals language_scanner_globals;
7122 #endif
7123
7124+ /* Set up Hardening-Patch utility functions first */
7125+#if HARDENING_PATCH
7126+ zend_security_log = utility_functions->security_log_function;
7127+#endif
7128+#if HARDENING_PATCH_INC_PROTECT
7129+ zend_is_valid_include = utility_functions->is_valid_include;
7130+#endif
7131+
7132 #ifdef ZTS
7133 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
7134 #else
7135@@ -777,6 +1177,7 @@
7136 }
7137 CG(unclean_shutdown) = 1;
7138 CG(in_compilation) = EG(in_execution) = 0;
7139+ EG(in_code_type) = 0;
7140 EG(current_execute_data) = NULL;
7141 longjmp(EG(bailout), FAILURE);
7142 }
7143diff -Nura php-5.1.4/Zend/zend_canary.c hardening-patch-5.1.4-0.4.13/Zend/zend_canary.c
7144--- php-5.1.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
7145+++ hardening-patch-5.1.4-0.4.13/Zend/zend_canary.c 2006-08-07 11:04:07.000000000 +0200
7146@@ -0,0 +1,58 @@
7147+/*
7148+ +----------------------------------------------------------------------+
7149+ | Hardening-Patch for PHP |
7150+ +----------------------------------------------------------------------+
7151+ | Copyright (c) 2004-2005 Stefan Esser |
7152+ +----------------------------------------------------------------------+
7153+ | This source file is subject to version 2.02 of the PHP license, |
7154+ | that is bundled with this package in the file LICENSE, and is |
7155+ | available at through the world-wide-web at |
7156+ | http://www.php.net/license/2_02.txt. |
7157+ | If you did not receive a copy of the PHP license and are unable to |
7158+ | obtain it through the world-wide-web, please send a note to |
7159+ | license@php.net so we can mail you a copy immediately. |
7160+ +----------------------------------------------------------------------+
7161+ | Author: Stefan Esser <sesser@hardened-php.net> |
7162+ +----------------------------------------------------------------------+
7163+ */
7164+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
7165+
7166+#include "zend.h"
7167+
7168+#include <stdio.h>
7169+#include <stdlib.h>
7170+
7171+
7172+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7173+
7174+/* will be replaced later with more compatible method */
7175+ZEND_API unsigned int zend_canary()
7176+{
7177+ time_t t;
7178+ unsigned int canary;
7179+ int fd;
7180+
7181+ fd = open("/dev/urandom", 0);
7182+ if (fd != -1) {
7183+ int r = read(fd, &canary, sizeof(canary));
7184+ close(fd);
7185+ if (r == sizeof(canary)) {
7186+ return (canary);
7187+ }
7188+ }
7189+ /* not good but we never want to do this */
7190+ time(&t);
7191+ canary = *(unsigned int *)&t + getpid() << 16;
7192+ return (canary);
7193+}
7194+#endif
7195+
7196+
7197+/*
7198+ * Local variables:
7199+ * tab-width: 4
7200+ * c-basic-offset: 4
7201+ * End:
7202+ * vim600: sw=4 ts=4 fdm=marker
7203+ * vim<600: sw=4 ts=4
7204+ */
7205diff -Nura php-5.1.4/Zend/zend_compile.c hardening-patch-5.1.4-0.4.13/Zend/zend_compile.c
7206--- php-5.1.4/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200
7207+++ hardening-patch-5.1.4-0.4.13/Zend/zend_compile.c 2006-08-07 11:04:07.000000000 +0200
7208@@ -1093,6 +1093,13 @@
7209 op_array.prototype = NULL;
7210
7211 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
7212+#if HARDENING_PATCH
7213+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7214+ op_array.created_by_eval = 1;
7215+ } else {
7216+ op_array.created_by_eval = 0;
7217+ }
7218+#endif
7219
7220 if (is_method) {
7221 char *short_class_name = CG(active_class_entry)->name;
7222diff -Nura php-5.1.4/Zend/zend_compile.h hardening-patch-5.1.4-0.4.13/Zend/zend_compile.h
7223--- php-5.1.4/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100
7224+++ hardening-patch-5.1.4-0.4.13/Zend/zend_compile.h 2006-08-07 11:04:07.000000000 +0200
7225@@ -217,6 +217,9 @@
7226 zend_uint doc_comment_len;
7227
7228 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
7229+#if HARDENING_PATCH
7230+ zend_bool created_by_eval;
7231+#endif
7232 };
7233
7234
7235@@ -295,6 +298,8 @@
7236 zval ***CVs;
7237 zend_bool original_in_execution;
7238 HashTable *symbol_table;
7239+ zend_uint original_in_code_type;
7240+ zend_uint execute_depth;
7241 struct _zend_execute_data *prev_execute_data;
7242 zval *old_error_reporting;
7243 };
7244@@ -617,6 +622,7 @@
7245 #define ZEND_OVERLOADED_FUNCTION 3
7246 #define ZEND_EVAL_CODE 4
7247 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
7248+#define ZEND_SANDBOX_CODE 6
7249
7250 #define ZEND_INTERNAL_CLASS 1
7251 #define ZEND_USER_CLASS 2
7252diff -Nura php-5.1.4/Zend/zend_constants.c hardening-patch-5.1.4-0.4.13/Zend/zend_constants.c
7253--- php-5.1.4/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100
7254+++ hardening-patch-5.1.4-0.4.13/Zend/zend_constants.c 2006-08-07 11:04:07.000000000 +0200
7255@@ -109,6 +109,74 @@
7256 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
7257
7258 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
7259+#if HARDENING_PATCH
7260+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
7261+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
7262+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
7263+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
7264+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
7265+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
7266+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
7267+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
7268+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
7269+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
7270+
7271+ /* error levels */
7272+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
7273+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
7274+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
7275+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
7276+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
7277+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
7278+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
7279+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
7280+ /* facility: type of program logging the message */
7281+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
7282+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
7283+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
7284+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
7285+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
7286+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
7287+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
7288+#ifdef LOG_NEWS
7289+ /* No LOG_NEWS on HP-UX */
7290+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
7291+#endif
7292+#ifdef LOG_UUCP
7293+ /* No LOG_UUCP on HP-UX */
7294+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
7295+#endif
7296+#ifdef LOG_CRON
7297+ /* apparently some systems don't have this one */
7298+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
7299+#endif
7300+#ifdef LOG_AUTHPRIV
7301+ /* AIX doesn't have LOG_AUTHPRIV */
7302+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7303+#endif
7304+#if !defined(PHP_WIN32) && !defined(NETWARE)
7305+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7306+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7307+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7308+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7309+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7310+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7311+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7312+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7313+#endif
7314+ /* options */
7315+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7316+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7317+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7318+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7319+#ifdef LOG_NOWAIT
7320+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7321+#endif
7322+#ifdef LOG_PERROR
7323+ /* AIX doesn't have LOG_PERROR */
7324+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7325+#endif
7326+#endif
7327
7328 /* true/false constants */
7329 {
7330diff -Nura php-5.1.4/Zend/zend_errors.h hardening-patch-5.1.4-0.4.13/Zend/zend_errors.h
7331--- php-5.1.4/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100
7332+++ hardening-patch-5.1.4-0.4.13/Zend/zend_errors.h 2006-08-07 11:04:07.000000000 +0200
7333@@ -38,6 +38,19 @@
7334 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
7335 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7336
7337+#if HARDENING_PATCH
7338+#define S_MEMORY (1<<0L)
7339+#define S_VARS (1<<1L)
7340+#define S_FILES (1<<2L)
7341+#define S_INCLUDE (1<<3L)
7342+#define S_SQL (1<<4L)
7343+#define S_EXECUTOR (1<<5L)
7344+#define S_MAIL (1<<6L)
7345+#define S_MISC (1<<30L)
7346+#define S_INTERNAL (1<<29L)
7347+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR)
7348+#endif
7349+
7350 #endif /* ZEND_ERRORS_H */
7351
7352 /*
7353diff -Nura php-5.1.4/Zend/zend_execute_API.c hardening-patch-5.1.4-0.4.13/Zend/zend_execute_API.c
7354--- php-5.1.4/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200
7355+++ hardening-patch-5.1.4-0.4.13/Zend/zend_execute_API.c 2006-08-07 11:04:07.000000000 +0200
7356@@ -142,6 +142,7 @@
7357 EG(class_table) = CG(class_table);
7358
7359 EG(in_execution) = 0;
7360+ EG(in_code_type) = 0;
7361 EG(in_autoload) = NULL;
7362 EG(autoload_func) = NULL;
7363
7364@@ -784,6 +785,39 @@
7365 if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
7366 EX(function_state).function = NULL;
7367 }
7368+#if HARDENING_PATCH
7369+ else {
7370+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7371+ if (HG(eval_whitelist) != NULL) {
7372+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
7373+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
7374+ efree(function_name_lc);
7375+ zend_bailout();
7376+ }
7377+ } else if (HG(eval_blacklist) != NULL) {
7378+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
7379+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
7380+ efree(function_name_lc);
7381+ zend_bailout();
7382+ }
7383+ }
7384+ }
7385+
7386+ if (HG(func_whitelist) != NULL) {
7387+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
7388+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
7389+ efree(function_name_lc);
7390+ zend_bailout();
7391+ }
7392+ } else if (HG(func_blacklist) != NULL) {
7393+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
7394+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
7395+ efree(function_name_lc);
7396+ zend_bailout();
7397+ }
7398+ }
7399+ }
7400+#endif
7401 efree(function_name_lc);
7402 }
7403
7404@@ -1076,7 +1110,7 @@
7405 return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
7406 }
7407
7408-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7409+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7410 {
7411 zval pv;
7412 zend_op_array *new_op_array;
7413@@ -1109,6 +1143,7 @@
7414 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7415 zend_op **original_opline_ptr = EG(opline_ptr);
7416
7417+ new_op_array->type = type;
7418 EG(return_value_ptr_ptr) = &local_retval_ptr;
7419 EG(active_op_array) = new_op_array;
7420 EG(no_extensions)=1;
7421@@ -1143,6 +1178,12 @@
7422 }
7423
7424
7425+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7426+{
7427+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7428+}
7429+
7430+
7431 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
7432 {
7433 int result;
7434diff -Nura php-5.1.4/Zend/zend_execute.c hardening-patch-5.1.4-0.4.13/Zend/zend_execute.c
7435--- php-5.1.4/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100
7436+++ hardening-patch-5.1.4-0.4.13/Zend/zend_execute.c 2006-08-07 11:04:07.000000000 +0200
7437@@ -1351,6 +1351,37 @@
7438 /* OBJ-TBI - doesn't support new object model! */
7439 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
7440 }
7441+#if HARDENING_PATCH
7442+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7443+ if (HG(eval_whitelist) != NULL) {
7444+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7445+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7446+ efree(lcname);
7447+ zend_bailout();
7448+ }
7449+ } else if (HG(eval_blacklist) != NULL) {
7450+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7451+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7452+ efree(lcname);
7453+ zend_bailout();
7454+ }
7455+ }
7456+ }
7457+
7458+ if (HG(func_whitelist) != NULL) {
7459+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7460+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7461+ efree(lcname);
7462+ zend_bailout();
7463+ }
7464+ } else if (HG(func_blacklist) != NULL) {
7465+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7466+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7467+ efree(lcname);
7468+ zend_bailout();
7469+ }
7470+ }
7471+#endif
7472
7473 return 0;
7474 }
7475@@ -1396,6 +1427,7 @@
7476 efree(EX(Ts)); \
7477 } \
7478 EG(in_execution) = EX(original_in_execution); \
7479+ EG(in_code_type) = EX(original_in_code_type); \
7480 EG(current_execute_data) = EX(prev_execute_data); \
7481 ZEND_VM_RETURN()
7482
7483diff -Nura php-5.1.4/Zend/zend_extensions.c hardening-patch-5.1.4-0.4.13/Zend/zend_extensions.c
7484--- php-5.1.4/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100
7485+++ hardening-patch-5.1.4-0.4.13/Zend/zend_extensions.c 2006-08-07 11:04:07.000000000 +0200
7486@@ -55,23 +55,44 @@
7487 return FAILURE;
7488 }
7489
7490+ /* check if module is compiled against Hardening-Patch */
7491+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7492+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7493+ "The Hardening-Patch version %d is installed.\n\n",
7494+ new_extension->name,
7495+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7496+ DL_UNLOAD(handle);
7497+ return FAILURE;
7498+ }
7499+
7500+
7501+ /* check if module is compiled against correct Hardening-Patch version */
7502+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7503+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7504+ "The Hardening-Patch version %d is installed.\n\n",
7505+ new_extension->name,
7506+ extension_version_info->zend_extension_api_no,
7507+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7508+ DL_UNLOAD(handle);
7509+ return FAILURE;
7510+ }
7511
7512 /* allow extension to proclaim compatibility with any Zend version */
7513- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7514- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7515+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7516+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7517 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7518 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7519 new_extension->name,
7520- extension_version_info->zend_extension_api_no,
7521+ extension_version_info->real_zend_extension_api_no,
7522 ZEND_EXTENSION_API_NO);
7523 DL_UNLOAD(handle);
7524 return FAILURE;
7525- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7526+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7527 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7528 "The Zend Engine API version %d which is installed, is newer.\n"
7529 "Contact %s at %s for a later version of %s.\n\n",
7530 new_extension->name,
7531- extension_version_info->zend_extension_api_no,
7532+ extension_version_info->real_zend_extension_api_no,
7533 ZEND_EXTENSION_API_NO,
7534 new_extension->author,
7535 new_extension->URL,
7536diff -Nura php-5.1.4/Zend/zend_extensions.h hardening-patch-5.1.4-0.4.13/Zend/zend_extensions.h
7537--- php-5.1.4/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100
7538+++ hardening-patch-5.1.4-0.4.13/Zend/zend_extensions.h 2006-08-07 11:04:07.000000000 +0200
7539@@ -24,9 +24,11 @@
7540
7541 #include "zend_compile.h"
7542
7543-/* The first number is the engine version and the rest is the date.
7544+/* The first API number is a flag saying that Hardening-Patch is used.
7545+ * The second number is the engine version and the date.
7546 * This way engine 2 API no. is always greater than engine 1 API no..
7547 */
7548+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106
7549 #define ZEND_EXTENSION_API_NO 220051025
7550
7551 typedef struct _zend_extension_version_info {
7552@@ -34,6 +36,7 @@
7553 char *required_zend_version;
7554 unsigned char thread_safe;
7555 unsigned char debug;
7556+ int real_zend_extension_api_no;
7557 } zend_extension_version_info;
7558
7559
7560@@ -101,7 +104,7 @@
7561
7562
7563 #define ZEND_EXTENSION() \
7564- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7565+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
7566
7567 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7568 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7569diff -Nura php-5.1.4/Zend/zend_globals.h hardening-patch-5.1.4-0.4.13/Zend/zend_globals.h
7570--- php-5.1.4/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100
7571+++ hardening-patch-5.1.4-0.4.13/Zend/zend_globals.h 2006-08-07 11:04:07.000000000 +0200
7572@@ -180,6 +180,16 @@
7573
7574 int error_reporting;
7575 int orig_error_reporting;
7576+#if HARDENING_PATCH
7577+ int hphp_log_syslog;
7578+ int hphp_log_syslog_facility;
7579+ int hphp_log_syslog_priority;
7580+ int hphp_log_sapi;
7581+ int hphp_log_script;
7582+ char *hphp_log_scriptname;
7583+ zend_bool hphp_log_use_x_forwarded_for;
7584+ long hphp_executor_max_depth;
7585+#endif
7586 int exit_status;
7587
7588 zend_op_array *active_op_array;
7589@@ -197,6 +207,7 @@
7590 int ticks_count;
7591
7592 zend_bool in_execution;
7593+ zend_uint in_code_type;
7594 HashTable *in_autoload;
7595 zend_function *autoload_func;
7596 zend_bool bailout_set;
7597diff -Nura php-5.1.4/Zend/zend.h hardening-patch-5.1.4-0.4.13/Zend/zend.h
7598--- php-5.1.4/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200
7599+++ hardening-patch-5.1.4-0.4.13/Zend/zend.h 2006-08-07 11:04:07.000000000 +0200
7600@@ -297,6 +297,7 @@
7601 /* Variable information */
7602 zvalue_value value; /* value */
7603 zend_uint refcount;
7604+ zend_ushort flags;
7605 zend_uchar type; /* active type */
7606 zend_uchar is_ref;
7607 };
7608@@ -382,6 +383,12 @@
7609 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7610 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
7611 char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
7612+#if HARDENING_PATCH
7613+ void (*security_log_function)(int loglevel, char *fmt, ...);
7614+#endif
7615+#if HARDENING_PATCH_INC_PROTECT
7616+ int (*is_valid_include)(zval *z);
7617+#endif
7618 } zend_utility_functions;
7619
7620
7621@@ -519,7 +526,16 @@
7622 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7623 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
7624 extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
7625+#if HARDENING_PATCH
7626+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7627+#endif
7628+#if HARDENING_PATCH_INC_PROTECT
7629+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7630+#endif
7631
7632+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7633+ZEND_API unsigned int zend_canary(void);
7634+#endif
7635
7636 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
7637
7638@@ -644,6 +660,11 @@
7639
7640 #include "zend_variables.h"
7641
7642+#if HARDENING_PATCH
7643+#include "hardened_globals.h"
7644+#include "php_syslog.h"
7645+#endif
7646+
7647 #endif /* ZEND_H */
7648
7649 /*
7650diff -Nura php-5.1.4/Zend/zend_hash.c hardening-patch-5.1.4-0.4.13/Zend/zend_hash.c
7651--- php-5.1.4/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200
7652+++ hardening-patch-5.1.4-0.4.13/Zend/zend_hash.c 2006-08-07 11:04:07.000000000 +0200
7653@@ -21,6 +21,18 @@
7654
7655 #include "zend.h"
7656
7657+#if HARDENING_PATCH_HASH_PROTECT
7658+ unsigned int zend_hash_canary = 0x1234567;
7659+ zend_bool zend_hash_canary_inited = 0;
7660+#endif
7661+
7662+#define CHECK_HASH_CANARY(hash) \
7663+ if (zend_hash_canary != (hash)->canary) { \
7664+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7665+ exit(1); \
7666+ }
7667+
7668+
7669 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
7670 (element)->pNext = (list_head); \
7671 (element)->pLast = NULL; \
7672@@ -138,6 +150,9 @@
7673 {
7674 uint i = 3;
7675 Bucket **tmp;
7676+#if HARDENING_PATCH_HASH_PROTECT
7677+ TSRMLS_FETCH();
7678+#endif
7679
7680 SET_INCONSISTENT(HT_OK);
7681
7682@@ -147,6 +162,13 @@
7683
7684 ht->nTableSize = 1 << i;
7685 ht->nTableMask = ht->nTableSize - 1;
7686+#if HARDENING_PATCH_HASH_PROTECT
7687+ if (zend_hash_canary_inited==0) {
7688+ zend_hash_canary = zend_canary();
7689+ zend_hash_canary_inited = 1;
7690+ }
7691+ ht->canary = zend_hash_canary;
7692+#endif
7693 ht->pDestructor = pDestructor;
7694 ht->arBuckets = NULL;
7695 ht->pListHead = NULL;
7696@@ -226,6 +248,9 @@
7697 }
7698 #endif
7699 if (ht->pDestructor) {
7700+#if HARDENING_PATCH_HASH_PROTECT
7701+ CHECK_HASH_CANARY(ht);
7702+#endif
7703 ht->pDestructor(p->pData);
7704 }
7705 UPDATE_DATA(ht, p, pData, nDataSize);
7706@@ -291,6 +316,9 @@
7707 }
7708 #endif
7709 if (ht->pDestructor) {
7710+#if HARDENING_PATCH_HASH_PROTECT
7711+ CHECK_HASH_CANARY(ht);
7712+#endif
7713 ht->pDestructor(p->pData);
7714 }
7715 UPDATE_DATA(ht, p, pData, nDataSize);
7716@@ -366,6 +394,9 @@
7717 }
7718 #endif
7719 if (ht->pDestructor) {
7720+#if HARDENING_PATCH_HASH_PROTECT
7721+ CHECK_HASH_CANARY(ht);
7722+#endif
7723 ht->pDestructor(p->pData);
7724 }
7725 UPDATE_DATA(ht, p, pData, nDataSize);
7726@@ -414,7 +445,7 @@
7727 IS_CONSISTENT(ht);
7728
7729 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7730- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7731+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7732 if (t) {
7733 HANDLE_BLOCK_INTERRUPTIONS();
7734 ht->arBuckets = t;
7735@@ -424,6 +455,7 @@
7736 HANDLE_UNBLOCK_INTERRUPTIONS();
7737 return SUCCESS;
7738 }
7739+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7740 return FAILURE;
7741 }
7742 return SUCCESS;
7743@@ -489,6 +521,9 @@
7744 ht->pInternalPointer = p->pListNext;
7745 }
7746 if (ht->pDestructor) {
7747+#if HARDENING_PATCH_HASH_PROTECT
7748+ CHECK_HASH_CANARY(ht);
7749+#endif
7750 ht->pDestructor(p->pData);
7751 }
7752 if (p->pData != &p->pDataPtr) {
7753@@ -513,6 +548,11 @@
7754
7755 SET_INCONSISTENT(HT_IS_DESTROYING);
7756
7757+#if HARDENING_PATCH_HASH_PROTECT
7758+ if (ht->pDestructor) {
7759+ CHECK_HASH_CANARY(ht);
7760+ }
7761+#endif
7762 p = ht->pListHead;
7763 while (p != NULL) {
7764 q = p;
7765@@ -539,6 +579,11 @@
7766
7767 SET_INCONSISTENT(HT_CLEANING);
7768
7769+#if HARDENING_PATCH_HASH_PROTECT
7770+ if (ht->pDestructor) {
7771+ CHECK_HASH_CANARY(ht);
7772+ }
7773+#endif
7774 p = ht->pListHead;
7775 while (p != NULL) {
7776 q = p;
7777@@ -573,6 +618,9 @@
7778 HANDLE_BLOCK_INTERRUPTIONS();
7779
7780 if (ht->pDestructor) {
7781+#if HARDENING_PATCH_HASH_PROTECT
7782+ CHECK_HASH_CANARY(ht);
7783+#endif
7784 ht->pDestructor(p->pData);
7785 }
7786 if (p->pData != &p->pDataPtr) {
7787diff -Nura php-5.1.4/Zend/zend_hash.h hardening-patch-5.1.4-0.4.13/Zend/zend_hash.h
7788--- php-5.1.4/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100
7789+++ hardening-patch-5.1.4-0.4.13/Zend/zend_hash.h 2006-08-07 11:04:07.000000000 +0200
7790@@ -58,6 +58,9 @@
7791 } Bucket;
7792
7793 typedef struct _hashtable {
7794+#if HARDENING_PATCH_HASH_PROTECT
7795+ unsigned int canary;
7796+#endif
7797 uint nTableSize;
7798 uint nTableMask;
7799 uint nNumOfElements;
7800diff -Nura php-5.1.4/Zend/zend_language_scanner.l hardening-patch-5.1.4-0.4.13/Zend/zend_language_scanner.l
7801--- php-5.1.4/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200
7802+++ hardening-patch-5.1.4-0.4.13/Zend/zend_language_scanner.l 2006-08-07 11:04:07.000000000 +0200
7803@@ -389,6 +389,13 @@
7804 compilation_successful=0;
7805 } else {
7806 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7807+#if HARDENING_PATCH
7808+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7809+ op_array->created_by_eval = 1;
7810+ } else {
7811+ op_array->created_by_eval = 0;
7812+ }
7813+#endif
7814 CG(in_compilation) = 1;
7815 CG(active_op_array) = op_array;
7816 compiler_result = zendparse(TSRMLS_C);
7817diff -Nura php-5.1.4/Zend/zend_language_scanner.c hardening-patch-5.1.4-0.4.13/Zend/zend_language_scanner.c
7818--- php-5.1.4/Zend/zend_language_scanner.c 2006-05-12 16:41:13.000000000 +0200
7819+++ hardening-patch-5.1.4-0.4.13/Zend/zend_language_scanner.c 2006-08-07 11:04:07.000000000 +0200
7820@@ -3075,6 +3075,13 @@
7821 compilation_successful=0;
7822 } else {
7823 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7824+#if HARDENING_PATCH
7825+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7826+ op_array->created_by_eval = 1;
7827+ } else {
7828+ op_array->created_by_eval = 0;
7829+ }
7830+#endif
7831 CG(in_compilation) = 1;
7832 CG(active_op_array) = op_array;
7833 compiler_result = zendparse(TSRMLS_C);
7834diff -Nura php-5.1.4/Zend/zend_llist.c hardening-patch-5.1.4-0.4.13/Zend/zend_llist.c
7835--- php-5.1.4/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100
7836+++ hardening-patch-5.1.4-0.4.13/Zend/zend_llist.c 2006-08-07 11:04:07.000000000 +0200
7837@@ -22,9 +22,49 @@
7838 #include "zend.h"
7839 #include "zend_llist.h"
7840 #include "zend_qsort.h"
7841+#include "zend_globals.h"
7842+
7843+#if HARDENING_PATCH_LL_PROTECT
7844+ unsigned int zend_llist_canary_1 = 0x1234567;
7845+ unsigned int zend_llist_canary_2 = 0x1553425;
7846+ zend_bool zend_llist_canary_inited = 0;
7847+#endif
7848+
7849+#define CHECK_LIST_CANARY(list) \
7850+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7851+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7852+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7853+ exit(1); \
7854+ }
7855+
7856+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7857+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7858+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7859+ exit(1); \
7860+ }
7861+
7862
7863 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7864 {
7865+#if HARDENING_PATCH_LL_PROTECT
7866+ TSRMLS_FETCH();
7867+
7868+ if (persistent) {
7869+ if (!zend_llist_canary_inited) {
7870+ /* do not change order to ensure thread safety */
7871+ zend_llist_canary_1 = zend_canary();
7872+ zend_llist_canary_2 = zend_canary();
7873+ zend_llist_canary_inited = 1;
7874+ }
7875+ } else
7876+ if (!HG(ll_canary_inited)) {
7877+ HG(canary_3) = zend_canary();
7878+ HG(canary_4) = zend_canary();
7879+ HG(ll_canary_inited) = 1;
7880+ }
7881+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7882+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7883+#endif
7884 l->head = NULL;
7885 l->tail = NULL;
7886 l->count = 0;
7887@@ -38,6 +78,11 @@
7888 {
7889 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7890
7891+#if HARDENING_PATCH_LL_PROTECT
7892+ TSRMLS_FETCH();
7893+ CHECK_LIST_CANARY(l)
7894+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7895+#endif
7896 tmp->prev = l->tail;
7897 tmp->next = NULL;
7898 if (l->tail) {
7899@@ -56,6 +101,11 @@
7900 {
7901 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7902
7903+#if HARDENING_PATCH_LL_PROTECT
7904+ TSRMLS_FETCH();
7905+ CHECK_LIST_CANARY(l)
7906+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7907+#endif
7908 tmp->next = l->head;
7909 tmp->prev = NULL;
7910 if (l->head) {
7911@@ -93,10 +143,20 @@
7912 zend_llist_element *current=l->head;
7913 zend_llist_element *next;
7914
7915+#if HARDENING_PATCH_LL_PROTECT
7916+ TSRMLS_FETCH();
7917+ CHECK_LIST_CANARY(l)
7918+#endif
7919 while (current) {
7920+#if HARDENING_PATCH_LL_PROTECT
7921+ CHECK_LISTELEMENT_CANARY(current, l)
7922+#endif
7923 next = current->next;
7924 if (compare(current->data, element)) {
7925 DEL_LLIST_ELEMENT(current, l);
7926+#if HARDENING_PATCH_LL_PROTECT
7927+ current->canary = 0;
7928+#endif
7929 break;
7930 }
7931 current = next;
7932@@ -108,7 +168,14 @@
7933 {
7934 zend_llist_element *current=l->head, *next;
7935
7936+#if HARDENING_PATCH_LL_PROTECT
7937+ TSRMLS_FETCH();
7938+ CHECK_LIST_CANARY(l)
7939+#endif
7940 while (current) {
7941+#if HARDENING_PATCH_LL_PROTECT
7942+ CHECK_LISTELEMENT_CANARY(current, l)
7943+#endif
7944 next = current->next;
7945 if (l->dtor) {
7946 l->dtor(current->data);
7947@@ -133,7 +200,14 @@
7948 zend_llist_element *old_tail;
7949 void *data;
7950
7951+#if HARDENING_PATCH_LL_PROTECT
7952+ TSRMLS_FETCH();
7953+ CHECK_LIST_CANARY(l)
7954+#endif
7955 if ((old_tail = l->tail)) {
7956+#if HARDENING_PATCH_LL_PROTECT
7957+ CHECK_LISTELEMENT_CANARY(old_tail, l)
7958+#endif
7959 if (l->tail->prev) {
7960 l->tail->prev->next = NULL;
7961 }
7962@@ -159,9 +233,16 @@
7963 {
7964 zend_llist_element *ptr;
7965
7966+#if HARDENING_PATCH_LL_PROTECT
7967+ TSRMLS_FETCH();
7968+ CHECK_LIST_CANARY(src)
7969+#endif
7970 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7971 ptr = src->head;
7972 while (ptr) {
7973+#if HARDENING_PATCH_LL_PROTECT
7974+ CHECK_LISTELEMENT_CANARY(ptr, src)
7975+#endif
7976 zend_llist_add_element(dst, ptr->data);
7977 ptr = ptr->next;
7978 }
7979@@ -172,11 +253,21 @@
7980 {
7981 zend_llist_element *element, *next;
7982
7983+#if HARDENING_PATCH_LL_PROTECT
7984+ TSRMLS_FETCH();
7985+ CHECK_LIST_CANARY(l)
7986+#endif
7987 element=l->head;
7988 while (element) {
7989+#if HARDENING_PATCH_LL_PROTECT
7990+ CHECK_LISTELEMENT_CANARY(element, l)
7991+#endif
7992 next = element->next;
7993 if (func(element->data)) {
7994 DEL_LLIST_ELEMENT(element, l);
7995+#if HARDENING_PATCH_LL_PROTECT
7996+ element->canary = 0;
7997+#endif
7998 }
7999 element = next;
8000 }
8001@@ -187,7 +278,13 @@
8002 {
8003 zend_llist_element *element;
8004
8005+#if HARDENING_PATCH_LL_PROTECT
8006+ CHECK_LIST_CANARY(l)
8007+#endif
8008 for (element=l->head; element; element=element->next) {
8009+#if HARDENING_PATCH_LL_PROTECT
8010+ CHECK_LISTELEMENT_CANARY(element, l)
8011+#endif
8012 func(element->data TSRMLS_CC);
8013 }
8014 }
8015@@ -199,6 +296,9 @@
8016 zend_llist_element **elements;
8017 zend_llist_element *element, **ptr;
8018
8019+#if HARDENING_PATCH_LL_PROTECT
8020+ CHECK_LIST_CANARY(l)
8021+#endif
8022 if (l->count <= 0) {
8023 return;
8024 }
8025@@ -208,6 +308,9 @@
8026 ptr = &elements[0];
8027
8028 for (element=l->head; element; element=element->next) {
8029+#if HARDENING_PATCH_LL_PROTECT
8030+ CHECK_LISTELEMENT_CANARY(element, l)
8031+#endif
8032 *ptr++ = element;
8033 }
8034
8035@@ -230,7 +333,13 @@
8036 {
8037 zend_llist_element *element;
8038
8039+#if HARDENING_PATCH_LL_PROTECT
8040+ CHECK_LIST_CANARY(l)
8041+#endif
8042 for (element=l->head; element; element=element->next) {
8043+#if HARDENING_PATCH_LL_PROTECT
8044+ CHECK_LISTELEMENT_CANARY(element, l)
8045+#endif
8046 func(element->data, arg TSRMLS_CC);
8047 }
8048 }
8049@@ -241,8 +350,14 @@
8050 zend_llist_element *element;
8051 va_list args;
8052
8053+#if HARDENING_PATCH_LL_PROTECT
8054+ CHECK_LIST_CANARY(l)
8055+#endif
8056 va_start(args, num_args);
8057 for (element=l->head; element; element=element->next) {
8058+#if HARDENING_PATCH_LL_PROTECT
8059+ CHECK_LISTELEMENT_CANARY(element, l)
8060+#endif
8061 func(element->data, num_args, args TSRMLS_CC);
8062 }
8063 va_end(args);
8064@@ -251,6 +366,10 @@
8065
8066 ZEND_API int zend_llist_count(zend_llist *l)
8067 {
8068+#if HARDENING_PATCH_LL_PROTECT
8069+ TSRMLS_FETCH();
8070+ CHECK_LIST_CANARY(l)
8071+#endif
8072 return l->count;
8073 }
8074
8075@@ -259,8 +378,15 @@
8076 {
8077 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8078
8079+#if HARDENING_PATCH_LL_PROTECT
8080+ TSRMLS_FETCH();
8081+ CHECK_LIST_CANARY(l)
8082+#endif
8083 *current = l->head;
8084 if (*current) {
8085+#if HARDENING_PATCH_LL_PROTECT
8086+ CHECK_LISTELEMENT_CANARY(*current, l)
8087+#endif
8088 return (*current)->data;
8089 } else {
8090 return NULL;
8091@@ -272,8 +398,15 @@
8092 {
8093 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8094
8095+#if HARDENING_PATCH_LL_PROTECT
8096+ TSRMLS_FETCH();
8097+ CHECK_LIST_CANARY(l)
8098+#endif
8099 *current = l->tail;
8100 if (*current) {
8101+#if HARDENING_PATCH_LL_PROTECT
8102+ CHECK_LISTELEMENT_CANARY(*current, l)
8103+#endif
8104 return (*current)->data;
8105 } else {
8106 return NULL;
8107@@ -285,9 +418,19 @@
8108 {
8109 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8110
8111+#if HARDENING_PATCH_LL_PROTECT
8112+ TSRMLS_FETCH();
8113+ CHECK_LIST_CANARY(l)
8114+#endif
8115 if (*current) {
8116+#if HARDENING_PATCH_LL_PROTECT
8117+ CHECK_LISTELEMENT_CANARY(*current, l)
8118+#endif
8119 *current = (*current)->next;
8120 if (*current) {
8121+#if HARDENING_PATCH_LL_PROTECT
8122+ CHECK_LISTELEMENT_CANARY(*current, l)
8123+#endif
8124 return (*current)->data;
8125 }
8126 }
8127@@ -299,9 +442,19 @@
8128 {
8129 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8130
8131+#if HARDENING_PATCH_LL_PROTECT
8132+ TSRMLS_FETCH();
8133+ CHECK_LIST_CANARY(l)
8134+#endif
8135 if (*current) {
8136+#if HARDENING_PATCH_LL_PROTECT
8137+ CHECK_LISTELEMENT_CANARY(*current, l)
8138+#endif
8139 *current = (*current)->prev;
8140 if (*current) {
8141+#if HARDENING_PATCH_LL_PROTECT
8142+ CHECK_LISTELEMENT_CANARY(*current, l)
8143+#endif
8144 return (*current)->data;
8145 }
8146 }
8147diff -Nura php-5.1.4/Zend/zend_llist.h hardening-patch-5.1.4-0.4.13/Zend/zend_llist.h
8148--- php-5.1.4/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100
8149+++ hardening-patch-5.1.4-0.4.13/Zend/zend_llist.h 2006-08-07 11:04:07.000000000 +0200
8150@@ -23,6 +23,9 @@
8151 #define ZEND_LLIST_H
8152
8153 typedef struct _zend_llist_element {
8154+#if HARDENING_PATCH_LL_PROTECT
8155+ unsigned int canary, padding;
8156+#endif
8157 struct _zend_llist_element *next;
8158 struct _zend_llist_element *prev;
8159 char data[1]; /* Needs to always be last in the struct */
8160@@ -35,6 +38,9 @@
8161 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
8162
8163 typedef struct _zend_llist {
8164+#if HARDENING_PATCH_LL_PROTECT
8165+ unsigned int canary_h; /* head */
8166+#endif
8167 zend_llist_element *head;
8168 zend_llist_element *tail;
8169 size_t count;
8170@@ -42,6 +48,9 @@
8171 llist_dtor_func_t dtor;
8172 unsigned char persistent;
8173 zend_llist_element *traverse_ptr;
8174+#if HARDENING_PATCH_LL_PROTECT
8175+ unsigned int canary_t; /* tail */
8176+#endif
8177 } zend_llist;
8178
8179 typedef zend_llist_element* zend_llist_position;
8180diff -Nura php-5.1.4/Zend/zend_modules.h hardening-patch-5.1.4-0.4.13/Zend/zend_modules.h
8181--- php-5.1.4/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200
8182+++ hardening-patch-5.1.4-0.4.13/Zend/zend_modules.h 2006-08-07 11:04:07.000000000 +0200
8183@@ -39,6 +39,7 @@
8184 extern struct _zend_arg_info fifth_arg_force_ref[6];
8185 extern struct _zend_arg_info all_args_by_ref[1];
8186
8187+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106
8188 #define ZEND_MODULE_API_NO 20050922
8189 #ifdef ZTS
8190 #define USING_ZTS 1
8191@@ -46,13 +47,13 @@
8192 #define USING_ZTS 0
8193 #endif
8194
8195-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8196+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8197 #define STANDARD_MODULE_HEADER \
8198 STANDARD_MODULE_HEADER_EX, NULL, NULL
8199 #define ZE2_STANDARD_MODULE_HEADER \
8200 STANDARD_MODULE_HEADER_EX, ini_entries, NULL
8201
8202-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8203+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8204
8205 #define STANDARD_MODULE_PROPERTIES \
8206 NULL, STANDARD_MODULE_PROPERTIES_EX
8207@@ -87,6 +88,7 @@
8208 unsigned char type;
8209 void *handle;
8210 int module_number;
8211+ unsigned int real_zend_api;
8212 };
8213
8214 #define MODULE_DEP_REQUIRED 1
8215diff -Nura php-5.1.4/Zend/zend_opcode.c hardening-patch-5.1.4-0.4.13/Zend/zend_opcode.c
8216--- php-5.1.4/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200
8217+++ hardening-patch-5.1.4-0.4.13/Zend/zend_opcode.c 2006-08-07 11:04:07.000000000 +0200
8218@@ -98,6 +98,9 @@
8219 op_array->uses_this = 0;
8220
8221 op_array->start_op = NULL;
8222+#if HARDENING_PATCH
8223+ op_array->created_by_eval = 0;
8224+#endif
8225
8226 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8227 }
8228diff -Nura php-5.1.4/Zend/zend_vm_def.h hardening-patch-5.1.4-0.4.13/Zend/zend_vm_def.h
8229--- php-5.1.4/Zend/zend_vm_def.h 2006-04-12 13:37:50.000000000 +0200
8230+++ hardening-patch-5.1.4-0.4.13/Zend/zend_vm_def.h 2006-08-07 11:04:07.000000000 +0200
8231@@ -1769,6 +1769,37 @@
8232 efree(lcname);
8233 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8234 }
8235+#if HARDENING_PATCH
8236+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8237+ if (HG(eval_whitelist) != NULL) {
8238+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8239+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8240+ efree(lcname);
8241+ zend_bailout();
8242+ }
8243+ } else if (HG(eval_blacklist) != NULL) {
8244+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8245+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8246+ efree(lcname);
8247+ zend_bailout();
8248+ }
8249+ }
8250+ }
8251+
8252+ if (HG(func_whitelist) != NULL) {
8253+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8254+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8255+ efree(lcname);
8256+ zend_bailout();
8257+ }
8258+ } else if (HG(func_blacklist) != NULL) {
8259+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8260+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8261+ efree(lcname);
8262+ zend_bailout();
8263+ }
8264+ }
8265+#endif
8266
8267 efree(lcname);
8268 if (OP2_TYPE != IS_CONST) {
8269@@ -1994,6 +2025,34 @@
8270 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
8271 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
8272 }
8273+#if HARDENING_PATCH
8274+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8275+ if (HG(eval_whitelist) != NULL) {
8276+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8277+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
8278+ zend_bailout();
8279+ }
8280+ } else if (HG(eval_blacklist) != NULL) {
8281+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8282+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
8283+ zend_bailout();
8284+ }
8285+ }
8286+ }
8287+
8288+ if (HG(func_whitelist) != NULL) {
8289+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8290+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
8291+ zend_bailout();
8292+ }
8293+ } else if (HG(func_blacklist) != NULL) {
8294+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8295+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
8296+ zend_bailout();
8297+ }
8298+ }
8299+#endif
8300+
8301 EX(object) = NULL;
8302
8303 FREE_OP1();
8304@@ -2709,7 +2768,12 @@
8305 int dummy = 1;
8306 zend_file_handle file_handle;
8307
8308- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8309+#if HARDENING_PATCH_INC_PROTECT
8310+ if (zend_is_valid_include(inc_filename)
8311+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
8312+#else
8313+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8314+#endif
8315
8316 if (!file_handle.opened_path) {
8317 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
8318@@ -2734,6 +2798,11 @@
8319 break;
8320 case ZEND_INCLUDE:
8321 case ZEND_REQUIRE:
8322+#if HARDENING_PATCH_INC_PROTECT
8323+ if (!zend_is_valid_include(inc_filename)) {
8324+ break;
8325+ }
8326+#endif
8327 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
8328 break;
8329 case ZEND_EVAL: {
8330diff -Nura php-5.1.4/Zend/zend_vm_execute.h hardening-patch-5.1.4-0.4.13/Zend/zend_vm_execute.h
8331--- php-5.1.4/Zend/zend_vm_execute.h 2006-04-12 13:37:50.000000000 +0200
8332+++ hardening-patch-5.1.4-0.4.13/Zend/zend_vm_execute.h 2006-08-07 11:04:07.000000000 +0200
8333@@ -56,6 +56,16 @@
8334 EX(symbol_table) = EG(active_symbol_table);
8335 EX(prev_execute_data) = EG(current_execute_data);
8336 EG(current_execute_data) = &execute_data;
8337+#if HARDENING_PATCH
8338+ EX(execute_depth) = 0;
8339+
8340+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
8341+ EG(in_code_type) = ZEND_EVAL_CODE;
8342+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
8343+ EG(in_code_type) = ZEND_SANDBOX_CODE;
8344+ op_array->type = ZEND_EVAL_CODE;
8345+ }
8346+#endif
8347
8348 EG(in_execution) = 1;
8349 if (op_array->start_op) {
8350@@ -81,6 +91,18 @@
8351 */
8352 EX(function_state).function_symbol_table = NULL;
8353 #endif
8354+#if HARDENING_PATCH
8355+ if (EX(prev_execute_data) == NULL) {
8356+ EX(execute_depth) = 0;
8357+ } else {
8358+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
8359+ }
8360+
8361+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
8362+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
8363+ zend_bailout();
8364+ }
8365+#endif
8366
8367 while (1) {
8368 #ifdef ZEND_WIN32
8369@@ -724,6 +746,37 @@
8370 efree(lcname);
8371 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8372 }
8373+#if HARDENING_PATCH
8374+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8375+ if (HG(eval_whitelist) != NULL) {
8376+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8377+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8378+ efree(lcname);
8379+ zend_bailout();
8380+ }
8381+ } else if (HG(eval_blacklist) != NULL) {
8382+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8383+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8384+ efree(lcname);
8385+ zend_bailout();
8386+ }
8387+ }
8388+ }
8389+
8390+ if (HG(func_whitelist) != NULL) {
8391+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8392+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8393+ efree(lcname);
8394+ zend_bailout();
8395+ }
8396+ } else if (HG(func_blacklist) != NULL) {
8397+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8398+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8399+ efree(lcname);
8400+ zend_bailout();
8401+ }
8402+ }
8403+#endif
8404
8405 efree(lcname);
8406 if (IS_CONST != IS_CONST) {
8407@@ -925,6 +978,37 @@
8408 efree(lcname);
8409 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8410 }
8411+#if HARDENING_PATCH
8412+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8413+ if (HG(eval_whitelist) != NULL) {
8414+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8415+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8416+ efree(lcname);
8417+ zend_bailout();
8418+ }
8419+ } else if (HG(eval_blacklist) != NULL) {
8420+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8421+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8422+ efree(lcname);
8423+ zend_bailout();
8424+ }
8425+ }
8426+ }
8427+
8428+ if (HG(func_whitelist) != NULL) {
8429+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8430+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8431+ efree(lcname);
8432+ zend_bailout();
8433+ }
8434+ } else if (HG(func_blacklist) != NULL) {
8435+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8436+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8437+ efree(lcname);
8438+ zend_bailout();
8439+ }
8440+ }
8441+#endif
8442
8443 efree(lcname);
8444 if (IS_TMP_VAR != IS_CONST) {
8445@@ -1083,6 +1167,37 @@
8446 efree(lcname);
8447 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8448 }
8449+#if HARDENING_PATCH
8450+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8451+ if (HG(eval_whitelist) != NULL) {
8452+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8453+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8454+ efree(lcname);
8455+ zend_bailout();
8456+ }
8457+ } else if (HG(eval_blacklist) != NULL) {
8458+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8459+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8460+ efree(lcname);
8461+ zend_bailout();
8462+ }
8463+ }
8464+ }
8465+
8466+ if (HG(func_whitelist) != NULL) {
8467+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8468+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8469+ efree(lcname);
8470+ zend_bailout();
8471+ }
8472+ } else if (HG(func_blacklist) != NULL) {
8473+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8474+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8475+ efree(lcname);
8476+ zend_bailout();
8477+ }
8478+ }
8479+#endif
8480
8481 efree(lcname);
8482 if (IS_VAR != IS_CONST) {
8483@@ -1330,6 +1445,37 @@
8484 efree(lcname);
8485 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8486 }
8487+#if HARDENING_PATCH
8488+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8489+ if (HG(eval_whitelist) != NULL) {
8490+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8491+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8492+ efree(lcname);
8493+ zend_bailout();
8494+ }
8495+ } else if (HG(eval_blacklist) != NULL) {
8496+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8497+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8498+ efree(lcname);
8499+ zend_bailout();
8500+ }
8501+ }
8502+ }
8503+
8504+ if (HG(func_whitelist) != NULL) {
8505+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8506+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8507+ efree(lcname);
8508+ zend_bailout();
8509+ }
8510+ } else if (HG(func_blacklist) != NULL) {
8511+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8512+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8513+ efree(lcname);
8514+ zend_bailout();
8515+ }
8516+ }
8517+#endif
8518
8519 efree(lcname);
8520 if (IS_CV != IS_CONST) {
8521@@ -1635,6 +1781,34 @@
8522 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
8523 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
8524 }
8525+#if HARDENING_PATCH
8526+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8527+ if (HG(eval_whitelist) != NULL) {
8528+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8529+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
8530+ zend_bailout();
8531+ }
8532+ } else if (HG(eval_blacklist) != NULL) {
8533+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8534+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
8535+ zend_bailout();
8536+ }
8537+ }
8538+ }
8539+
8540+ if (HG(func_whitelist) != NULL) {
8541+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8542+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
8543+ zend_bailout();
8544+ }
8545+ } else if (HG(func_blacklist) != NULL) {
8546+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8547+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
8548+ zend_bailout();
8549+ }
8550+ }
8551+#endif
8552+
8553 EX(object) = NULL;
8554
8555 return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
8556@@ -1914,7 +2088,12 @@
8557 int dummy = 1;
8558 zend_file_handle file_handle;
8559
8560- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8561+#if HARDENING_PATCH_INC_PROTECT
8562+ if (zend_is_valid_include(inc_filename)
8563+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
8564+#else
8565+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8566+#endif
8567
8568 if (!file_handle.opened_path) {
8569 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
8570@@ -1939,6 +2118,11 @@
8571 break;
8572 case ZEND_INCLUDE:
8573 case ZEND_REQUIRE:
8574+#if HARDENING_PATCH_INC_PROTECT
8575+ if (!zend_is_valid_include(inc_filename)) {
8576+ break;
8577+ }
8578+#endif
8579 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
8580 break;
8581 case ZEND_EVAL: {
8582diff -Nura php-5.1.4/Zend/zend_vm_execute.skl hardening-patch-5.1.4-0.4.13/Zend/zend_vm_execute.skl
8583--- php-5.1.4/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100
8584+++ hardening-patch-5.1.4-0.4.13/Zend/zend_vm_execute.skl 2006-08-07 11:04:07.000000000 +0200
8585@@ -27,6 +27,16 @@
8586 EX(symbol_table) = EG(active_symbol_table);
8587 EX(prev_execute_data) = EG(current_execute_data);
8588 EG(current_execute_data) = &execute_data;
8589+#if HARDENING_PATCH
8590+ EX(execute_depth) = 0;
8591+
8592+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
8593+ EG(in_code_type) = ZEND_EVAL_CODE;
8594+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
8595+ EG(in_code_type) = ZEND_SANDBOX_CODE;
8596+ op_array->type = ZEND_EVAL_CODE;
8597+ }
8598+#endif
8599
8600 EG(in_execution) = 1;
8601 if (op_array->start_op) {
8602@@ -52,6 +62,18 @@
8603 */
8604 EX(function_state).function_symbol_table = NULL;
8605 #endif
8606+#if HARDENING_PATCH
8607+ if (EX(prev_execute_data) == NULL) {
8608+ EX(execute_depth) = 0;
8609+ } else {
8610+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
8611+ }
8612+
8613+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
8614+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
8615+ zend_bailout();
8616+ }
8617+#endif
8618
8619 while (1) {
8620 {%ZEND_VM_CONTINUE_LABEL%}
diff --git a/0.4.6/hardening-patch-4.4.1-0.4.6.patch b/0.4.6/hardening-patch-4.4.1-0.4.6.patch
new file mode 100644
index 0000000..804d9a6
--- /dev/null
+++ b/0.4.6/hardening-patch-4.4.1-0.4.6.patch
@@ -0,0 +1,8089 @@
1diff -Nura php-4.4.1/acinclude.m4 hardening-patch-4.4.1-0.4.6/acinclude.m4
2--- php-4.4.1/acinclude.m4 2005-09-23 11:20:22.000000000 +0200
3+++ hardening-patch-4.4.1-0.4.6/acinclude.m4 2005-11-05 13:04:08.000000000 +0100
4@@ -1182,6 +1182,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.4.1/configure hardening-patch-4.4.1-0.4.6/configure
42--- php-4.4.1/configure 2005-10-30 12:06:37.000000000 +0100
43+++ hardening-patch-4.4.1-0.4.6/configure 2005-11-05 13:04:08.000000000 +0100
44@@ -395,6 +395,16 @@
45 ac_default_prefix=/usr/local
46 # Any additions from configure.in:
47 ac_help="$ac_help
48+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
49+ac_help="$ac_help
50+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
51+ac_help="$ac_help
52+ --disable-hardening-patch-inc-protect Disable include/require protection."
53+ac_help="$ac_help
54+ --disable-hardening-patch-fmt-protect Disable format string protection."
55+ac_help="$ac_help
56+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
57+ac_help="$ac_help
58
59 SAPI modules:
60 "
61@@ -847,6 +857,8 @@
62 ac_help="$ac_help
63 --disable-tokenizer Disable tokenizer support"
64 ac_help="$ac_help
65+ --disable-varfilter Disable Hardening-Patch's variable filter"
66+ac_help="$ac_help
67 --enable-wddx Enable WDDX support."
68 ac_help="$ac_help
69 --disable-xml Disable XML support using bundled expat lib"
70@@ -2828,6 +2840,157 @@
71
72
73
74+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
75+if test "${enable_hardening_patch_mm_protect+set}" = set; then
76+ enableval="$enable_hardening_patch_mm_protect"
77+
78+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
79+
80+else
81+
82+ DO_HARDENING_PATCH_MM_PROTECT=yes
83+
84+fi
85+
86+
87+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
88+if test "${enable_hardening_patch_ll_protect+set}" = set; then
89+ enableval="$enable_hardening_patch_ll_protect"
90+
91+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
92+
93+else
94+
95+ DO_HARDENING_PATCH_LL_PROTECT=yes
96+
97+fi
98+
99+
100+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
101+if test "${enable_hardening_patch_inc_protect+set}" = set; then
102+ enableval="$enable_hardening_patch_inc_protect"
103+
104+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
105+
106+else
107+
108+ DO_HARDENING_PATCH_INC_PROTECT=yes
109+
110+fi
111+
112+
113+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
114+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
115+ enableval="$enable_hardening_patch_fmt_protect"
116+
117+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
118+
119+else
120+
121+ DO_HARDENING_PATCH_FMT_PROTECT=yes
122+
123+fi
124+
125+
126+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
127+if test "${enable_hardening_patch_hash_protect+set}" = set; then
128+ enableval="$enable_hardening_patch_hash_protect"
129+
130+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
131+
132+else
133+
134+ DO_HARDENING_PATCH_HASH_PROTECT=yes
135+
136+fi
137+
138+
139+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
140+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
141+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
142+
143+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
144+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
145+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
146+
147+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
148+echo "configure:2733: checking whether to protect include/require statements" >&5
149+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
150+
151+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
152+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
153+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
154+
155+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
156+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
157+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
158+
159+
160+cat >> confdefs.h <<\EOF
161+#define HARDENING_PATCH 1
162+EOF
163+
164+
165+
166+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
167+ cat >> confdefs.h <<\EOF
168+#define HARDENING_PATCH_MM_PROTECT 1
169+EOF
170+
171+else
172+ cat >> confdefs.h <<\EOF
173+#define HARDENING_PATCH_MM_PROTECT 0
174+EOF
175+
176+fi
177+
178+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
179+ cat >> confdefs.h <<\EOF
180+#define HARDENING_PATCH_LL_PROTECT 1
181+EOF
182+
183+else
184+ cat >> confdefs.h <<\EOF
185+#define HARDENING_PATCH_LL_PROTECT 0
186+EOF
187+
188+fi
189+
190+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
191+ cat >> confdefs.h <<\EOF
192+#define HARDENING_PATCH_INC_PROTECT 1
193+EOF
194+
195+else
196+ cat >> confdefs.h <<\EOF
197+#define HARDENING_PATCH_INC_PROTECT 0
198+EOF
199+
200+fi
201+
202+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
203+ cat >> confdefs.h <<\EOF
204+#define HARDENING_PATCH_FMT_PROTECT 1
205+EOF
206+
207+else
208+ cat >> confdefs.h <<\EOF
209+#define HARDENING_PATCH_FMT_PROTECT 0
210+EOF
211+
212+fi
213+
214+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
215+ cat >> confdefs.h <<\EOF
216+#define HARDENING_PATCH_HASH_PROTECT 1
217+EOF
218+
219+else
220+ cat >> confdefs.h <<\EOF
221+#define HARDENING_PATCH_HASH_PROTECT 0
222+EOF
223+
224+fi
225
226
227
228@@ -15903,6 +16066,62 @@
229 fi
230
231
232+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
233+echo "configure:14928: checking whether realpath is broken" >&5
234+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
235+ echo $ac_n "(cached) $ac_c" 1>&6
236+else
237+
238+ if test "$cross_compiling" = yes; then
239+
240+ ac_cv_broken_realpath=no
241+
242+else
243+ cat > conftest.$ac_ext <<EOF
244+#line 14939 "configure"
245+#include "confdefs.h"
246+
247+main() {
248+ char buf[4096+1];
249+ buf[0] = 0;
250+ realpath("/etc/hosts/../passwd", buf);
251+ exit(strcmp(buf, "/etc/passwd")==0);
252+}
253+
254+EOF
255+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
256+then
257+
258+ ac_cv_broken_realpath=no
259+
260+else
261+ echo "configure: failed program was:" >&5
262+ cat conftest.$ac_ext >&5
263+ rm -fr conftest*
264+
265+ ac_cv_broken_realpath=yes
266+
267+fi
268+rm -fr conftest*
269+fi
270+
271+
272+fi
273+
274+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
275+ if test "$ac_cv_broken_realpath" = "yes"; then
276+ cat >> confdefs.h <<\EOF
277+#define PHP_BROKEN_REALPATH 1
278+EOF
279+
280+ else
281+ cat >> confdefs.h <<\EOF
282+#define PHP_BROKEN_REALPATH 0
283+EOF
284+
285+ fi
286+
287+
288 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
289 echo "configure:15908: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -86368,7 +86587,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -87070,7 +87289,7 @@
301 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
302 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
303 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
304- var_unserializer.c ftok.c aggregation.c sha1.c ; do
305+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -87125,7 +87344,7 @@
310 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
311 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
312 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
313- var_unserializer.c ftok.c aggregation.c sha1.c ; do
314+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -87251,7 +87470,7 @@
319 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
320 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
321 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
322- var_unserializer.c ftok.c aggregation.c sha1.c ; do
323+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -87303,7 +87522,7 @@
328 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
329 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
330 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
331- var_unserializer.c ftok.c aggregation.c sha1.c ; do
332+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -90774,6 +90993,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.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" ;;
428+ *.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" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.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" ;;
474+ *.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" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(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)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.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" ;;
538+ *.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" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.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" ;;
581+ *.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" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -103822,7 +104300,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 streams.c network.c php_open_temporary_file.c php_logos.c \
606- output.c memory_streams.c user_streams.c; do
607+ output.c memory_streams.c user_streams.c hardening_patch.c; do
608
609 IFS=.
610 set $ac_src
611@@ -104007,7 +104485,7 @@
612 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
613 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
614 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
615- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
616+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-4.4.1/configure.in hardening-patch-4.4.1-0.4.6/configure.in
621--- php-4.4.1/configure.in 2005-10-26 09:58:22.000000000 +0200
622+++ hardening-patch-4.4.1-0.4.6/configure.in 2005-11-05 13:04:08.000000000 +0100
623@@ -247,7 +247,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -621,6 +621,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1260,7 +1261,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 streams.c network.c php_open_temporary_file.c php_logos.c \
644- output.c memory_streams.c user_streams.c)
645+ output.c memory_streams.c user_streams.c hardening_patch.c)
646 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
647 case $host_alias in
648 *netware*)
649@@ -1281,7 +1282,7 @@
650 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
654+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
658diff -Nura php-4.4.1/ext/curl/curl.c hardening-patch-4.4.1-0.4.6/ext/curl/curl.c
659--- php-4.4.1/ext/curl/curl.c 2005-10-17 04:42:51.000000000 +0200
660+++ hardening-patch-4.4.1-0.4.6/ext/curl/curl.c 2005-11-05 13:04:08.000000000 +0100
661@@ -76,7 +76,7 @@
662 RETURN_FALSE; \
663 } \
664 \
665- if (tmp_url->query || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
666+ if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
667 (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
668 ) { \
669 php_url_free(tmp_url); \
670diff -Nura php-4.4.1/ext/fbsql/php_fbsql.c hardening-patch-4.4.1-0.4.6/ext/fbsql/php_fbsql.c
671--- php-4.4.1/ext/fbsql/php_fbsql.c 2005-02-09 20:33:32.000000000 +0100
672+++ hardening-patch-4.4.1-0.4.6/ext/fbsql/php_fbsql.c 2005-11-05 13:04:08.000000000 +0100
673@@ -1797,8 +1797,24 @@
674 }
675 else if (fbcmdErrorsFound(md))
676 {
677+#if HARDENING_PATCH
678+ char* query_copy;
679+ int i;
680+#endif
681 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
682 char* emg = fbcemdAllErrorMessages(emd);
683+#if HARDENING_PATCH
684+ query_copy=estrdup(query_copy);
685+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
686+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
687+ efree(query_copy);
688+ if (HG(hphp_sql_bailout_on_error)) {
689+ free(emg);
690+ fbcemdRelease(emd);
691+ result = 0;
692+ zend_bailout();
693+ }
694+#endif
695 if (FB_SQL_G(generateWarnings))
696 {
697 if (emg)
698diff -Nura php-4.4.1/ext/gd/gd.c hardening-patch-4.4.1-0.4.6/ext/gd/gd.c
699--- php-4.4.1/ext/gd/gd.c 2005-10-06 22:44:52.000000000 +0200
700+++ hardening-patch-4.4.1-0.4.6/ext/gd/gd.c 2005-11-05 13:04:08.000000000 +0100
701@@ -3742,13 +3742,13 @@
702 }
703
704 /* Check origin file */
705- if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC)) {
706+ if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_org, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
707 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid origin filename '%s'", fn_org);
708 RETURN_FALSE;
709 }
710
711 /* Check destination file */
712- if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC)) {
713+ if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_dest, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
714 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid destination filename '%s'", fn_dest);
715 RETURN_FALSE;
716 }
717diff -Nura php-4.4.1/ext/mbstring/mbstring.c hardening-patch-4.4.1-0.4.6/ext/mbstring/mbstring.c
718--- php-4.4.1/ext/mbstring/mbstring.c 2005-09-21 15:19:19.000000000 +0200
719+++ hardening-patch-4.4.1-0.4.6/ext/mbstring/mbstring.c 2005-11-05 13:04:08.000000000 +0100
720@@ -1488,6 +1488,7 @@
721 char *strtok_buf = NULL, **val_list;
722 zval *array_ptr = (zval *) arg;
723 int n, num, val_len, *len_list;
724+ unsigned int new_val_len;
725 enum mbfl_no_encoding from_encoding;
726 mbfl_string string, resvar, resval;
727 mbfl_encoding_detector *identd = NULL;
728@@ -1610,8 +1611,14 @@
729 val_len = len_list[n];
730 }
731 n++;
732- /* add variable to symbol table */
733- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
734+ /* we need val to be emalloc()ed */
735+ val = estrndup(val, val_len);
736+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
737+ /* add variable to symbol table */
738+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
739+ }
740+ efree(val);
741+
742 if (convd != NULL){
743 mbfl_string_clear(&resvar);
744 mbfl_string_clear(&resval);
745diff -Nura php-4.4.1/ext/mysql/php_mysql.c hardening-patch-4.4.1-0.4.6/ext/mysql/php_mysql.c
746--- php-4.4.1/ext/mysql/php_mysql.c 2005-04-08 00:23:01.000000000 +0200
747+++ hardening-patch-4.4.1-0.4.6/ext/mysql/php_mysql.c 2005-11-05 13:04:08.000000000 +0100
748@@ -1218,6 +1218,8 @@
749 {
750 php_mysql_conn *mysql;
751 MYSQL_RES *mysql_result;
752+ char *copy_query;
753+ int i;
754
755 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
756
757@@ -1268,6 +1270,13 @@
758 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
759 }
760 }
761+ copy_query = estrdup(Z_STRVAL_PP(query));
762+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
763+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
764+ efree(copy_query);
765+ if (HG(hphp_sql_bailout_on_error)) {
766+ zend_bailout();
767+ }
768 RETURN_FALSE;
769 }
770 #else
771@@ -1275,12 +1284,20 @@
772 /* check possible error */
773 if (MySG(trace_mode)){
774 if (mysql_errno(&mysql->conn)){
775- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
776+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
777 }
778 }
779+ copy_query = estrdup(Z_STRVAL_PP(query));
780+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
781+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
782+ efree(copy_query);
783+ if (HG(hphp_sql_bailout_on_error)) {
784+ zend_bailout();
785+ }
786 RETURN_FALSE;
787 }
788 #endif
789+
790 if(use_store == MYSQL_USE_RESULT) {
791 mysql_result=mysql_use_result(&mysql->conn);
792 } else {
793diff -Nura php-4.4.1/ext/pgsql/pgsql.c hardening-patch-4.4.1-0.4.6/ext/pgsql/pgsql.c
794--- php-4.4.1/ext/pgsql/pgsql.c 2005-07-05 14:50:03.000000000 +0200
795+++ hardening-patch-4.4.1-0.4.6/ext/pgsql/pgsql.c 2005-11-05 13:04:08.000000000 +0100
796@@ -1001,10 +1001,28 @@
797 case PGRES_EMPTY_QUERY:
798 case PGRES_BAD_RESPONSE:
799 case PGRES_NONFATAL_ERROR:
800- case PGRES_FATAL_ERROR:
801- PHP_PQ_ERROR("Query failed: %s", pgsql);
802- PQclear(pgsql_result);
803- RETURN_FALSE;
804+ case PGRES_FATAL_ERROR:
805+ {
806+#if HARDENING_PATCH
807+ int i;
808+ char *query_copy;
809+#endif
810+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
811+ PQclear(pgsql_result);
812+#if HARDENING_PATCH
813+ query_copy = estrdup(Z_STRVAL_PP(query));
814+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
815+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
816+ efree(query_copy);
817+ if (HG(hphp_sql_bailout_on_error)) {
818+ efree(msgbuf);
819+ zend_bailout();
820+ }
821+#endif
822+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
823+ efree(msgbuf);
824+ RETURN_FALSE;
825+ }
826 break;
827 case PGRES_COMMAND_OK: /* successful command that did not return rows */
828 default:
829diff -Nura php-4.4.1/ext/session/mod_files.c hardening-patch-4.4.1-0.4.6/ext/session/mod_files.c
830--- php-4.4.1/ext/session/mod_files.c 2005-07-25 16:06:17.000000000 +0200
831+++ hardening-patch-4.4.1-0.4.6/ext/session/mod_files.c 2005-11-26 00:29:06.000000000 +0100
832@@ -389,6 +389,34 @@
833 return SUCCESS;
834 }
835
836+PS_VALIDATE_SID_FUNC(files)
837+{
838+ char buf[MAXPATHLEN];
839+ int fd;
840+ PS_FILES_DATA;
841+
842+ if (!ps_files_valid_key(key)) {
843+ return FAILURE;
844+ }
845+
846+ if (!PS(use_strict_mode)) {
847+ return SUCCESS;
848+ }
849+
850+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
851+ return FAILURE;
852+ }
853+
854+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
855+
856+ if (fd != -1) {
857+ close(fd);
858+ return SUCCESS;
859+ }
860+
861+ return FAILURE;
862+}
863+
864 /*
865 * Local variables:
866 * tab-width: 4
867diff -Nura php-4.4.1/ext/session/mod_mm.c hardening-patch-4.4.1-0.4.6/ext/session/mod_mm.c
868--- php-4.4.1/ext/session/mod_mm.c 2004-06-30 03:12:09.000000000 +0200
869+++ hardening-patch-4.4.1-0.4.6/ext/session/mod_mm.c 2005-11-26 00:14:31.000000000 +0100
870@@ -425,6 +425,42 @@
871 return SUCCESS;
872 }
873
874+PS_VALIDATE_SID_FUNC(mm)
875+{
876+ PS_MM_DATA;
877+ ps_sd *sd;
878+ const char *p;
879+ char c;
880+ int ret = SUCCESS;
881+
882+ for (p = key; (c = *p); p++) {
883+ /* valid characters are a..z,A..Z,0..9 */
884+ if (!((c >= 'a' && c <= 'z')
885+ || (c >= 'A' && c <= 'Z')
886+ || (c >= '0' && c <= '9')
887+ || c == ','
888+ || c == '-')) {
889+ return FAILURE;
890+ }
891+ }
892+
893+ if (!PS(use_strict_mode)) {
894+ return SUCCESS;
895+ }
896+
897+ mm_lock(data->mm, MM_LOCK_RD);
898+
899+ sd = ps_sd_lookup(data, key, 0);
900+ if (sd) {
901+ mm_unlock(data->mm);
902+ return SUCCESS;
903+ }
904+
905+ mm_unlock(data->mm);
906+
907+ return FAILURE;
908+}
909+
910 #endif
911
912 /*
913diff -Nura php-4.4.1/ext/session/mod_user.c hardening-patch-4.4.1-0.4.6/ext/session/mod_user.c
914--- php-4.4.1/ext/session/mod_user.c 2002-12-31 17:35:20.000000000 +0100
915+++ hardening-patch-4.4.1-0.4.6/ext/session/mod_user.c 2005-11-26 00:14:31.000000000 +0100
916@@ -23,7 +23,7 @@
917 #include "mod_user.h"
918
919 ps_module ps_mod_user = {
920- PS_MOD(user)
921+ PS_MOD_SID(user)
922 };
923
924 #define SESS_ZVAL_LONG(val, a) \
925@@ -174,6 +174,83 @@
926 FINISH;
927 }
928
929+PS_CREATE_SID_FUNC(user)
930+{
931+ int i;
932+ char *val = NULL;
933+ zval *retval;
934+ ps_user *mdata = PS_GET_MOD_DATA();
935+
936+ if (!mdata)
937+ return estrndup("", 0);
938+
939+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
940+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
941+ }
942+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
943+
944+ if (retval) {
945+ if (Z_TYPE_P(retval) == IS_STRING) {
946+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
947+ } else {
948+ val = estrndup("", 0);
949+ }
950+ zval_ptr_dtor(&retval);
951+ } else {
952+ val = estrndup("", 0);
953+ }
954+
955+ return val;
956+}
957+
958+static int ps_user_valid_key(const char *key TSRMLS_DC)
959+{
960+ size_t len;
961+ const char *p;
962+ char c;
963+ int ret = SUCCESS;
964+
965+ for (p = key; (c = *p); p++) {
966+ /* valid characters are a..z,A..Z,0..9 */
967+ if (!((c >= 'a' && c <= 'z')
968+ || (c >= 'A' && c <= 'Z')
969+ || (c >= '0' && c <= '9')
970+ || c == ','
971+ || c == '-')) {
972+ ret = FAILURE;
973+ break;
974+ }
975+ }
976+
977+ len = p - key;
978+
979+ if (len == 0)
980+ ret = FAILURE;
981+
982+ return ret;
983+}
984+
985+PS_VALIDATE_SID_FUNC(user)
986+{
987+ zval *args[1];
988+ STDVARS;
989+
990+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
991+ return ps_user_valid_key(key TSRMLS_CC);
992+ }
993+ SESS_ZVAL_STRING(key, args[0]);
994+
995+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
996+
997+ if (retval) {
998+ convert_to_long(retval);
999+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1000+ zval_ptr_dtor(&retval);
1001+ }
1002+
1003+ return ret;
1004+}
1005+
1006 /*
1007 * Local variables:
1008 * tab-width: 4
1009diff -Nura php-4.4.1/ext/session/mod_user.h hardening-patch-4.4.1-0.4.6/ext/session/mod_user.h
1010--- php-4.4.1/ext/session/mod_user.h 2005-02-13 18:54:56.000000000 +0100
1011+++ hardening-patch-4.4.1-0.4.6/ext/session/mod_user.h 2005-11-26 00:14:31.000000000 +0100
1012@@ -22,7 +22,7 @@
1013 #define MOD_USER_H
1014
1015 typedef union {
1016- zval *names[6];
1017+ zval *names[8];
1018 struct {
1019 zval *ps_open;
1020 zval *ps_close;
1021@@ -30,6 +30,8 @@
1022 zval *ps_write;
1023 zval *ps_destroy;
1024 zval *ps_gc;
1025+ zval *ps_create;
1026+ zval *ps_validate;
1027 } name;
1028 } ps_user;
1029
1030diff -Nura php-4.4.1/ext/session/php_session.h hardening-patch-4.4.1-0.4.6/ext/session/php_session.h
1031--- php-4.4.1/ext/session/php_session.h 2005-02-13 18:54:56.000000000 +0100
1032+++ hardening-patch-4.4.1-0.4.6/ext/session/php_session.h 2005-11-26 00:15:31.000000000 +0100
1033@@ -23,7 +23,7 @@
1034
1035 #include "ext/standard/php_var.h"
1036
1037-#define PHP_SESSION_API 20020330
1038+#define PHP_SESSION_API 20051121
1039
1040 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1041 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1042@@ -32,6 +32,7 @@
1043 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1044 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1045 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1046+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1047
1048 /* default create id function */
1049 char *php_session_create_id(PS_CREATE_SID_ARGS);
1050@@ -45,6 +46,7 @@
1051 int (*s_destroy)(PS_DESTROY_ARGS);
1052 int (*s_gc)(PS_GC_ARGS);
1053 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1054+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1055 } ps_module;
1056
1057 #define PS_GET_MOD_DATA() *mod_data
1058@@ -57,6 +59,7 @@
1059 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1060 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1061 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1062+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1063
1064 #define PS_FUNCS(x) \
1065 PS_OPEN_FUNC(x); \
1066@@ -65,11 +68,12 @@
1067 PS_WRITE_FUNC(x); \
1068 PS_DESTROY_FUNC(x); \
1069 PS_GC_FUNC(x); \
1070- PS_CREATE_SID_FUNC(x)
1071+ PS_CREATE_SID_FUNC(x); \
1072+ PS_VALIDATE_SID_FUNC(x)
1073
1074 #define PS_MOD(x) \
1075 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1076- ps_delete_##x, ps_gc_##x, php_session_create_id
1077+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1078
1079 /* SID enabled module handler definitions */
1080 #define PS_FUNCS_SID(x) \
1081@@ -79,11 +83,12 @@
1082 PS_WRITE_FUNC(x); \
1083 PS_DESTROY_FUNC(x); \
1084 PS_GC_FUNC(x); \
1085- PS_CREATE_SID_FUNC(x)
1086+ PS_CREATE_SID_FUNC(x); \
1087+ PS_VALIDATE_SID(x)
1088
1089 #define PS_MOD_SID(x) \
1090 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1091- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1092+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1093
1094 typedef enum {
1095 php_session_disabled,
1096@@ -120,6 +125,7 @@
1097 zend_bool use_only_cookies;
1098 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1099 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1100+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1101 int send_cookie;
1102 int define_sid;
1103 } php_ps_globals;
1104diff -Nura php-4.4.1/ext/session/session.c hardening-patch-4.4.1-0.4.6/ext/session/session.c
1105--- php-4.4.1/ext/session/session.c 2005-09-23 10:16:01.000000000 +0200
1106+++ hardening-patch-4.4.1-0.4.6/ext/session/session.c 2005-11-26 00:25:26.000000000 +0100
1107@@ -155,6 +155,7 @@
1108 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1109 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1110 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1111+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1112 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1113 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1114 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1115@@ -637,6 +638,15 @@
1116 return;
1117 }
1118
1119+ /* If there is an ID, use session module to verify it */
1120+ if (PS(id)) {
1121+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1122+ efree(PS(id));
1123+ PS(id) = NULL;
1124+ PS(send_cookie) = 1;
1125+ }
1126+ }
1127+
1128 /* If there is no ID, use session module to create one */
1129 if (!PS(id))
1130 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1131@@ -1256,22 +1266,31 @@
1132 }
1133 /* }}} */
1134
1135-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1136+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1137 Sets user-level functions */
1138 PHP_FUNCTION(session_set_save_handler)
1139 {
1140- zval **args[6];
1141- int i;
1142+ zval **args[8];
1143+ int i, numargs;
1144 ps_user *mdata;
1145 char *name;
1146
1147+ numargs = ZEND_NUM_ARGS();
1148+ args[6] = NULL;
1149+ args[7] = NULL;
1150+
1151+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1152+ WRONG_PARAM_COUNT;
1153 if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1154 WRONG_PARAM_COUNT;
1155
1156 if (PS(session_status) != php_session_none)
1157 RETURN_FALSE;
1158
1159- for (i = 0; i < 6; i++) {
1160+ for (i = 0; i < 8; i++) {
1161+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1162+ continue;
1163+ }
1164 if (!zend_is_callable(*args[i], 0, &name)) {
1165 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1166 efree(name);
1167@@ -1284,7 +1303,11 @@
1168
1169 mdata = emalloc(sizeof(*mdata));
1170
1171- for (i = 0; i < 6; i++) {
1172+ for (i = 0; i < 8; i++) {
1173+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1174+ mdata->names[i] = NULL;
1175+ continue;
1176+ }
1177 ZVAL_ADDREF(*args[i]);
1178 mdata->names[i] = *args[i];
1179 }
1180@@ -1345,8 +1368,20 @@
1181 Update the current session id with a newly generated one. */
1182 PHP_FUNCTION(session_regenerate_id)
1183 {
1184+ zend_bool del_ses = 0;
1185+
1186+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1187+ WRONG_PARAM_COUNT;
1188+ }
1189+
1190 if (PS(session_status) == php_session_active) {
1191- if (PS(id)) efree(PS(id));
1192+ if (PS(id)) {
1193+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1194+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1195+ RETURN_FALSE;
1196+ }
1197+ efree(PS(id));
1198+ }
1199
1200 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1201
1202diff -Nura php-4.4.1/ext/session/tests/014.phpt hardening-patch-4.4.1-0.4.6/ext/session/tests/014.phpt
1203--- php-4.4.1/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1204+++ hardening-patch-4.4.1-0.4.6/ext/session/tests/014.phpt 2005-11-26 00:33:45.000000000 +0100
1205@@ -5,6 +5,7 @@
1206 --INI--
1207 session.use_trans_sid=1
1208 session.use_cookies=0
1209+session.use_strict_mode=0
1210 session.cache_limiter=
1211 register_globals=1
1212 session.bug_compat_42=1
1213diff -Nura php-4.4.1/ext/session/tests/015.phpt hardening-patch-4.4.1-0.4.6/ext/session/tests/015.phpt
1214--- php-4.4.1/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1215+++ hardening-patch-4.4.1-0.4.6/ext/session/tests/015.phpt 2005-11-26 00:33:53.000000000 +0100
1216@@ -5,6 +5,7 @@
1217 --INI--
1218 session.use_trans_sid=1
1219 session.use_cookies=0
1220+session.use_strict_mode=0
1221 session.cache_limiter=
1222 arg_separator.output=&
1223 session.name=PHPSESSID
1224diff -Nura php-4.4.1/ext/session/tests/018.phpt hardening-patch-4.4.1-0.4.6/ext/session/tests/018.phpt
1225--- php-4.4.1/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1226+++ hardening-patch-4.4.1-0.4.6/ext/session/tests/018.phpt 2005-11-26 00:34:04.000000000 +0100
1227@@ -4,6 +4,7 @@
1228 <?php include('skipif.inc'); ?>
1229 --INI--
1230 session.use_cookies=0
1231+session.use_strict_mode=0
1232 session.cache_limiter=
1233 session.use_trans_sid=1
1234 session.name=PHPSESSID
1235diff -Nura php-4.4.1/ext/session/tests/020.phpt hardening-patch-4.4.1-0.4.6/ext/session/tests/020.phpt
1236--- php-4.4.1/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1237+++ hardening-patch-4.4.1-0.4.6/ext/session/tests/020.phpt 2005-11-26 00:34:18.000000000 +0100
1238@@ -4,6 +4,7 @@
1239 <?php include('skipif.inc'); ?>
1240 --INI--
1241 session.use_cookies=0
1242+session.use_strict_mode=0
1243 session.cache_limiter=
1244 session.use_trans_sid=1
1245 arg_separator.output=&amp;
1246diff -Nura php-4.4.1/ext/session/tests/021.phpt hardening-patch-4.4.1-0.4.6/ext/session/tests/021.phpt
1247--- php-4.4.1/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1248+++ hardening-patch-4.4.1-0.4.6/ext/session/tests/021.phpt 2005-11-26 00:34:24.000000000 +0100
1249@@ -4,6 +4,7 @@
1250 <?php include('skipif.inc'); ?>
1251 --INI--
1252 session.use_cookies=0
1253+session.use_strict_mode=0
1254 session.cache_limiter=
1255 session.use_trans_sid=1
1256 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1257diff -Nura php-4.4.1/ext/standard/array.c hardening-patch-4.4.1-0.4.6/ext/standard/array.c
1258--- php-4.4.1/ext/standard/array.c 2005-10-03 16:05:07.000000000 +0200
1259+++ hardening-patch-4.4.1-0.4.6/ext/standard/array.c 2005-11-05 13:04:08.000000000 +0100
1260@@ -1162,6 +1162,32 @@
1261 }
1262 }
1263 }
1264+
1265+ if (var_name[0] == 'H') {
1266+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1267+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1268+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1269+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1270+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1271+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1272+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1273+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1274+ return 0;
1275+ }
1276+ } else if (var_name[0] == '_') {
1277+ if ((strcmp(var_name, "_COOKIE")==0)||
1278+ (strcmp(var_name, "_ENV")==0)||
1279+ (strcmp(var_name, "_FILES")==0)||
1280+ (strcmp(var_name, "_GET")==0)||
1281+ (strcmp(var_name, "_POST")==0)||
1282+ (strcmp(var_name, "_REQUEST")==0)||
1283+ (strcmp(var_name, "_SESSION")==0)||
1284+ (strcmp(var_name, "_SERVER")==0)) {
1285+ return 0;
1286+ }
1287+ } else if (strcmp(var_name, "GLOBALS")==0) {
1288+ return 0;
1289+ }
1290
1291 return 1;
1292 }
1293diff -Nura php-4.4.1/ext/standard/basic_functions.c hardening-patch-4.4.1-0.4.6/ext/standard/basic_functions.c
1294--- php-4.4.1/ext/standard/basic_functions.c 2005-09-29 18:31:48.000000000 +0200
1295+++ hardening-patch-4.4.1-0.4.6/ext/standard/basic_functions.c 2005-11-05 13:04:08.000000000 +0100
1296@@ -107,12 +107,14 @@
1297 typedef struct _php_shutdown_function_entry {
1298 zval **arguments;
1299 int arg_count;
1300+ zend_bool created_by_eval;
1301 } php_shutdown_function_entry;
1302
1303 typedef struct _user_tick_function_entry {
1304 zval **arguments;
1305 int arg_count;
1306 int calling;
1307+ zend_bool created_by_eval;
1308 } user_tick_function_entry;
1309
1310 /* some prototypes for local functions */
1311@@ -295,6 +297,8 @@
1312 PHP_FE(get_html_translation_table, NULL)
1313 PHP_FE(sha1, NULL)
1314 PHP_FE(sha1_file, NULL)
1315+ PHP_FE(sha256, NULL)
1316+ PHP_FE(sha256_file, NULL)
1317 PHP_NAMED_FE(md5,php_if_md5, NULL)
1318 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1319 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1320@@ -676,7 +680,7 @@
1321 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1322
1323 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1324- PHP_FE(realpath, NULL)
1325+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1326 #endif
1327
1328 #ifdef HAVE_FNMATCH
1329@@ -2093,6 +2097,13 @@
1330 {
1331 zval retval;
1332 char *function_name = NULL;
1333+#if HARDENING_PATCH
1334+ zend_uint orig_code_type = EG(in_code_type);
1335+
1336+ if (shutdown_function_entry->created_by_eval) {
1337+ EG(in_code_type) = ZEND_EVAL_CODE;
1338+ }
1339+#endif
1340
1341 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1342 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1343@@ -2108,6 +2119,9 @@
1344 if (function_name) {
1345 efree(function_name);
1346 }
1347+#if HARDENING_PATCH
1348+ EG(in_code_type) = orig_code_type;
1349+#endif
1350 return 0;
1351 }
1352
1353@@ -2115,6 +2129,13 @@
1354 {
1355 zval retval;
1356 zval *function = tick_fe->arguments[0];
1357+#if HARDENING_PATCH
1358+ zend_uint orig_code_type = EG(in_code_type);
1359+
1360+ if (tick_fe->created_by_eval) {
1361+ EG(in_code_type) = ZEND_EVAL_CODE;
1362+ }
1363+#endif
1364
1365 /* Prevent reentrant calls to the same user ticks function */
1366 if (! tick_fe->calling) {
1367@@ -2146,6 +2167,9 @@
1368
1369 tick_fe->calling = 0;
1370 }
1371+#if HARDENING_PATCH
1372+ EG(in_code_type) = orig_code_type;
1373+#endif
1374 }
1375
1376 static void run_user_tick_functions(int tick_count)
1377@@ -2213,6 +2237,13 @@
1378 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1379 RETURN_FALSE;
1380 }
1381+#if HARDENING_PATCH
1382+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1383+ shutdown_function_entry.created_by_eval = 1;
1384+ } else {
1385+ shutdown_function_entry.created_by_eval = 0;
1386+ }
1387+#endif
1388
1389 /* Prevent entering of anything but valid callback (syntax check only!) */
1390 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1391@@ -2750,6 +2781,13 @@
1392 }
1393
1394 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1395+#if HARDENING_PATCH
1396+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1397+ tick_fe.created_by_eval = 1;
1398+ } else {
1399+ tick_fe.created_by_eval = 0;
1400+ }
1401+#endif
1402
1403 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1404 RETURN_FALSE;
1405@@ -3047,6 +3085,35 @@
1406 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1407 }
1408
1409+ if (new_key[0] == 'H') {
1410+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1411+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1412+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1413+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1414+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1415+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1416+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1417+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1418+ efree(new_key);
1419+ return 0;
1420+ }
1421+ } else if (new_key[0] == '_') {
1422+ if ((strcmp(new_key, "_COOKIE")==0)||
1423+ (strcmp(new_key, "_ENV")==0)||
1424+ (strcmp(new_key, "_FILES")==0)||
1425+ (strcmp(new_key, "_GET")==0)||
1426+ (strcmp(new_key, "_POST")==0)||
1427+ (strcmp(new_key, "_REQUEST")==0)||
1428+ (strcmp(new_key, "_SESSION")==0)||
1429+ (strcmp(new_key, "_SERVER")==0)) {
1430+ efree(new_key);
1431+ return 0;
1432+ }
1433+ } else if (strcmp(new_key, "GLOBALS")==0) {
1434+ efree(new_key);
1435+ return 0;
1436+ }
1437+
1438 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1439 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1440
1441diff -Nura php-4.4.1/ext/standard/config.m4 hardening-patch-4.4.1-0.4.6/ext/standard/config.m4
1442--- php-4.4.1/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1443+++ hardening-patch-4.4.1-0.4.6/ext/standard/config.m4 2005-11-05 13:04:08.000000000 +0100
1444@@ -203,7 +203,7 @@
1445 if test "$ac_cv_crypt_blowfish" = "yes"; then
1446 ac_result=1
1447 else
1448- ac_result=0
1449+ ac_result=1
1450 fi
1451 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1452 ])
1453@@ -419,6 +419,6 @@
1454 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1455 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1456 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1457- var_unserializer.c ftok.c aggregation.c sha1.c )
1458+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1459
1460 PHP_ADD_MAKEFILE_FRAGMENT
1461diff -Nura php-4.4.1/ext/standard/crypt_blowfish.c hardening-patch-4.4.1-0.4.6/ext/standard/crypt_blowfish.c
1462--- php-4.4.1/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1463+++ hardening-patch-4.4.1-0.4.6/ext/standard/crypt_blowfish.c 2005-11-05 13:04:08.000000000 +0100
1464@@ -0,0 +1,748 @@
1465+/*
1466+ * This code comes from John the Ripper password cracker, with reentrant
1467+ * and crypt(3) interfaces added, but optimizations specific to password
1468+ * cracking removed.
1469+ *
1470+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1471+ * placed in the public domain.
1472+ *
1473+ * There's absolutely no warranty.
1474+ *
1475+ * It is my intent that you should be able to use this on your system,
1476+ * as a part of a software package, or anywhere else to improve security,
1477+ * ensure compatibility, or for any other purpose. I would appreciate
1478+ * it if you give credit where it is due and keep your modifications in
1479+ * the public domain as well, but I don't require that in order to let
1480+ * you place this code and any modifications you make under a license
1481+ * of your choice.
1482+ *
1483+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1484+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1485+ * ideas. The password hashing algorithm was designed by David Mazieres
1486+ * <dm at lcs.mit.edu>.
1487+ *
1488+ * There's a paper on the algorithm that explains its design decisions:
1489+ *
1490+ * http://www.usenix.org/events/usenix99/provos.html
1491+ *
1492+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1493+ * Blowfish library (I can't be sure if I would think of something if I
1494+ * hadn't seen his code).
1495+ */
1496+
1497+#include <string.h>
1498+
1499+#include <errno.h>
1500+#ifndef __set_errno
1501+#define __set_errno(val) errno = (val)
1502+#endif
1503+
1504+#undef __CONST
1505+#ifdef __GNUC__
1506+#define __CONST __const
1507+#else
1508+#define __CONST
1509+#endif
1510+
1511+#ifdef __i386__
1512+#define BF_ASM 0
1513+#define BF_SCALE 1
1514+#elif defined(__alpha__) || defined(__hppa__)
1515+#define BF_ASM 0
1516+#define BF_SCALE 1
1517+#else
1518+#define BF_ASM 0
1519+#define BF_SCALE 0
1520+#endif
1521+
1522+typedef unsigned int BF_word;
1523+
1524+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1525+#define BF_N 16
1526+
1527+typedef BF_word BF_key[BF_N + 2];
1528+
1529+typedef struct {
1530+ BF_word S[4][0x100];
1531+ BF_key P;
1532+} BF_ctx;
1533+
1534+/*
1535+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1536+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1537+ */
1538+static BF_word BF_magic_w[6] = {
1539+ 0x4F727068, 0x65616E42, 0x65686F6C,
1540+ 0x64657253, 0x63727944, 0x6F756274
1541+};
1542+
1543+/*
1544+ * P-box and S-box tables initialized with digits of Pi.
1545+ */
1546+static BF_ctx BF_init_state = {
1547+ {
1548+ {
1549+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1550+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1551+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1552+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1553+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1554+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1555+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1556+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1557+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1558+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1559+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1560+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1561+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1562+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1563+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1564+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1565+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1566+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1567+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1568+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1569+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1570+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1571+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1572+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1573+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1574+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1575+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1576+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1577+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1578+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1579+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1580+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1581+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1582+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1583+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1584+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1585+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1586+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1587+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1588+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1589+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1590+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1591+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1592+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1593+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1594+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1595+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1596+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1597+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1598+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1599+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1600+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1601+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1602+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1603+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1604+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1605+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1606+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1607+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1608+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1609+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1610+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1611+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1612+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1613+ }, {
1614+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1615+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1616+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1617+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1618+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1619+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1620+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1621+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1622+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1623+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1624+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1625+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1626+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1627+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1628+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1629+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1630+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1631+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1632+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1633+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1634+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1635+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1636+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1637+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1638+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1639+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1640+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1641+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1642+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1643+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1644+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1645+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1646+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1647+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1648+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1649+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1650+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1651+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1652+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1653+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1654+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1655+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1656+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1657+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1658+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1659+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1660+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1661+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1662+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1663+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1664+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1665+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1666+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1667+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1668+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1669+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1670+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1671+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1672+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1673+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1674+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1675+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1676+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1677+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1678+ }, {
1679+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1680+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1681+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1682+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1683+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1684+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1685+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1686+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1687+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1688+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1689+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1690+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1691+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1692+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1693+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1694+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1695+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1696+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1697+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1698+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1699+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1700+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1701+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1702+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1703+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1704+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1705+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1706+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1707+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1708+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1709+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1710+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1711+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1712+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1713+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1714+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1715+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1716+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1717+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1718+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1719+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1720+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1721+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1722+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1723+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1724+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1725+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1726+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1727+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1728+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1729+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1730+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1731+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1732+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1733+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1734+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1735+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1736+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1737+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1738+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1739+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1740+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1741+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1742+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1743+ }, {
1744+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1745+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1746+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1747+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1748+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1749+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1750+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1751+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1752+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1753+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1754+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1755+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1756+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1757+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1758+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1759+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1760+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1761+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1762+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1763+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1764+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1765+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1766+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1767+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1768+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1769+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1770+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1771+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1772+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1773+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1774+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1775+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1776+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1777+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1778+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1779+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1780+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1781+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1782+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1783+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1784+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1785+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1786+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1787+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1788+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1789+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1790+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1791+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1792+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1793+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1794+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1795+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1796+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1797+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1798+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1799+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1800+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1801+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1802+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1803+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1804+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1805+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1806+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1807+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1808+ }
1809+ }, {
1810+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1811+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1812+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1813+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1814+ 0x9216d5d9, 0x8979fb1b
1815+ }
1816+};
1817+
1818+static unsigned char BF_itoa64[64 + 1] =
1819+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1820+
1821+static unsigned char BF_atoi64[0x60] = {
1822+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1823+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1824+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1825+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1826+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1827+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1828+};
1829+
1830+/*
1831+ * This may be optimized out if built with function inlining and no BF_ASM.
1832+ */
1833+static void clean(void *data, int size)
1834+{
1835+#if BF_ASM
1836+ extern void _BF_clean(void *data);
1837+#endif
1838+ memset(data, 0, size);
1839+#if BF_ASM
1840+ _BF_clean(data);
1841+#endif
1842+}
1843+
1844+#define BF_safe_atoi64(dst, src) \
1845+{ \
1846+ tmp = (unsigned char)(src); \
1847+ if (tmp == '$') break; \
1848+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1849+ tmp = BF_atoi64[tmp]; \
1850+ if (tmp > 63) return -1; \
1851+ (dst) = tmp; \
1852+}
1853+
1854+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1855+{
1856+ unsigned char *dptr = (unsigned char *)dst;
1857+ unsigned char *end = dptr + size;
1858+ unsigned char *sptr = (unsigned char *)src;
1859+ unsigned int tmp, c1, c2, c3, c4;
1860+
1861+ do {
1862+ BF_safe_atoi64(c1, *sptr++);
1863+ BF_safe_atoi64(c2, *sptr++);
1864+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1865+ if (dptr >= end) break;
1866+
1867+ BF_safe_atoi64(c3, *sptr++);
1868+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1869+ if (dptr >= end) break;
1870+
1871+ BF_safe_atoi64(c4, *sptr++);
1872+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1873+ } while (dptr < end);
1874+
1875+ while (dptr < end)
1876+ *dptr++ = 0;
1877+
1878+ return 0;
1879+}
1880+
1881+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1882+{
1883+ unsigned char *sptr = (unsigned char *)src;
1884+ unsigned char *end = sptr + size;
1885+ unsigned char *dptr = (unsigned char *)dst;
1886+ unsigned int c1, c2;
1887+
1888+ do {
1889+ c1 = *sptr++;
1890+ *dptr++ = BF_itoa64[c1 >> 2];
1891+ c1 = (c1 & 0x03) << 4;
1892+ if (sptr >= end) {
1893+ *dptr++ = BF_itoa64[c1];
1894+ break;
1895+ }
1896+
1897+ c2 = *sptr++;
1898+ c1 |= c2 >> 4;
1899+ *dptr++ = BF_itoa64[c1];
1900+ c1 = (c2 & 0x0f) << 2;
1901+ if (sptr >= end) {
1902+ *dptr++ = BF_itoa64[c1];
1903+ break;
1904+ }
1905+
1906+ c2 = *sptr++;
1907+ c1 |= c2 >> 6;
1908+ *dptr++ = BF_itoa64[c1];
1909+ *dptr++ = BF_itoa64[c2 & 0x3f];
1910+ } while (sptr < end);
1911+}
1912+
1913+static void BF_swap(BF_word *x, int count)
1914+{
1915+ static int endianness_check = 1;
1916+ char *is_little_endian = (char *)&endianness_check;
1917+ BF_word tmp;
1918+
1919+ if (*is_little_endian)
1920+ do {
1921+ tmp = *x;
1922+ tmp = (tmp << 16) | (tmp >> 16);
1923+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1924+ } while (--count);
1925+}
1926+
1927+#if BF_SCALE
1928+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1929+#define BF_ROUND(L, R, N) \
1930+ tmp1 = L & 0xFF; \
1931+ tmp2 = L >> 8; \
1932+ tmp2 &= 0xFF; \
1933+ tmp3 = L >> 16; \
1934+ tmp3 &= 0xFF; \
1935+ tmp4 = L >> 24; \
1936+ tmp1 = data.ctx.S[3][tmp1]; \
1937+ tmp2 = data.ctx.S[2][tmp2]; \
1938+ tmp3 = data.ctx.S[1][tmp3]; \
1939+ tmp3 += data.ctx.S[0][tmp4]; \
1940+ tmp3 ^= tmp2; \
1941+ R ^= data.ctx.P[N + 1]; \
1942+ tmp3 += tmp1; \
1943+ R ^= tmp3;
1944+#else
1945+/* Architectures with no complicated addressing modes supported */
1946+#define BF_INDEX(S, i) \
1947+ (*((BF_word *)(((unsigned char *)S) + (i))))
1948+#define BF_ROUND(L, R, N) \
1949+ tmp1 = L & 0xFF; \
1950+ tmp1 <<= 2; \
1951+ tmp2 = L >> 6; \
1952+ tmp2 &= 0x3FC; \
1953+ tmp3 = L >> 14; \
1954+ tmp3 &= 0x3FC; \
1955+ tmp4 = L >> 22; \
1956+ tmp4 &= 0x3FC; \
1957+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1958+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1959+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1960+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1961+ tmp3 ^= tmp2; \
1962+ R ^= data.ctx.P[N + 1]; \
1963+ tmp3 += tmp1; \
1964+ R ^= tmp3;
1965+#endif
1966+
1967+/*
1968+ * Encrypt one block, BF_N is hardcoded here.
1969+ */
1970+#define BF_ENCRYPT \
1971+ L ^= data.ctx.P[0]; \
1972+ BF_ROUND(L, R, 0); \
1973+ BF_ROUND(R, L, 1); \
1974+ BF_ROUND(L, R, 2); \
1975+ BF_ROUND(R, L, 3); \
1976+ BF_ROUND(L, R, 4); \
1977+ BF_ROUND(R, L, 5); \
1978+ BF_ROUND(L, R, 6); \
1979+ BF_ROUND(R, L, 7); \
1980+ BF_ROUND(L, R, 8); \
1981+ BF_ROUND(R, L, 9); \
1982+ BF_ROUND(L, R, 10); \
1983+ BF_ROUND(R, L, 11); \
1984+ BF_ROUND(L, R, 12); \
1985+ BF_ROUND(R, L, 13); \
1986+ BF_ROUND(L, R, 14); \
1987+ BF_ROUND(R, L, 15); \
1988+ tmp4 = R; \
1989+ R = L; \
1990+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1991+
1992+#if BF_ASM
1993+#define BF_body() \
1994+ _BF_body_r(&data.ctx);
1995+#else
1996+#define BF_body() \
1997+ L = R = 0; \
1998+ ptr = data.ctx.P; \
1999+ do { \
2000+ ptr += 2; \
2001+ BF_ENCRYPT; \
2002+ *(ptr - 2) = L; \
2003+ *(ptr - 1) = R; \
2004+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2005+\
2006+ ptr = data.ctx.S[0]; \
2007+ do { \
2008+ ptr += 2; \
2009+ BF_ENCRYPT; \
2010+ *(ptr - 2) = L; \
2011+ *(ptr - 1) = R; \
2012+ } while (ptr < &data.ctx.S[3][0xFF]);
2013+#endif
2014+
2015+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2016+{
2017+ __CONST char *ptr = key;
2018+ int i, j;
2019+ BF_word tmp;
2020+
2021+ for (i = 0; i < BF_N + 2; i++) {
2022+ tmp = 0;
2023+ for (j = 0; j < 4; j++) {
2024+ tmp <<= 8;
2025+ tmp |= *ptr;
2026+
2027+ if (!*ptr) ptr = key; else ptr++;
2028+ }
2029+
2030+ expanded[i] = tmp;
2031+ initial[i] = BF_init_state.P[i] ^ tmp;
2032+ }
2033+}
2034+
2035+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2036+ char *output, int size)
2037+{
2038+#if BF_ASM
2039+ extern void _BF_body_r(BF_ctx *ctx);
2040+#endif
2041+ struct {
2042+ BF_ctx ctx;
2043+ BF_key expanded_key;
2044+ union {
2045+ BF_word salt[4];
2046+ BF_word output[6];
2047+ } binary;
2048+ } data;
2049+ BF_word L, R;
2050+ BF_word tmp1, tmp2, tmp3, tmp4;
2051+ BF_word *ptr;
2052+ BF_word count;
2053+ int i;
2054+
2055+ if (size < 7 + 22 + 31 + 1) {
2056+ __set_errno(ERANGE);
2057+ return NULL;
2058+ }
2059+
2060+ if (setting[0] != '$' ||
2061+ setting[1] != '2' ||
2062+ setting[2] != 'a' ||
2063+ setting[3] != '$' ||
2064+ setting[4] < '0' || setting[4] > '3' ||
2065+ setting[5] < '0' || setting[5] > '9' ||
2066+ setting[6] != '$') {
2067+ __set_errno(EINVAL);
2068+ return NULL;
2069+ }
2070+
2071+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2072+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2073+ clean(data.binary.salt, sizeof(data.binary.salt));
2074+ __set_errno(EINVAL);
2075+ return NULL;
2076+ }
2077+
2078+ BF_swap(data.binary.salt, 4);
2079+
2080+ BF_set_key(key, data.expanded_key, data.ctx.P);
2081+
2082+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2083+
2084+ L = R = 0;
2085+ for (i = 0; i < BF_N + 2; i += 2) {
2086+ L ^= data.binary.salt[i & 2];
2087+ R ^= data.binary.salt[(i & 2) + 1];
2088+ BF_ENCRYPT;
2089+ data.ctx.P[i] = L;
2090+ data.ctx.P[i + 1] = R;
2091+ }
2092+
2093+ ptr = data.ctx.S[0];
2094+ do {
2095+ ptr += 4;
2096+ L ^= data.binary.salt[(BF_N + 2) & 3];
2097+ R ^= data.binary.salt[(BF_N + 3) & 3];
2098+ BF_ENCRYPT;
2099+ *(ptr - 4) = L;
2100+ *(ptr - 3) = R;
2101+
2102+ L ^= data.binary.salt[(BF_N + 4) & 3];
2103+ R ^= data.binary.salt[(BF_N + 5) & 3];
2104+ BF_ENCRYPT;
2105+ *(ptr - 2) = L;
2106+ *(ptr - 1) = R;
2107+ } while (ptr < &data.ctx.S[3][0xFF]);
2108+
2109+ do {
2110+ data.ctx.P[0] ^= data.expanded_key[0];
2111+ data.ctx.P[1] ^= data.expanded_key[1];
2112+ data.ctx.P[2] ^= data.expanded_key[2];
2113+ data.ctx.P[3] ^= data.expanded_key[3];
2114+ data.ctx.P[4] ^= data.expanded_key[4];
2115+ data.ctx.P[5] ^= data.expanded_key[5];
2116+ data.ctx.P[6] ^= data.expanded_key[6];
2117+ data.ctx.P[7] ^= data.expanded_key[7];
2118+ data.ctx.P[8] ^= data.expanded_key[8];
2119+ data.ctx.P[9] ^= data.expanded_key[9];
2120+ data.ctx.P[10] ^= data.expanded_key[10];
2121+ data.ctx.P[11] ^= data.expanded_key[11];
2122+ data.ctx.P[12] ^= data.expanded_key[12];
2123+ data.ctx.P[13] ^= data.expanded_key[13];
2124+ data.ctx.P[14] ^= data.expanded_key[14];
2125+ data.ctx.P[15] ^= data.expanded_key[15];
2126+ data.ctx.P[16] ^= data.expanded_key[16];
2127+ data.ctx.P[17] ^= data.expanded_key[17];
2128+
2129+ BF_body();
2130+
2131+ tmp1 = data.binary.salt[0];
2132+ tmp2 = data.binary.salt[1];
2133+ tmp3 = data.binary.salt[2];
2134+ tmp4 = data.binary.salt[3];
2135+ data.ctx.P[0] ^= tmp1;
2136+ data.ctx.P[1] ^= tmp2;
2137+ data.ctx.P[2] ^= tmp3;
2138+ data.ctx.P[3] ^= tmp4;
2139+ data.ctx.P[4] ^= tmp1;
2140+ data.ctx.P[5] ^= tmp2;
2141+ data.ctx.P[6] ^= tmp3;
2142+ data.ctx.P[7] ^= tmp4;
2143+ data.ctx.P[8] ^= tmp1;
2144+ data.ctx.P[9] ^= tmp2;
2145+ data.ctx.P[10] ^= tmp3;
2146+ data.ctx.P[11] ^= tmp4;
2147+ data.ctx.P[12] ^= tmp1;
2148+ data.ctx.P[13] ^= tmp2;
2149+ data.ctx.P[14] ^= tmp3;
2150+ data.ctx.P[15] ^= tmp4;
2151+ data.ctx.P[16] ^= tmp1;
2152+ data.ctx.P[17] ^= tmp2;
2153+
2154+ BF_body();
2155+ } while (--count);
2156+
2157+ for (i = 0; i < 6; i += 2) {
2158+ L = BF_magic_w[i];
2159+ R = BF_magic_w[i + 1];
2160+
2161+ count = 64;
2162+ do {
2163+ BF_ENCRYPT;
2164+ } while (--count);
2165+
2166+ data.binary.output[i] = L;
2167+ data.binary.output[i + 1] = R;
2168+ }
2169+
2170+ memcpy(output, setting, 7 + 22 - 1);
2171+ output[7 + 22 - 1] = BF_itoa64[(int)
2172+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2173+
2174+/* This has to be bug-compatible with the original implementation, so
2175+ * only encode 23 of the 24 bytes. :-) */
2176+ BF_swap(data.binary.output, 6);
2177+ BF_encode(&output[7 + 22], data.binary.output, 23);
2178+ output[7 + 22 + 31] = '\0';
2179+
2180+/* Overwrite the most obvious sensitive data we have on the stack. Note
2181+ * that this does not guarantee there's no sensitive data left on the
2182+ * stack and/or in registers; I'm not aware of portable code that does. */
2183+ clean(&data, sizeof(data));
2184+
2185+ return output;
2186+}
2187+
2188+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2189+ __CONST char *input, int size, char *output, int output_size)
2190+{
2191+ if (size < 16 || output_size < 7 + 22 + 1 ||
2192+ (count && (count < 4 || count > 31))) {
2193+ if (output_size > 0) output[0] = '\0';
2194+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2195+ return NULL;
2196+ }
2197+
2198+ if (!count) count = 5;
2199+
2200+ output[0] = '$';
2201+ output[1] = '2';
2202+ output[2] = 'a';
2203+ output[3] = '$';
2204+ output[4] = '0' + count / 10;
2205+ output[5] = '0' + count % 10;
2206+ output[6] = '$';
2207+
2208+ BF_encode(&output[7], (BF_word *)input, 16);
2209+ output[7 + 22] = '\0';
2210+
2211+ return output;
2212+}
2213diff -Nura php-4.4.1/ext/standard/crypt.c hardening-patch-4.4.1-0.4.6/ext/standard/crypt.c
2214--- php-4.4.1/ext/standard/crypt.c 2004-01-19 04:16:04.000000000 +0100
2215+++ hardening-patch-4.4.1-0.4.6/ext/standard/crypt.c 2005-11-05 13:04:08.000000000 +0100
2216@@ -100,6 +100,8 @@
2217 return SUCCESS;
2218 }
2219
2220+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2221+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2222
2223 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2224
2225@@ -135,7 +137,14 @@
2226
2227 /* The automatic salt generation only covers standard DES and md5-crypt */
2228 if(!*salt) {
2229-#if PHP_MD5_CRYPT
2230+#if PHP_BLOWFISH_CRYPT
2231+ char randat[16];
2232+ int i;
2233+
2234+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2235+
2236+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2237+#elif PHP_MD5_CRYPT
2238 strcpy(salt, "$1$");
2239 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2240 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2241@@ -145,8 +154,24 @@
2242 salt[2] = '\0';
2243 #endif
2244 }
2245-
2246- RETVAL_STRING(crypt(str, salt), 1);
2247+
2248+ if (salt[0] == '$' &&
2249+ salt[1] == '2' &&
2250+ salt[2] == 'a' &&
2251+ salt[3] == '$' &&
2252+ salt[4] >= '0' && salt[4] <= '3' &&
2253+ salt[5] >= '0' && salt[5] <= '9' &&
2254+ salt[6] == '$') {
2255+
2256+ char output[PHP_MAX_SALT_LEN+1];
2257+
2258+ output[0] = 0;
2259+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2260+ RETVAL_STRING(output, 1);
2261+
2262+ } else {
2263+ RETVAL_STRING(crypt(str, salt), 1);
2264+ }
2265 }
2266 /* }}} */
2267 #endif
2268diff -Nura php-4.4.1/ext/standard/dl.c hardening-patch-4.4.1-0.4.6/ext/standard/dl.c
2269--- php-4.4.1/ext/standard/dl.c 2005-07-25 15:08:32.000000000 +0200
2270+++ hardening-patch-4.4.1-0.4.6/ext/standard/dl.c 2005-11-05 13:04:08.000000000 +0100
2271@@ -160,8 +160,35 @@
2272 RETURN_FALSE;
2273 }
2274 module_entry = get_module();
2275+
2276+ /* check if Hardening-Patch is installed */
2277+ if (module_entry->zend_api < 1000000000) {
2278+ php_error_docref(NULL TSRMLS_CC, error_type,
2279+ "%s: Unable to initialize module\n"
2280+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2281+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2282+ "These options need to match\n",
2283+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2284+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2285+ DL_UNLOAD(handle);
2286+ RETURN_FALSE;
2287+ }
2288+
2289+ /* check if correct Hardening-Patch is installed */
2290+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2291+ php_error_docref(NULL TSRMLS_CC, error_type,
2292+ "%s: Unable to initialize module\n"
2293+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2294+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2295+ "These options need to match\n",
2296+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2297+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2298+ DL_UNLOAD(handle);
2299+ RETURN_FALSE;
2300+ }
2301+
2302 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2303- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2304+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2305 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2306 struct pre_4_1_0_module_entry {
2307 char *name;
2308@@ -195,7 +222,7 @@
2309 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2310 } else {
2311 name = module_entry->name;
2312- zend_api = module_entry->zend_api;
2313+ zend_api = module_entry->real_zend_api;
2314 zend_debug = module_entry->zend_debug;
2315 zts = module_entry->zts;
2316 }
2317diff -Nura php-4.4.1/ext/standard/file.c hardening-patch-4.4.1-0.4.6/ext/standard/file.c
2318--- php-4.4.1/ext/standard/file.c 2005-07-26 11:32:57.000000000 +0200
2319+++ hardening-patch-4.4.1-0.4.6/ext/standard/file.c 2005-11-05 13:04:08.000000000 +0100
2320@@ -2522,7 +2522,7 @@
2321 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2322 /* {{{ proto string realpath(string path)
2323 Return the resolved path */
2324-PHP_FUNCTION(realpath)
2325+PHP_FUNCTION(real_path)
2326 {
2327 zval **path;
2328 char resolved_path_buff[MAXPATHLEN];
2329diff -Nura php-4.4.1/ext/standard/file.h hardening-patch-4.4.1-0.4.6/ext/standard/file.h
2330--- php-4.4.1/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
2331+++ hardening-patch-4.4.1-0.4.6/ext/standard/file.h 2005-11-05 13:04:08.000000000 +0100
2332@@ -64,7 +64,7 @@
2333 PHP_FUNCTION(fd_set);
2334 PHP_FUNCTION(fd_isset);
2335 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2336-PHP_FUNCTION(realpath);
2337+PHP_FUNCTION(real_path);
2338 #endif
2339 #ifdef HAVE_FNMATCH
2340 PHP_FUNCTION(fnmatch);
2341diff -Nura php-4.4.1/ext/standard/head.c hardening-patch-4.4.1-0.4.6/ext/standard/head.c
2342--- php-4.4.1/ext/standard/head.c 2005-07-27 13:22:36.000000000 +0200
2343+++ hardening-patch-4.4.1-0.4.6/ext/standard/head.c 2005-11-20 19:49:16.000000000 +0100
2344@@ -44,7 +44,7 @@
2345 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2346 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2347 return;
2348-
2349+
2350 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2351 }
2352 /* }}} */
2353diff -Nura php-4.4.1/ext/standard/info.c hardening-patch-4.4.1-0.4.6/ext/standard/info.c
2354--- php-4.4.1/ext/standard/info.c 2005-08-16 02:26:02.000000000 +0200
2355+++ hardening-patch-4.4.1-0.4.6/ext/standard/info.c 2005-11-05 13:04:08.000000000 +0100
2356@@ -408,7 +408,7 @@
2357
2358 if (flag & PHP_INFO_GENERAL) {
2359 char *zend_version = get_zend_version();
2360- char temp_api[9];
2361+ char temp_api[11];
2362
2363 php_uname = php_get_uname('a');
2364
2365@@ -430,11 +430,22 @@
2366 }
2367 }
2368
2369+#if HARDENING_PATCH
2370+ if (!sapi_module.phpinfo_as_text) {
2371+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2372+ } else {
2373+ char temp_ver[40];
2374+
2375+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2376+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2377+ }
2378+#else
2379 if (!sapi_module.phpinfo_as_text) {
2380 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2381 } else {
2382 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2383 }
2384+#endif
2385 php_info_print_box_end();
2386 php_info_print_table_start();
2387 php_info_print_table_row(2, "System", php_uname );
2388diff -Nura php-4.4.1/ext/standard/php_standard.h hardening-patch-4.4.1-0.4.6/ext/standard/php_standard.h
2389--- php-4.4.1/ext/standard/php_standard.h 2002-12-31 17:35:33.000000000 +0100
2390+++ hardening-patch-4.4.1-0.4.6/ext/standard/php_standard.h 2005-11-05 13:04:08.000000000 +0100
2391@@ -28,6 +28,7 @@
2392 #include "php_mail.h"
2393 #include "md5.h"
2394 #include "sha1.h"
2395+#include "sha256.h"
2396 #include "html.h"
2397 #include "exec.h"
2398 #include "file.h"
2399diff -Nura php-4.4.1/ext/standard/sha256.c hardening-patch-4.4.1-0.4.6/ext/standard/sha256.c
2400--- php-4.4.1/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2401+++ hardening-patch-4.4.1-0.4.6/ext/standard/sha256.c 2005-11-05 13:04:08.000000000 +0100
2402@@ -0,0 +1,398 @@
2403+/*
2404+ +----------------------------------------------------------------------+
2405+ | PHP Version 5 |
2406+ +----------------------------------------------------------------------+
2407+ | Copyright (c) 1997-2004 The PHP Group |
2408+ +----------------------------------------------------------------------+
2409+ | This source file is subject to version 3.0 of the PHP license, |
2410+ | that is bundled with this package in the file LICENSE, and is |
2411+ | available through the world-wide-web at the following url: |
2412+ | http://www.php.net/license/3_0.txt. |
2413+ | If you did not receive a copy of the PHP license and are unable to |
2414+ | obtain it through the world-wide-web, please send a note to |
2415+ | license@php.net so we can mail you a copy immediately. |
2416+ +----------------------------------------------------------------------+
2417+ | Author: Stefan Esser <sesser@php.net> |
2418+ +----------------------------------------------------------------------+
2419+*/
2420+
2421+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2422+
2423+#include <stdio.h>
2424+#include "php.h"
2425+
2426+/* This code is heavily based on the PHP md5/sha1 implementations */
2427+
2428+#include "sha256.h"
2429+
2430+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2431+{
2432+ int i;
2433+
2434+ for (i = 0; i < 32; i++) {
2435+ sprintf(sha256str, "%02x", digest[i]);
2436+ sha256str += 2;
2437+ }
2438+
2439+ *sha256str = '\0';
2440+}
2441+
2442+/* {{{ proto string sha256(string str [, bool raw_output])
2443+ Calculate the sha256 hash of a string */
2444+PHP_FUNCTION(sha256)
2445+{
2446+ char *arg;
2447+ int arg_len;
2448+ zend_bool raw_output = 0;
2449+ char sha256str[65];
2450+ PHP_SHA256_CTX context;
2451+ unsigned char digest[32];
2452+
2453+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2454+ return;
2455+ }
2456+
2457+ sha256str[0] = '\0';
2458+ PHP_SHA256Init(&context);
2459+ PHP_SHA256Update(&context, arg, arg_len);
2460+ PHP_SHA256Final(digest, &context);
2461+ if (raw_output) {
2462+ RETURN_STRINGL(digest, 32, 1);
2463+ } else {
2464+ make_sha256_digest(sha256str, digest);
2465+ RETVAL_STRING(sha256str, 1);
2466+ }
2467+
2468+}
2469+
2470+/* }}} */
2471+
2472+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2473+ Calculate the sha256 hash of given filename */
2474+PHP_FUNCTION(sha256_file)
2475+{
2476+ char *arg;
2477+ int arg_len;
2478+ zend_bool raw_output = 0;
2479+ char sha256str[65];
2480+ unsigned char buf[1024];
2481+ unsigned char digest[32];
2482+ PHP_SHA256_CTX context;
2483+ int n;
2484+ FILE *fp;
2485+
2486+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2487+ return;
2488+ }
2489+
2490+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2491+ RETURN_FALSE;
2492+ }
2493+
2494+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2495+ RETURN_FALSE;
2496+ }
2497+
2498+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2499+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2500+ RETURN_FALSE;
2501+ }
2502+
2503+ PHP_SHA256Init(&context);
2504+
2505+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2506+ PHP_SHA256Update(&context, buf, n);
2507+ }
2508+
2509+ PHP_SHA256Final(digest, &context);
2510+
2511+ if (ferror(fp)) {
2512+ fclose(fp);
2513+ RETURN_FALSE;
2514+ }
2515+
2516+ fclose(fp);
2517+
2518+ if (raw_output) {
2519+ RETURN_STRINGL(digest, 32, 1);
2520+ } else {
2521+ make_sha256_digest(sha256str, digest);
2522+ RETVAL_STRING(sha256str, 1);
2523+ }
2524+}
2525+/* }}} */
2526+
2527+
2528+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2529+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2530+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2531+
2532+static unsigned char PADDING[64] =
2533+{
2534+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2535+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2536+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2537+};
2538+
2539+/* F, G, H and I are basic SHA256 functions.
2540+ */
2541+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2542+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2543+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2544+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2545+
2546+/* ROTATE_RIGHT rotates x right n bits.
2547+ */
2548+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2549+
2550+/* W[i]
2551+ */
2552+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2553+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2554+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2555+
2556+/* ROUND function of sha256
2557+ */
2558+
2559+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2560+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2561+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2562+ (d) += t1; \
2563+ }
2564+
2565+
2566+/* {{{ PHP_SHA256Init
2567+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2568+ */
2569+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2570+{
2571+ context->count[0] = context->count[1] = 0;
2572+ /* Load magic initialization constants.
2573+ */
2574+ context->state[0] = 0x6a09e667;
2575+ context->state[1] = 0xbb67ae85;
2576+ context->state[2] = 0x3c6ef372;
2577+ context->state[3] = 0xa54ff53a;
2578+ context->state[4] = 0x510e527f;
2579+ context->state[5] = 0x9b05688c;
2580+ context->state[6] = 0x1f83d9ab;
2581+ context->state[7] = 0x5be0cd19;
2582+}
2583+/* }}} */
2584+
2585+/* {{{ PHP_SHA256Update
2586+ SHA256 block update operation. Continues an SHA256 message-digest
2587+ operation, processing another message block, and updating the
2588+ context.
2589+ */
2590+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2591+ unsigned int inputLen)
2592+{
2593+ unsigned int i, index, partLen;
2594+
2595+ /* Compute number of bytes mod 64 */
2596+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2597+
2598+ /* Update number of bits */
2599+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2600+ < ((php_uint32) inputLen << 3))
2601+ context->count[1]++;
2602+ context->count[1] += ((php_uint32) inputLen >> 29);
2603+
2604+ partLen = 64 - index;
2605+
2606+ /* Transform as many times as possible.
2607+ */
2608+ if (inputLen >= partLen) {
2609+ memcpy
2610+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2611+ SHA256Transform(context->state, context->buffer);
2612+
2613+ for (i = partLen; i + 63 < inputLen; i += 64)
2614+ SHA256Transform(context->state, &input[i]);
2615+
2616+ index = 0;
2617+ } else
2618+ i = 0;
2619+
2620+ /* Buffer remaining input */
2621+ memcpy
2622+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2623+ inputLen - i);
2624+}
2625+/* }}} */
2626+
2627+/* {{{ PHP_SHA256Final
2628+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2629+ the message digest and zeroizing the context.
2630+ */
2631+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2632+{
2633+ unsigned char bits[8];
2634+ unsigned int index, padLen;
2635+
2636+ /* Save number of bits */
2637+ bits[7] = context->count[0] & 0xFF;
2638+ bits[6] = (context->count[0] >> 8) & 0xFF;
2639+ bits[5] = (context->count[0] >> 16) & 0xFF;
2640+ bits[4] = (context->count[0] >> 24) & 0xFF;
2641+ bits[3] = context->count[1] & 0xFF;
2642+ bits[2] = (context->count[1] >> 8) & 0xFF;
2643+ bits[1] = (context->count[1] >> 16) & 0xFF;
2644+ bits[0] = (context->count[1] >> 24) & 0xFF;
2645+
2646+ /* Pad out to 56 mod 64.
2647+ */
2648+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2649+ padLen = (index < 56) ? (56 - index) : (120 - index);
2650+ PHP_SHA256Update(context, PADDING, padLen);
2651+
2652+ /* Append length (before padding) */
2653+ PHP_SHA256Update(context, bits, 8);
2654+
2655+ /* Store state in digest */
2656+ SHA256Encode(digest, context->state, 32);
2657+
2658+ /* Zeroize sensitive information.
2659+ */
2660+ memset((unsigned char*) context, 0, sizeof(*context));
2661+}
2662+/* }}} */
2663+
2664+/* {{{ SHA256Transform
2665+ * SHA256 basic transformation. Transforms state based on block.
2666+ */
2667+static void SHA256Transform(state, block)
2668+php_uint32 state[8];
2669+const unsigned char block[64];
2670+{
2671+ php_uint32 a = state[0], b = state[1], c = state[2];
2672+ php_uint32 d = state[3], e = state[4], f = state[5];
2673+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2674+
2675+ SHA256Decode(x, block, 64);
2676+
2677+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2678+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2679+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2680+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2681+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2682+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2683+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2684+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2685+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2686+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2687+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2688+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2689+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2690+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2691+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2692+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2693+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2694+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2695+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2696+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2697+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2698+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2699+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2700+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2701+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2702+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2703+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2704+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2705+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2706+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2707+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2708+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2709+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2710+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2711+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2712+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2713+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2714+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2715+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2716+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2717+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2718+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2719+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2720+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2721+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2722+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2723+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2724+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2725+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2726+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2727+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2728+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2729+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2730+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2731+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2732+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2733+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2734+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2735+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2736+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2737+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2738+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2739+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2740+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2741+
2742+ state[0] += a;
2743+ state[1] += b;
2744+ state[2] += c;
2745+ state[3] += d;
2746+ state[4] += e;
2747+ state[5] += f;
2748+ state[6] += g;
2749+ state[7] += h;
2750+
2751+ /* Zeroize sensitive information. */
2752+ memset((unsigned char*) x, 0, sizeof(x));
2753+}
2754+/* }}} */
2755+
2756+/* {{{ SHA256Encode
2757+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2758+ a multiple of 4.
2759+ */
2760+static void SHA256Encode(output, input, len)
2761+unsigned char *output;
2762+php_uint32 *input;
2763+unsigned int len;
2764+{
2765+ unsigned int i, j;
2766+
2767+ for (i = 0, j = 0; j < len; i++, j += 4) {
2768+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2769+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2770+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2771+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2772+ }
2773+}
2774+/* }}} */
2775+
2776+/* {{{ SHA256Decode
2777+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2778+ a multiple of 4.
2779+ */
2780+static void SHA256Decode(output, input, len)
2781+php_uint32 *output;
2782+const unsigned char *input;
2783+unsigned int len;
2784+{
2785+ unsigned int i, j;
2786+
2787+ for (i = 0, j = 0; j < len; i++, j += 4)
2788+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2789+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2790+}
2791+/* }}} */
2792+
2793+/*
2794+ * Local variables:
2795+ * tab-width: 4
2796+ * c-basic-offset: 4
2797+ * End:
2798+ * vim600: sw=4 ts=4 fdm=marker
2799+ * vim<600: sw=4 ts=4
2800+ */
2801diff -Nura php-4.4.1/ext/standard/sha256.h hardening-patch-4.4.1-0.4.6/ext/standard/sha256.h
2802--- php-4.4.1/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2803+++ hardening-patch-4.4.1-0.4.6/ext/standard/sha256.h 2005-11-05 13:04:08.000000000 +0100
2804@@ -0,0 +1,40 @@
2805+/*
2806+ +----------------------------------------------------------------------+
2807+ | PHP Version 5 |
2808+ +----------------------------------------------------------------------+
2809+ | Copyright (c) 1997-2004 The PHP Group |
2810+ +----------------------------------------------------------------------+
2811+ | This source file is subject to version 3.0 of the PHP license, |
2812+ | that is bundled with this package in the file LICENSE, and is |
2813+ | available through the world-wide-web at the following url: |
2814+ | http://www.php.net/license/3_0.txt. |
2815+ | If you did not receive a copy of the PHP license and are unable to |
2816+ | obtain it through the world-wide-web, please send a note to |
2817+ | license@php.net so we can mail you a copy immediately. |
2818+ +----------------------------------------------------------------------+
2819+ | Author: Stefan Esser <sesser@php.net> |
2820+ +----------------------------------------------------------------------+
2821+*/
2822+
2823+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2824+
2825+#ifndef SHA256_H
2826+#define SHA256_H
2827+
2828+#include "ext/standard/basic_functions.h"
2829+
2830+/* SHA1 context. */
2831+typedef struct {
2832+ php_uint32 state[8]; /* state (ABCD) */
2833+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2834+ unsigned char buffer[64]; /* input buffer */
2835+} PHP_SHA256_CTX;
2836+
2837+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2838+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2839+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2840+
2841+PHP_FUNCTION(sha256);
2842+PHP_FUNCTION(sha256_file);
2843+
2844+#endif
2845diff -Nura php-4.4.1/ext/standard/syslog.c hardening-patch-4.4.1-0.4.6/ext/standard/syslog.c
2846--- php-4.4.1/ext/standard/syslog.c 2004-07-30 16:38:29.000000000 +0200
2847+++ hardening-patch-4.4.1-0.4.6/ext/standard/syslog.c 2005-11-05 13:04:08.000000000 +0100
2848@@ -42,6 +42,8 @@
2849 */
2850 PHP_MINIT_FUNCTION(syslog)
2851 {
2852+
2853+#if !HARDENING_PATCH
2854 /* error levels */
2855 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2856 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2857@@ -97,7 +99,7 @@
2858 /* AIX doesn't have LOG_PERROR */
2859 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2860 #endif
2861-
2862+#endif
2863 return SUCCESS;
2864 }
2865 /* }}} */
2866diff -Nura php-4.4.1/ext/varfilter/config.m4 hardening-patch-4.4.1-0.4.6/ext/varfilter/config.m4
2867--- php-4.4.1/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2868+++ hardening-patch-4.4.1-0.4.6/ext/varfilter/config.m4 2005-11-25 13:23:41.000000000 +0100
2869@@ -0,0 +1,11 @@
2870+dnl
2871+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2872+dnl
2873+
2874+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2875+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2876+
2877+if test "$PHP_VARFILTER" != "no"; then
2878+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2879+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2880+fi
2881diff -Nura php-4.4.1/ext/varfilter/CREDITS hardening-patch-4.4.1-0.4.6/ext/varfilter/CREDITS
2882--- php-4.4.1/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2883+++ hardening-patch-4.4.1-0.4.6/ext/varfilter/CREDITS 2005-11-25 13:23:41.000000000 +0100
2884@@ -0,0 +1,2 @@
2885+varfilter
2886+Stefan Esser
2887\ Kein Zeilenumbruch am Dateiende.
2888diff -Nura php-4.4.1/ext/varfilter/php_varfilter.h hardening-patch-4.4.1-0.4.6/ext/varfilter/php_varfilter.h
2889--- php-4.4.1/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2890+++ hardening-patch-4.4.1-0.4.6/ext/varfilter/php_varfilter.h 2005-11-25 18:19:51.000000000 +0100
2891@@ -0,0 +1,144 @@
2892+/*
2893+ +----------------------------------------------------------------------+
2894+ | Hardened-PHP Project's varfilter extension |
2895+ +----------------------------------------------------------------------+
2896+ | Copyright (c) 2004-2005 Stefan Esser |
2897+ +----------------------------------------------------------------------+
2898+ | This source file is subject to version 2.02 of the PHP license, |
2899+ | that is bundled with this package in the file LICENSE, and is |
2900+ | available at through the world-wide-web at |
2901+ | http://www.php.net/license/2_02.txt. |
2902+ | If you did not receive a copy of the PHP license and are unable to |
2903+ | obtain it through the world-wide-web, please send a note to |
2904+ | license@php.net so we can mail you a copy immediately. |
2905+ +----------------------------------------------------------------------+
2906+ | Author: Stefan Esser <sesser@hardened-php.net> |
2907+ +----------------------------------------------------------------------+
2908+
2909+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2910+*/
2911+
2912+#ifndef PHP_VARFILTER_H
2913+#define PHP_VARFILTER_H
2914+
2915+extern zend_module_entry varfilter_module_entry;
2916+#define phpext_varfilter_ptr &varfilter_module_entry
2917+
2918+#ifdef PHP_WIN32
2919+#define PHP_VARFILTER_API __declspec(dllexport)
2920+#else
2921+#define PHP_VARFILTER_API
2922+#endif
2923+
2924+#ifdef ZTS
2925+#include "TSRM.h"
2926+#endif
2927+
2928+#include "SAPI.h"
2929+
2930+#include "php_variables.h"
2931+
2932+#ifdef ZEND_ENGINE_2
2933+#define HASH_HTTP_GET_VARS 0x2095733f
2934+#define HASH_HTTP_POST_VARS 0xbfee1265
2935+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
2936+#define HASH_HTTP_ENV_VARS 0x1fe186a8
2937+#define HASH_HTTP_SERVER_VARS 0xc987afd6
2938+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
2939+#define HASH_HTTP_POST_FILES 0x98eb1ddc
2940+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
2941+#else
2942+#define HASH_HTTP_GET_VARS 0x8d8645bd
2943+#define HASH_HTTP_POST_VARS 0x7c699bf3
2944+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
2945+#define HASH_HTTP_ENV_VARS 0x84da3016
2946+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
2947+#define HASH_HTTP_SESSION_VARS 0x322906f5
2948+#define HASH_HTTP_POST_FILES 0xe4e4ce70
2949+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
2950+#endif
2951+
2952+PHP_MINIT_FUNCTION(varfilter);
2953+PHP_MSHUTDOWN_FUNCTION(varfilter);
2954+PHP_RINIT_FUNCTION(varfilter);
2955+PHP_RSHUTDOWN_FUNCTION(varfilter);
2956+PHP_MINFO_FUNCTION(varfilter);
2957+
2958+
2959+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2960+/* request variables */
2961+ long max_request_variables;
2962+ long cur_request_variables;
2963+ long max_varname_length;
2964+ long max_totalname_length;
2965+ long max_value_length;
2966+ long max_array_depth;
2967+ long max_array_index_length;
2968+ zend_bool disallow_nul;
2969+/* cookie variables */
2970+ long max_cookie_vars;
2971+ long cur_cookie_vars;
2972+ long max_cookie_name_length;
2973+ long max_cookie_totalname_length;
2974+ long max_cookie_value_length;
2975+ long max_cookie_array_depth;
2976+ long max_cookie_array_index_length;
2977+ zend_bool disallow_cookie_nul;
2978+/* get variables */
2979+ long max_get_vars;
2980+ long cur_get_vars;
2981+ long max_get_name_length;
2982+ long max_get_totalname_length;
2983+ long max_get_value_length;
2984+ long max_get_array_depth;
2985+ long max_get_array_index_length;
2986+ zend_bool disallow_get_nul;
2987+/* post variables */
2988+ long max_post_vars;
2989+ long cur_post_vars;
2990+ long max_post_name_length;
2991+ long max_post_totalname_length;
2992+ long max_post_value_length;
2993+ long max_post_array_depth;
2994+ long max_post_array_index_length;
2995+ zend_bool disallow_post_nul;
2996+/* fileupload */
2997+ long max_uploads;
2998+ long cur_uploads;
2999+ zend_bool disallow_elf_files;
3000+ char *verification_script;
3001+
3002+ zend_bool no_more_variables;
3003+ zend_bool no_more_get_variables;
3004+ zend_bool no_more_post_variables;
3005+ zend_bool no_more_cookie_variables;
3006+ zend_bool no_more_uploads;
3007+
3008+ZEND_END_MODULE_GLOBALS(varfilter)
3009+
3010+
3011+#ifdef ZTS
3012+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3013+#else
3014+#define VARFILTER_G(v) (varfilter_globals.v)
3015+#endif
3016+
3017+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3018+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3019+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3020+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3021+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3022+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3023+
3024+
3025+
3026+#endif /* PHP_VARFILTER_H */
3027+
3028+
3029+/*
3030+ * Local variables:
3031+ * tab-width: 4
3032+ * c-basic-offset: 4
3033+ * indent-tabs-mode: t
3034+ * End:
3035+ */
3036diff -Nura php-4.4.1/ext/varfilter/varfilter.c hardening-patch-4.4.1-0.4.6/ext/varfilter/varfilter.c
3037--- php-4.4.1/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3038+++ hardening-patch-4.4.1-0.4.6/ext/varfilter/varfilter.c 2005-11-25 19:17:42.000000000 +0100
3039@@ -0,0 +1,915 @@
3040+/*
3041+ +----------------------------------------------------------------------+
3042+ | Hardened-PHP Project's varfilter extension |
3043+ +----------------------------------------------------------------------+
3044+ | Copyright (c) 2004-2005 Stefan Esser |
3045+ +----------------------------------------------------------------------+
3046+ | This source file is subject to version 2.02 of the PHP license, |
3047+ | that is bundled with this package in the file LICENSE, and is |
3048+ | available at through the world-wide-web at |
3049+ | http://www.php.net/license/2_02.txt. |
3050+ | If you did not receive a copy of the PHP license and are unable to |
3051+ | obtain it through the world-wide-web, please send a note to |
3052+ | license@php.net so we can mail you a copy immediately. |
3053+ +----------------------------------------------------------------------+
3054+ | Author: Stefan Esser <sesser@hardened-php.net> |
3055+ +----------------------------------------------------------------------+
3056+
3057+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3058+*/
3059+
3060+#ifdef HAVE_CONFIG_H
3061+#include "config.h"
3062+#endif
3063+
3064+#include "php.h"
3065+#include "php_ini.h"
3066+#include "ext/standard/info.h"
3067+#include "php_varfilter.h"
3068+#include "hardening_patch.h"
3069+
3070+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3071+
3072+/* True global resources - no need for thread safety here */
3073+static int le_varfilter;
3074+
3075+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3076+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3077+static zend_bool hooked = 0;
3078+
3079+/* {{{ varfilter_module_entry
3080+ */
3081+zend_module_entry varfilter_module_entry = {
3082+#if ZEND_MODULE_API_NO >= 20010901
3083+ STANDARD_MODULE_HEADER,
3084+#endif
3085+ "varfilter",
3086+ NULL,
3087+ PHP_MINIT(varfilter),
3088+ PHP_MSHUTDOWN(varfilter),
3089+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3090+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3091+ PHP_MINFO(varfilter),
3092+#if ZEND_MODULE_API_NO >= 20010901
3093+ "0.4.6", /* Replace with version number for your extension */
3094+#endif
3095+ STANDARD_MODULE_PROPERTIES
3096+};
3097+/* }}} */
3098+
3099+#ifdef COMPILE_DL_VARFILTER
3100+ZEND_GET_MODULE(varfilter)
3101+#endif
3102+
3103+/* {{{ PHP_INI
3104+ */
3105+PHP_INI_BEGIN()
3106+ /* for backward compatibility */
3107+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3108+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3109+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3110+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3111+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3112+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3113+
3114+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3115+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3116+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3117+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3118+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3119+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3120+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3121+
3122+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3123+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3124+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3125+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3126+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3127+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
3128+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3129+
3130+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3131+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3132+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3133+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3134+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3135+ STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
3136+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3137+
3138+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3139+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3140+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3141+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3142+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3143+ STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
3144+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3145+
3146+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3147+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3148+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3149+
3150+
3151+PHP_INI_END()
3152+/* }}} */
3153+
3154+/* {{{ php_varfilter_init_globals
3155+ */
3156+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3157+{
3158+ varfilter_globals->max_request_variables = 200;
3159+ varfilter_globals->max_varname_length = 64;
3160+ varfilter_globals->max_value_length = 10000;
3161+ varfilter_globals->max_array_depth = 100;
3162+ varfilter_globals->max_totalname_length = 256;
3163+ varfilter_globals->max_array_index_length = 64;
3164+ varfilter_globals->disallow_nul = 1;
3165+
3166+ varfilter_globals->max_cookie_vars = 100;
3167+ varfilter_globals->max_cookie_name_length = 64;
3168+ varfilter_globals->max_cookie_totalname_length = 256;
3169+ varfilter_globals->max_cookie_value_length = 10000;
3170+ varfilter_globals->max_cookie_array_depth = 100;
3171+ varfilter_globals->max_cookie_array_index_length = 64;
3172+ varfilter_globals->disallow_cookie_nul = 1;
3173+
3174+ varfilter_globals->max_get_vars = 100;
3175+ varfilter_globals->max_get_name_length = 64;
3176+ varfilter_globals->max_get_totalname_length = 256;
3177+ varfilter_globals->max_get_value_length = 512;
3178+ varfilter_globals->max_get_array_depth = 50;
3179+ varfilter_globals->max_get_array_index_length = 64;
3180+ varfilter_globals->disallow_get_nul = 1;
3181+
3182+ varfilter_globals->max_post_vars = 200;
3183+ varfilter_globals->max_post_name_length = 64;
3184+ varfilter_globals->max_post_totalname_length = 256;
3185+ varfilter_globals->max_post_value_length = 65000;
3186+ varfilter_globals->max_post_array_depth = 100;
3187+ varfilter_globals->max_post_array_index_length = 64;
3188+ varfilter_globals->disallow_post_nul = 1;
3189+
3190+ varfilter_globals->max_uploads = 25;
3191+ varfilter_globals->disallow_elf_files = 1;
3192+ varfilter_globals->verification_script = NULL;
3193+
3194+ varfilter_globals->no_more_variables = 0;
3195+ varfilter_globals->no_more_get_variables = 0;
3196+ varfilter_globals->no_more_post_variables = 0;
3197+ varfilter_globals->no_more_cookie_variables = 0;
3198+ varfilter_globals->no_more_uploads = 0;
3199+
3200+ varfilter_globals->cur_request_variables = 0;
3201+ varfilter_globals->cur_get_vars = 0;
3202+ varfilter_globals->cur_post_vars = 0;
3203+ varfilter_globals->cur_cookie_vars = 0;
3204+
3205+ varfilter_globals->cur_uploads = 0;
3206+
3207+}
3208+/* }}} */
3209+
3210+
3211+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3212+{
3213+ HashTable *svars;
3214+ int retval, failure=0;
3215+
3216+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3217+
3218+ svars = Z_ARRVAL_P(track_vars_array);
3219+
3220+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3221+ if (retval == SUCCESS) failure = 1;
3222+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3223+ if (retval == SUCCESS) failure = 1;
3224+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3225+ if (retval == SUCCESS) failure = 1;
3226+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3227+ if (retval == SUCCESS) failure = 1;
3228+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3229+ if (retval == SUCCESS) failure = 1;
3230+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3231+ if (retval == SUCCESS) failure = 1;
3232+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3233+ if (retval == SUCCESS) failure = 1;
3234+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX);
3235+ if (retval == SUCCESS) failure = 1;
3236+
3237+ if (failure) {
3238+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3239+ }
3240+}
3241+
3242+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3243+{
3244+ int retval, i;
3245+ char *tmp;
3246+
3247+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3248+
3249+ tmp = sapi_header->header;
3250+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3251+ if (tmp[0] == 0) {
3252+ char *fname = get_active_function_name(TSRMLS_C);
3253+
3254+ if (!fname) {
3255+ fname = "unknown";
3256+ }
3257+
3258+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3259+ sapi_header->header_len = i;
3260+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3261+ char *fname = get_active_function_name(TSRMLS_C);
3262+
3263+ if (!fname) {
3264+ fname = "unknown";
3265+ }
3266+
3267+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3268+ sapi_header->header_len = i;
3269+ tmp[0] = 0;
3270+ }
3271+ }
3272+ }
3273+
3274+ if (orig_header_handler) {
3275+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3276+ }
3277+
3278+ return retval;
3279+}
3280+
3281+/* {{{ PHP_MINIT_FUNCTION
3282+ */
3283+PHP_MINIT_FUNCTION(varfilter)
3284+{
3285+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3286+ REGISTER_INI_ENTRIES();
3287+
3288+ if (!hooked) {
3289+ void *temp;
3290+ hooked = 1;
3291+
3292+ temp = (void *)sapi_module.register_server_variables;
3293+ if (temp != varfilter_register_server_variables) {
3294+ orig_register_server_variables = temp;
3295+ }
3296+ temp = (void *)sapi_module.header_handler;
3297+ if (temp != varfilter_header_handler) {
3298+ orig_header_handler = temp;
3299+ }
3300+ }
3301+
3302+ sapi_register_input_filter(varfilter_input_filter);
3303+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3304+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3305+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3306+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3307+
3308+ sapi_module.header_handler = varfilter_header_handler;
3309+ sapi_module.register_server_variables = varfilter_register_server_variables;
3310+
3311+
3312+ return SUCCESS;
3313+}
3314+/* }}} */
3315+
3316+/* {{{ PHP_MSHUTDOWN_FUNCTION
3317+ */
3318+PHP_MSHUTDOWN_FUNCTION(varfilter)
3319+{
3320+ UNREGISTER_INI_ENTRIES();
3321+
3322+ return SUCCESS;
3323+}
3324+/* }}} */
3325+
3326+/* Remove if there's nothing to do at request start */
3327+/* {{{ PHP_RINIT_FUNCTION
3328+ */
3329+PHP_RINIT_FUNCTION(varfilter)
3330+{
3331+ VARFILTER_G(cur_request_variables) = 0;
3332+ VARFILTER_G(cur_get_vars) = 0;
3333+ VARFILTER_G(cur_post_vars) = 0;
3334+ VARFILTER_G(cur_cookie_vars) = 0;
3335+
3336+ VARFILTER_G(cur_uploads) = 0;
3337+
3338+ VARFILTER_G(no_more_variables) = 0;
3339+ VARFILTER_G(no_more_get_variables) = 0;
3340+ VARFILTER_G(no_more_post_variables) = 0;
3341+ VARFILTER_G(no_more_cookie_variables) = 0;
3342+ VARFILTER_G(no_more_uploads) = 0;
3343+
3344+ return SUCCESS;
3345+}
3346+/* }}} */
3347+
3348+/* Remove if there's nothing to do at request end */
3349+/* {{{ PHP_RSHUTDOWN_FUNCTION
3350+ */
3351+PHP_RSHUTDOWN_FUNCTION(varfilter)
3352+{
3353+ return SUCCESS;
3354+}
3355+/* }}} */
3356+
3357+/* {{{ PHP_MINFO_FUNCTION
3358+ */
3359+PHP_MINFO_FUNCTION(varfilter)
3360+{
3361+ php_info_print_table_start();
3362+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3363+ php_info_print_table_end();
3364+
3365+ DISPLAY_INI_ENTRIES();
3366+}
3367+/* }}} */
3368+
3369+/* {{{ normalize_varname
3370+ */
3371+static void normalize_varname(char *varname)
3372+{
3373+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3374+
3375+ /* overjump leading space */
3376+ while (*s == ' ') {
3377+ s++;
3378+ }
3379+
3380+ /* and remove it */
3381+ if (s != varname) {
3382+ memmove(varname, s, strlen(s)+1);
3383+ }
3384+
3385+ for (p=varname; *p && *p != '['; p++) {
3386+ switch(*p) {
3387+ case ' ':
3388+ case '.':
3389+ *p='_';
3390+ break;
3391+ }
3392+ }
3393+
3394+ /* find index */
3395+ index = strchr(varname, '[');
3396+ if (index) {
3397+ index++;
3398+ s=index;
3399+ } else {
3400+ return;
3401+ }
3402+
3403+ /* done? */
3404+ while (index) {
3405+
3406+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3407+ index++;
3408+ }
3409+ indexend = strchr(index, ']');
3410+ indexend = indexend ? indexend + 1 : index + strlen(index);
3411+
3412+ if (s != index) {
3413+ memmove(s, index, strlen(index)+1);
3414+ s += indexend-index;
3415+ } else {
3416+ s = indexend;
3417+ }
3418+
3419+ if (*s == '[') {
3420+ s++;
3421+ index = s;
3422+ } else {
3423+ index = NULL;
3424+ }
3425+ }
3426+ *s++='\0';
3427+}
3428+/* }}} */
3429+
3430+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3431+ */
3432+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3433+{
3434+ char *index, *prev_index = NULL, *var;
3435+ unsigned int var_len, total_len, depth = 0;
3436+
3437+ var = estrdup(varname);
3438+
3439+ /* Normalize the variable name */
3440+ normalize_varname(var);
3441+
3442+ /* Find length of variable name */
3443+ index = strchr(var, '[');
3444+ total_len = strlen(var);
3445+ var_len = index ? index-var : total_len;
3446+
3447+ /* Drop this variable if it exceeds the varname/total length limit */
3448+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3449+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3450+ goto return_failure;
3451+ }
3452+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3453+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3454+ goto return_failure;
3455+ }
3456+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3457+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3458+
3459+ goto return_failure;
3460+ }
3461+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3462+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3463+ goto return_failure;
3464+ }
3465+
3466+ /* Find out array depth */
3467+ while (index) {
3468+ unsigned int index_length;
3469+
3470+ depth++;
3471+ index = strchr(index+1, '[');
3472+
3473+ if (prev_index) {
3474+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3475+
3476+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3477+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3478+ goto return_failure;
3479+ }
3480+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3481+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3482+ goto return_failure;
3483+ }
3484+ prev_index = index;
3485+ }
3486+
3487+ }
3488+
3489+ /* Drop this variable if it exceeds the array depth limit */
3490+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3491+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3492+ goto return_failure;
3493+ }
3494+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3495+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3496+ goto return_failure;
3497+ }
3498+
3499+
3500+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3501+ /* This is to protect several silly scripts that do globalizing themself */
3502+
3503+ switch (var_len) {
3504+ case 18:
3505+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3506+ break;
3507+ case 17:
3508+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3509+ break;
3510+ case 16:
3511+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3512+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3513+ break;
3514+ case 15:
3515+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3516+ break;
3517+ case 14:
3518+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3519+ break;
3520+ case 13:
3521+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3522+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3523+ break;
3524+ case 8:
3525+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3526+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3527+ break;
3528+ case 7:
3529+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3530+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3531+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3532+ break;
3533+ case 6:
3534+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3535+ break;
3536+ case 5:
3537+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3538+ break;
3539+ case 4:
3540+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3541+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3542+ break;
3543+ }
3544+
3545+ efree(var);
3546+ return SUCCESS;
3547+protected_varname2:
3548+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3549+return_failure:
3550+ efree(var);
3551+ return FAILURE;
3552+}
3553+/* }}} */
3554+
3555+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3556+ */
3557+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3558+{
3559+ /* Drop if no more variables flag is set */
3560+ if (VARFILTER_G(no_more_uploads)) {
3561+ return FAILURE;
3562+ }
3563+ /* Drop this fileupload if the limit is reached */
3564+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3565+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3566+ VARFILTER_G(no_more_uploads) = 1;
3567+ return FAILURE;
3568+ }
3569+
3570+ return SUCCESS;
3571+}
3572+/* }}} */
3573+
3574+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3575+ */
3576+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3577+{
3578+
3579+ if (VARFILTER_G(disallow_elf_files)) {
3580+
3581+ if (offset == 0 && buffer_len > 10) {
3582+
3583+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3584+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3585+ return FAILURE;
3586+ }
3587+ }
3588+
3589+ }
3590+
3591+ return SUCCESS;
3592+}
3593+/* }}} */
3594+
3595+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3596+ */
3597+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3598+{
3599+ int retval = SUCCESS;
3600+
3601+ if (VARFILTER_G(verification_script)) {
3602+ char cmd[8192];
3603+ FILE *in;
3604+ int first=1;
3605+
3606+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3607+
3608+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3609+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3610+ return FAILURE;
3611+ }
3612+
3613+ retval = FAILURE;
3614+
3615+ /* read and forget the result */
3616+ while (1) {
3617+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3618+ if (readbytes<=0) {
3619+ break;
3620+ }
3621+ if (first) {
3622+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3623+ first = 0;
3624+ }
3625+ }
3626+ pclose(in);
3627+ }
3628+
3629+ if (retval != SUCCESS) {
3630+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3631+ return FAILURE;
3632+ }
3633+
3634+ VARFILTER_G(cur_uploads)++;
3635+ return SUCCESS;
3636+}
3637+/* }}} */
3638+
3639+/* {{{ SAPI_INPUT_FILTER_FUNC
3640+ */
3641+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3642+{
3643+ char *index, *prev_index = NULL;
3644+ unsigned int var_len, total_len, depth = 0;
3645+
3646+ /* Drop this variable if the limit was reached */
3647+ switch (arg) {
3648+ case PARSE_GET:
3649+ if (VARFILTER_G(no_more_get_variables)) {
3650+ return 0;
3651+ }
3652+ break;
3653+ case PARSE_POST:
3654+ if (VARFILTER_G(no_more_post_variables)) {
3655+ return 0;
3656+ }
3657+ break;
3658+ case PARSE_COOKIE:
3659+ if (VARFILTER_G(no_more_cookie_variables)) {
3660+ return 0;
3661+ }
3662+ break;
3663+ default: /* we do not want to protect parse_str() and friends */
3664+ if (new_val_len) {
3665+ *new_val_len = val_len;
3666+ }
3667+ return 1;
3668+ }
3669+ if (VARFILTER_G(no_more_variables)) {
3670+ return 0;
3671+ }
3672+
3673+ /* Drop this variable if the limit is now reached */
3674+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3675+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3676+ VARFILTER_G(no_more_variables) = 1;
3677+ return 0;
3678+ }
3679+ switch (arg) {
3680+ case PARSE_GET:
3681+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3682+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3683+ VARFILTER_G(no_more_get_variables) = 1;
3684+ return 0;
3685+ }
3686+ break;
3687+ case PARSE_COOKIE:
3688+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3689+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3690+ VARFILTER_G(no_more_cookie_variables) = 1;
3691+ return 0;
3692+ }
3693+ break;
3694+ case PARSE_POST:
3695+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3696+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3697+ VARFILTER_G(no_more_post_variables) = 1;
3698+ return 0;
3699+ }
3700+ break;
3701+ }
3702+
3703+
3704+ /* Drop this variable if it exceeds the value length limit */
3705+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3706+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3707+ return 0;
3708+ }
3709+ switch (arg) {
3710+ case PARSE_GET:
3711+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3712+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3713+ return 0;
3714+ }
3715+ break;
3716+ case PARSE_COOKIE:
3717+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3718+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3719+ return 0;
3720+ }
3721+ break;
3722+ case PARSE_POST:
3723+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3724+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3725+ return 0;
3726+ }
3727+ break;
3728+ }
3729+
3730+ /* Normalize the variable name */
3731+ normalize_varname(var);
3732+
3733+ /* Find length of variable name */
3734+ index = strchr(var, '[');
3735+ total_len = strlen(var);
3736+ var_len = index ? index-var : total_len;
3737+
3738+ /* Drop this variable if it exceeds the varname/total length limit */
3739+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3740+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3741+ return 0;
3742+ }
3743+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3744+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3745+ return 0;
3746+ }
3747+ switch (arg) {
3748+ case PARSE_GET:
3749+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3750+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3751+ return 0;
3752+ }
3753+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3754+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3755+ return 0;
3756+ }
3757+ break;
3758+ case PARSE_COOKIE:
3759+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3760+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3761+ return 0;
3762+ }
3763+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3764+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3765+ return 0;
3766+ }
3767+ break;
3768+ case PARSE_POST:
3769+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3770+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3771+ return 0;
3772+ }
3773+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3774+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3775+ return 0;
3776+ }
3777+ break;
3778+ }
3779+
3780+ /* Find out array depth */
3781+ while (index) {
3782+ unsigned int index_length;
3783+
3784+ depth++;
3785+ index = strchr(index+1, '[');
3786+
3787+ if (prev_index) {
3788+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3789+
3790+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3791+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3792+ return 0;
3793+ }
3794+ switch (arg) {
3795+ case PARSE_GET:
3796+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3797+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3798+ return 0;
3799+ }
3800+ break;
3801+ case PARSE_COOKIE:
3802+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3803+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3804+ return 0;
3805+ }
3806+ break;
3807+ case PARSE_POST:
3808+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3809+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3810+ return 0;
3811+ }
3812+ break;
3813+ }
3814+ prev_index = index;
3815+ }
3816+
3817+ }
3818+
3819+ /* Drop this variable if it exceeds the array depth limit */
3820+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3821+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3822+ return 0;
3823+ }
3824+ switch (arg) {
3825+ case PARSE_GET:
3826+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3827+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3828+ return 0;
3829+ }
3830+ break;
3831+ case PARSE_COOKIE:
3832+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3833+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3834+ return 0;
3835+ }
3836+ break;
3837+ case PARSE_POST:
3838+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3839+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3840+ return 0;
3841+ }
3842+ break;
3843+ }
3844+
3845+ /* Check if variable value is truncated by a \0 */
3846+
3847+ if (val && *val && val_len != strlen(*val)) {
3848+
3849+ if (VARFILTER_G(disallow_nul)) {
3850+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3851+ return 0;
3852+ }
3853+ switch (arg) {
3854+ case PARSE_GET:
3855+ if (VARFILTER_G(disallow_get_nul)) {
3856+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3857+ return 0;
3858+ }
3859+ break;
3860+ case PARSE_COOKIE:
3861+ if (VARFILTER_G(disallow_cookie_nul)) {
3862+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3863+ return 0;
3864+ }
3865+ break;
3866+ case PARSE_POST:
3867+ if (VARFILTER_G(disallow_post_nul)) {
3868+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3869+ return 0;
3870+ }
3871+ break;
3872+ }
3873+ }
3874+
3875+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3876+ /* This is to protect several silly scripts that do globalizing themself */
3877+
3878+ switch (var_len) {
3879+ case 18:
3880+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3881+ break;
3882+ case 17:
3883+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3884+ break;
3885+ case 16:
3886+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3887+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3888+ break;
3889+ case 15:
3890+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3891+ break;
3892+ case 14:
3893+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3894+ break;
3895+ case 13:
3896+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3897+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3898+ break;
3899+ case 8:
3900+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3901+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3902+ break;
3903+ case 7:
3904+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3905+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3906+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3907+ break;
3908+ case 6:
3909+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3910+ break;
3911+ case 5:
3912+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3913+ break;
3914+ case 4:
3915+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3916+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3917+ break;
3918+ }
3919+
3920+ /* Okay let PHP register this variable */
3921+ VARFILTER_G(cur_request_variables)++;
3922+ switch (arg) {
3923+ case PARSE_GET:
3924+ VARFILTER_G(cur_get_vars)++;
3925+ break;
3926+ case PARSE_COOKIE:
3927+ VARFILTER_G(cur_cookie_vars)++;
3928+ break;
3929+ case PARSE_POST:
3930+ VARFILTER_G(cur_post_vars)++;
3931+ break;
3932+ }
3933+
3934+ if (new_val_len) {
3935+ *new_val_len = val_len;
3936+ }
3937+
3938+ return 1;
3939+protected_varname:
3940+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3941+ return 0;
3942+}
3943+/* }}} */
3944+
3945+/*
3946+ * Local variables:
3947+ * tab-width: 4
3948+ * c-basic-offset: 4
3949+ * End:
3950+ * vim600: noet sw=4 ts=4 fdm=marker
3951+ * vim<600: noet sw=4 ts=4
3952+ */
3953+
3954+
3955diff -Nura php-4.4.1/main/fopen_wrappers.c hardening-patch-4.4.1-0.4.6/main/fopen_wrappers.c
3956--- php-4.4.1/main/fopen_wrappers.c 2005-09-27 17:08:43.000000000 +0200
3957+++ hardening-patch-4.4.1-0.4.6/main/fopen_wrappers.c 2005-11-05 13:04:08.000000000 +0100
3958@@ -156,6 +156,21 @@
3959 char *pathbuf;
3960 char *ptr;
3961 char *end;
3962+ char path_copy[MAXPATHLEN];
3963+ int path_len;
3964+
3965+ /* Special case path ends with a trailing slash */
3966+ path_len = strlen(path);
3967+ if (path_len >= MAXPATHLEN) {
3968+ errno = EPERM; /* we deny permission to open it */
3969+ return -1;
3970+ }
3971+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3972+ memcpy(path_copy, path, path_len+1);
3973+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3974+ path_copy[path_len] = '\0';
3975+ path = (const char *)&path_copy;
3976+ }
3977
3978 pathbuf = estrdup(PG(open_basedir));
3979
3980diff -Nura php-4.4.1/main/hardened_globals.h hardening-patch-4.4.1-0.4.6/main/hardened_globals.h
3981--- php-4.4.1/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3982+++ hardening-patch-4.4.1-0.4.6/main/hardened_globals.h 2005-11-25 13:26:41.000000000 +0100
3983@@ -0,0 +1,62 @@
3984+/*
3985+ +----------------------------------------------------------------------+
3986+ | Hardening-Patch for PHP |
3987+ +----------------------------------------------------------------------+
3988+ | Copyright (c) 2004-2005 Stefan Esser |
3989+ +----------------------------------------------------------------------+
3990+ | This source file is subject to version 2.02 of the PHP license, |
3991+ | that is bundled with this package in the file LICENSE, and is |
3992+ | available at through the world-wide-web at |
3993+ | http://www.php.net/license/2_02.txt. |
3994+ | If you did not receive a copy of the PHP license and are unable to |
3995+ | obtain it through the world-wide-web, please send a note to |
3996+ | license@php.net so we can mail you a copy immediately. |
3997+ +----------------------------------------------------------------------+
3998+ | Author: Stefan Esser <sesser@hardened-php.net> |
3999+ +----------------------------------------------------------------------+
4000+ */
4001+
4002+#ifndef HARDENED_GLOBALS_H
4003+#define HARDENED_GLOBALS_H
4004+
4005+typedef struct _hardened_globals hardened_globals_struct;
4006+
4007+#ifdef ZTS
4008+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4009+extern int hardened_globals_id;
4010+#else
4011+# define HG(v) (hardened_globals.v)
4012+extern struct _hardened_globals hardened_globals;
4013+#endif
4014+
4015+
4016+struct _hardened_globals {
4017+#if HARDENING_PATCH_MM_PROTECT
4018+ unsigned int canary_1;
4019+ unsigned int canary_2;
4020+#endif
4021+#if HARDENING_PATCH_LL_PROTECT
4022+ unsigned int canary_3;
4023+ unsigned int canary_4;
4024+ unsigned int ll_canary_inited;
4025+#endif
4026+ zend_bool hphp_sql_bailout_on_error;
4027+ zend_bool hphp_multiheader;
4028+ HashTable *eval_whitelist;
4029+ HashTable *eval_blacklist;
4030+ HashTable *func_whitelist;
4031+ HashTable *func_blacklist;
4032+ HashTable *include_whitelist;
4033+ HashTable *include_blacklist;
4034+ unsigned int dummy;
4035+};
4036+
4037+
4038+#endif /* HARDENED_GLOBALS_H */
4039+
4040+/*
4041+ * Local variables:
4042+ * tab-width: 4
4043+ * c-basic-offset: 4
4044+ * End:
4045+ */
4046diff -Nura php-4.4.1/main/hardening_patch.c hardening-patch-4.4.1-0.4.6/main/hardening_patch.c
4047--- php-4.4.1/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4048+++ hardening-patch-4.4.1-0.4.6/main/hardening_patch.c 2005-11-25 13:23:41.000000000 +0100
4049@@ -0,0 +1,430 @@
4050+/*
4051+ +----------------------------------------------------------------------+
4052+ | Hardening Patch for PHP |
4053+ +----------------------------------------------------------------------+
4054+ | Copyright (c) 2004-2005 Stefan Esser |
4055+ +----------------------------------------------------------------------+
4056+ | This source file is subject to version 2.02 of the PHP license, |
4057+ | that is bundled with this package in the file LICENSE, and is |
4058+ | available at through the world-wide-web at |
4059+ | http://www.php.net/license/2_02.txt. |
4060+ | If you did not receive a copy of the PHP license and are unable to |
4061+ | obtain it through the world-wide-web, please send a note to |
4062+ | license@php.net so we can mail you a copy immediately. |
4063+ +----------------------------------------------------------------------+
4064+ | Author: Stefan Esser <sesser@hardened-php.net> |
4065+ +----------------------------------------------------------------------+
4066+ */
4067+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4068+
4069+#include "php.h"
4070+
4071+#include <stdio.h>
4072+#include <stdlib.h>
4073+
4074+#if HAVE_UNISTD_H
4075+#include <unistd.h>
4076+#endif
4077+#include "SAPI.h"
4078+#include "php_globals.h"
4079+
4080+#if HARDENING_PATCH
4081+
4082+#ifdef HAVE_SYS_SOCKET_H
4083+#include <sys/socket.h>
4084+#endif
4085+
4086+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4087+#undef AF_UNIX
4088+#endif
4089+
4090+#if defined(AF_UNIX)
4091+#include <sys/un.h>
4092+#endif
4093+
4094+#define SYSLOG_PATH "/dev/log"
4095+
4096+#include "snprintf.h"
4097+
4098+#include "hardening_patch.h"
4099+
4100+#ifdef ZTS
4101+#include "hardened_globals.h"
4102+int hardened_globals_id;
4103+#else
4104+struct _hardened_globals hardened_globals;
4105+#endif
4106+
4107+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4108+{
4109+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4110+}
4111+
4112+
4113+PHPAPI void hardened_startup()
4114+{
4115+#ifdef ZTS
4116+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4117+#else
4118+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4119+#endif
4120+}
4121+
4122+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4123+{
4124+ HG(canary_1) = php_canary();
4125+ HG(canary_2) = php_canary();
4126+}
4127+
4128+char *loglevel2string(int loglevel)
4129+{
4130+ switch (loglevel) {
4131+ case S_FILES:
4132+ return "FILES";
4133+ case S_INCLUDE:
4134+ return "INCLUDE";
4135+ case S_MEMORY:
4136+ return "MEMORY";
4137+ case S_MISC:
4138+ return "MISC";
4139+ case S_SQL:
4140+ return "SQL";
4141+ case S_EXECUTOR:
4142+ return "EXECUTOR";
4143+ case S_VARS:
4144+ return "VARS";
4145+ default:
4146+ return "UNKNOWN";
4147+ }
4148+}
4149+
4150+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4151+{
4152+#if defined(AF_UNIX)
4153+ int s, r, i=0;
4154+ struct sockaddr_un saun;
4155+ char buf[4096+64];
4156+ char error[4096+100];
4157+ char *ip_address;
4158+ char *fname;
4159+ int lineno;
4160+ va_list ap;
4161+ TSRMLS_FETCH();
4162+
4163+ if (EG(hphp_log_use_x_forwarded_for)) {
4164+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4165+ if (ip_address == NULL) {
4166+ ip_address = "X-FORWARDED-FOR not set";
4167+ }
4168+ } else {
4169+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4170+ if (ip_address == NULL) {
4171+ ip_address = "REMOTE_ADDR not set";
4172+ }
4173+ }
4174+
4175+
4176+ va_start(ap, fmt);
4177+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4178+ va_end(ap);
4179+ while (error[i]) {
4180+ if (error[i] < 32) error[i] = '.';
4181+ i++;
4182+ }
4183+
4184+ if (zend_is_executing(TSRMLS_C)) {
4185+ lineno = zend_get_executed_lineno(TSRMLS_C);
4186+ fname = zend_get_executed_filename(TSRMLS_C);
4187+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4188+ } else {
4189+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4190+ if (fname==NULL) {
4191+ fname = "unknown";
4192+ }
4193+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4194+ }
4195+
4196+ /* Syslog-Logging disabled? */
4197+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4198+ goto log_sapi;
4199+ }
4200+
4201+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4202+
4203+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4204+ if (s == -1) {
4205+ goto log_sapi;
4206+ }
4207+
4208+ memset(&saun, 0, sizeof(saun));
4209+ saun.sun_family = AF_UNIX;
4210+ strcpy(saun.sun_path, SYSLOG_PATH);
4211+ /*saun.sun_len = sizeof(saun);*/
4212+
4213+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4214+ if (r) {
4215+ close(s);
4216+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4217+ if (s == -1) {
4218+ goto log_sapi;
4219+ }
4220+
4221+ memset(&saun, 0, sizeof(saun));
4222+ saun.sun_family = AF_UNIX;
4223+ strcpy(saun.sun_path, SYSLOG_PATH);
4224+ /*saun.sun_len = sizeof(saun);*/
4225+
4226+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4227+ if (r) {
4228+ close(s);
4229+ goto log_sapi;
4230+ }
4231+ }
4232+ send(s, error, strlen(error), 0);
4233+
4234+ close(s);
4235+
4236+log_sapi:
4237+ /* SAPI Logging activated? */
4238+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4239+ sapi_module.log_message(buf);
4240+ }
4241+
4242+log_script:
4243+ /* script logging activaed? */
4244+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4245+ char cmd[8192], *cmdpos, *bufpos;
4246+ FILE *in;
4247+ int space;
4248+
4249+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4250+ space = sizeof(cmd) - strlen(cmd);
4251+ cmdpos = cmd + strlen(cmd);
4252+ bufpos = buf;
4253+ if (space <= 1) return;
4254+ while (space > 2 && *bufpos) {
4255+ if (*bufpos == '\'') {
4256+ if (space<=5) break;
4257+ *cmdpos++ = '\'';
4258+ *cmdpos++ = '\\';
4259+ *cmdpos++ = '\'';
4260+ *cmdpos++ = '\'';
4261+ bufpos++;
4262+ space-=4;
4263+ } else {
4264+ *cmdpos++ = *bufpos++;
4265+ space--;
4266+ }
4267+ }
4268+ *cmdpos++ = '\'';
4269+ *cmdpos = 0;
4270+
4271+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4272+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4273+ return;
4274+ }
4275+ /* read and forget the result */
4276+ while (1) {
4277+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4278+ if (readbytes<=0) {
4279+ break;
4280+ }
4281+ }
4282+ pclose(in);
4283+ }
4284+
4285+#endif
4286+}
4287+#endif
4288+
4289+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4290+
4291+/* will be replaced later with more compatible method */
4292+PHPAPI unsigned int php_canary()
4293+{
4294+ time_t t;
4295+ unsigned int canary;
4296+ int fd;
4297+
4298+ fd = open("/dev/urandom", 0);
4299+ if (fd != -1) {
4300+ int r = read(fd, &canary, sizeof(canary));
4301+ close(fd);
4302+ if (r == sizeof(canary)) {
4303+ return (canary);
4304+ }
4305+ }
4306+ /* not good but we never want to do this */
4307+ time(&t);
4308+ canary = *(unsigned int *)&t + getpid() << 16;
4309+ return (canary);
4310+}
4311+#endif
4312+
4313+#if HARDENING_PATCH_INC_PROTECT
4314+
4315+PHPAPI int php_is_valid_include(zval *z)
4316+{
4317+ char *filename;
4318+ int len, i;
4319+ TSRMLS_FETCH();
4320+
4321+ /* must be of type string */
4322+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4323+ return (0);
4324+ }
4325+
4326+ /* short cut */
4327+ filename = z->value.str.val;
4328+ len = z->value.str.len;
4329+
4330+ /* 1. must be shorter than MAXPATHLEN */
4331+ if (len > MAXPATHLEN) {
4332+ char *fname = estrndup(filename, len);
4333+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4334+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4335+ efree(fname);
4336+ return (0);
4337+ }
4338+
4339+ /* 2. must not be cutted */
4340+ if (len != strlen(filename)) {
4341+ char *fname = estrndup(filename, len);
4342+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4343+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4344+ efree(fname);
4345+ return (0);
4346+ }
4347+
4348+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4349+ if (strstr(filename, "://")) {
4350+ char *fname = estrndup(filename, len);
4351+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4352+
4353+ /* no black or whitelist then disallow all */
4354+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4355+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4356+ efree(fname);
4357+ return (0);
4358+ }
4359+
4360+ /* whitelist is stronger than blacklist */
4361+ if (HG(include_whitelist)) {
4362+ char *s, *t, *h, *index;
4363+ uint indexlen;
4364+ ulong numindex;
4365+
4366+ s = filename;
4367+
4368+ do {
4369+ zend_bool isOk = 0;
4370+ int tlen;
4371+
4372+ t = h = strstr(s, "://");
4373+ if (h == NULL) break;
4374+
4375+
4376+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4377+ t--;
4378+ }
4379+
4380+ tlen = strlen(t);
4381+
4382+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4383+ do {
4384+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4385+
4386+ if (r==HASH_KEY_NON_EXISTANT) {
4387+ break;
4388+ }
4389+ if (r==HASH_KEY_IS_STRING) {
4390+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4391+ if (strncmp(t, index, indexlen-1)==0) {
4392+ isOk = 1;
4393+ break;
4394+ }
4395+ }
4396+ }
4397+
4398+ zend_hash_move_forward(HG(include_whitelist));
4399+ } while (1);
4400+
4401+ /* not found in whitelist */
4402+ if (!isOk) {
4403+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4404+ efree(fname);
4405+ return 0;
4406+ }
4407+
4408+ s = h + 3;
4409+ } while (1);
4410+ } else {
4411+ /* okay then handle the blacklist */
4412+ char *s, *t, *h, *index;
4413+ uint indexlen;
4414+ ulong numindex;
4415+
4416+ s = filename;
4417+
4418+ do {
4419+ int tlen;
4420+
4421+ t = h = strstr(s, "://");
4422+ if (h == NULL) break;
4423+
4424+
4425+ while (t > s) {
4426+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4427+ }
4428+
4429+ tlen = strlen(t);
4430+
4431+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4432+ do {
4433+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4434+
4435+ if (r==HASH_KEY_NON_EXISTANT) {
4436+ break;
4437+ }
4438+ if (r==HASH_KEY_IS_STRING) {
4439+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4440+ if (strncmp(t, index, indexlen-1)==0) {
4441+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4442+ efree(fname);
4443+ return 0;
4444+ }
4445+ }
4446+ }
4447+
4448+ zend_hash_move_forward(HG(include_blacklist));
4449+ } while (1);
4450+
4451+ s = h + 3;
4452+ } while (1);
4453+ }
4454+
4455+ efree(fname);
4456+ }
4457+
4458+ /* 4. must not be an uploaded file */
4459+ if (SG(rfc1867_uploaded_files)) {
4460+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4461+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4462+ return (0);
4463+ }
4464+ }
4465+
4466+ /* passed all tests */
4467+ return (1);
4468+}
4469+
4470+#endif
4471+
4472+/*
4473+ * Local variables:
4474+ * tab-width: 4
4475+ * c-basic-offset: 4
4476+ * End:
4477+ * vim600: sw=4 ts=4 fdm=marker
4478+ * vim<600: sw=4 ts=4
4479+ */
4480diff -Nura php-4.4.1/main/hardening_patch.h hardening-patch-4.4.1-0.4.6/main/hardening_patch.h
4481--- php-4.4.1/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4482+++ hardening-patch-4.4.1-0.4.6/main/hardening_patch.h 2005-11-25 13:23:41.000000000 +0100
4483@@ -0,0 +1,46 @@
4484+/*
4485+ +----------------------------------------------------------------------+
4486+ | Hardening Patch for PHP |
4487+ +----------------------------------------------------------------------+
4488+ | Copyright (c) 2004-2005 Stefan Esser |
4489+ +----------------------------------------------------------------------+
4490+ | This source file is subject to version 2.02 of the PHP license, |
4491+ | that is bundled with this package in the file LICENSE, and is |
4492+ | available at through the world-wide-web at |
4493+ | http://www.php.net/license/2_02.txt. |
4494+ | If you did not receive a copy of the PHP license and are unable to |
4495+ | obtain it through the world-wide-web, please send a note to |
4496+ | license@php.net so we can mail you a copy immediately. |
4497+ +----------------------------------------------------------------------+
4498+ | Author: Stefan Esser <sesser@hardened-php.net> |
4499+ +----------------------------------------------------------------------+
4500+ */
4501+
4502+#ifndef HARDENING_PATCH_H
4503+#define HARDENING_PATCH_H
4504+
4505+#include "zend.h"
4506+
4507+#if HARDENING_PATCH
4508+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4509+PHPAPI void hardened_startup();
4510+#define HARDENING_PATCH_VERSION "0.4.6"
4511+
4512+#endif
4513+
4514+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4515+PHPAPI unsigned int php_canary();
4516+#endif
4517+
4518+#if HARDENING_PATCH_INC_PROTECT
4519+PHPAPI int php_is_valid_include(zval *z);
4520+#endif
4521+
4522+#endif /* HARDENING_PATCH_H */
4523+
4524+/*
4525+ * Local variables:
4526+ * tab-width: 4
4527+ * c-basic-offset: 4
4528+ * End:
4529+ */
4530diff -Nura php-4.4.1/main/hardening_patch.m4 hardening-patch-4.4.1-0.4.6/main/hardening_patch.m4
4531--- php-4.4.1/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4532+++ hardening-patch-4.4.1-0.4.6/main/hardening_patch.m4 2005-11-25 13:23:41.000000000 +0100
4533@@ -0,0 +1,95 @@
4534+dnl
4535+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4536+dnl
4537+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4538+dnl
4539+
4540+AC_ARG_ENABLE(hardening-patch-mm-protect,
4541+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4542+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4543+],[
4544+ DO_HARDENING_PATCH_MM_PROTECT=yes
4545+])
4546+
4547+AC_ARG_ENABLE(hardening-patch-ll-protect,
4548+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4549+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4550+],[
4551+ DO_HARDENING_PATCH_LL_PROTECT=yes
4552+])
4553+
4554+AC_ARG_ENABLE(hardening-patch-inc-protect,
4555+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4556+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4557+],[
4558+ DO_HARDENING_PATCH_INC_PROTECT=yes
4559+])
4560+
4561+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4562+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4563+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4564+],[
4565+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4566+])
4567+
4568+AC_ARG_ENABLE(hardening-patch-hash-protect,
4569+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4570+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4571+],[
4572+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4573+])
4574+
4575+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4576+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4577+
4578+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4579+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4580+
4581+AC_MSG_CHECKING(whether to protect include/require statements)
4582+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4583+
4584+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4585+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4586+
4587+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4588+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4589+
4590+
4591+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4592+
4593+
4594+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4595+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4596+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4597+else
4598+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4599+fi
4600+
4601+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4602+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4603+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4604+else
4605+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4606+fi
4607+
4608+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4609+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4610+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4611+else
4612+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4613+fi
4614+
4615+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4616+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4617+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4618+else
4619+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4620+fi
4621+
4622+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4623+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4624+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4625+else
4626+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4627+fi
4628+
4629diff -Nura php-4.4.1/main/main.c hardening-patch-4.4.1-0.4.6/main/main.c
4630--- php-4.4.1/main/main.c 2005-09-15 16:06:15.000000000 +0200
4631+++ hardening-patch-4.4.1-0.4.6/main/main.c 2005-11-20 19:49:42.000000000 +0100
4632@@ -92,6 +92,10 @@
4633 PHPAPI int core_globals_id;
4634 #endif
4635
4636+#if HARDENING_PATCH
4637+#include "hardened_globals.h"
4638+#endif
4639+
4640 #define ERROR_BUF_LEN 1024
4641
4642 typedef struct {
4643@@ -142,10 +146,33 @@
4644 */
4645 static PHP_INI_MH(OnChangeMemoryLimit)
4646 {
4647+#if HARDENING_PATCH
4648+ long orig_memory_limit;
4649+
4650+ if (entry->modified) {
4651+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4652+ } else {
4653+ orig_memory_limit = 1<<30;
4654+ }
4655+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4656+ orig_memory_limit = 1<<30;
4657+ }
4658+#endif
4659 if (new_value) {
4660 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4661+#if HARDENING_PATCH
4662+ if (PG(memory_limit) > orig_memory_limit) {
4663+ PG(memory_limit) = orig_memory_limit;
4664+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4665+ return FAILURE;
4666+ }
4667+#endif
4668 } else {
4669+#if HARDENING_PATCH
4670+ PG(memory_limit) = orig_memory_limit;
4671+#else
4672 PG(memory_limit) = 1<<30; /* effectively, no limit */
4673+#endif
4674 }
4675 return zend_set_memory_limit(PG(memory_limit));
4676 }
4677@@ -998,6 +1025,9 @@
4678
4679 zend_try {
4680 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4681+#if HARDENING_PATCH
4682+ hardened_clear_mm_canaries(TSRMLS_C);
4683+#endif
4684 } zend_end_try();
4685
4686 zend_try {
4687@@ -1088,6 +1118,10 @@
4688 tsrm_ls = ts_resource(0);
4689 #endif
4690
4691+#if HARDENING_PATCH
4692+ hardened_startup();
4693+#endif
4694+
4695 sapi_initialize_empty_request(TSRMLS_C);
4696 sapi_activate(TSRMLS_C);
4697
4698@@ -1100,6 +1134,12 @@
4699 php_output_startup();
4700 php_output_activate(TSRMLS_C);
4701
4702+#if HARDENING_PATCH_INC_PROTECT
4703+ zuf.is_valid_include = php_is_valid_include;
4704+#endif
4705+#if HARDENING_PATCH
4706+ zuf.security_log_function = php_security_log;
4707+#endif
4708 zuf.error_function = php_error_cb;
4709 zuf.printf_function = php_printf;
4710 zuf.write_function = php_body_write_wrapper;
4711@@ -1201,6 +1241,10 @@
4712 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4713 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);
4714 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4715+#if HARDENING_PATCH
4716+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4717+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4718+#endif
4719 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4720 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4721 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4722@@ -1308,7 +1352,7 @@
4723 */
4724 static inline void php_register_server_variables(TSRMLS_D)
4725 {
4726- zval *array_ptr=NULL;
4727+ zval *array_ptr=NULL, *vptr;
4728
4729 ALLOC_ZVAL(array_ptr);
4730 array_init(array_ptr);
4731diff -Nura php-4.4.1/main/php_config.h.in hardening-patch-4.4.1-0.4.6/main/php_config.h.in
4732--- php-4.4.1/main/php_config.h.in 2005-10-30 12:06:40.000000000 +0100
4733+++ hardening-patch-4.4.1-0.4.6/main/php_config.h.in 2005-11-05 13:04:08.000000000 +0100
4734@@ -859,6 +859,39 @@
4735 /* Enabling BIND8 compatibility for Panther */
4736 #undef BIND_8_COMPAT
4737
4738+/* Hardening-Patch */
4739+#undef HARDENING_PATCH
4740+
4741+/* Memory Manager Protection */
4742+#undef HARDENING_PATCH_MM_PROTECT
4743+
4744+/* Memory Manager Protection */
4745+#undef HARDENING_PATCH_MM_PROTECT
4746+
4747+/* Linked List Protection */
4748+#undef HARDENING_PATCH_LL_PROTECT
4749+
4750+/* Linked List Protection */
4751+#undef HARDENING_PATCH_LL_PROTECT
4752+
4753+/* Include/Require Protection */
4754+#undef HARDENING_PATCH_INC_PROTECT
4755+
4756+/* Include/Require Protection */
4757+#undef HARDENING_PATCH_INC_PROTECT
4758+
4759+/* Fmt String Protection */
4760+#undef HARDENING_PATCH_FMT_PROTECT
4761+
4762+/* Fmt String Protection */
4763+#undef HARDENING_PATCH_FMT_PROTECT
4764+
4765+/* HashTable DTOR Protection */
4766+#undef HARDENING_PATCH_HASH_PROTECT
4767+
4768+/* HashTable DTOR Protection */
4769+#undef HARDENING_PATCH_HASH_PROTECT
4770+
4771 /* Whether you have AOLserver */
4772 #undef HAVE_AOLSERVER
4773
4774@@ -1142,6 +1175,12 @@
4775 /* Define if you have the getaddrinfo function */
4776 #undef HAVE_GETADDRINFO
4777
4778+/* Whether realpath is broken */
4779+#undef PHP_BROKEN_REALPATH
4780+
4781+/* Whether realpath is broken */
4782+#undef PHP_BROKEN_REALPATH
4783+
4784 /* Whether system headers declare timezone */
4785 #undef HAVE_DECLARED_TIMEZONE
4786
4787diff -Nura php-4.4.1/main/php_content_types.c hardening-patch-4.4.1-0.4.6/main/php_content_types.c
4788--- php-4.4.1/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
4789+++ hardening-patch-4.4.1-0.4.6/main/php_content_types.c 2005-11-05 13:04:08.000000000 +0100
4790@@ -77,6 +77,7 @@
4791 sapi_register_post_entries(php_post_entries);
4792 sapi_register_default_post_reader(php_default_post_reader);
4793 sapi_register_treat_data(php_default_treat_data);
4794+ sapi_register_input_filter(php_default_input_filter);
4795 return SUCCESS;
4796 }
4797 /* }}} */
4798diff -Nura php-4.4.1/main/php.h hardening-patch-4.4.1-0.4.6/main/php.h
4799--- php-4.4.1/main/php.h 2005-07-27 12:26:25.000000000 +0200
4800+++ hardening-patch-4.4.1-0.4.6/main/php.h 2005-11-05 13:04:08.000000000 +0100
4801@@ -35,11 +35,19 @@
4802 #include "zend_qsort.h"
4803 #include "php_compat.h"
4804
4805+
4806 #include "zend_API.h"
4807
4808 #undef sprintf
4809 #define sprintf php_sprintf
4810
4811+#if HARDENING_PATCH
4812+#if HAVE_REALPATH
4813+#undef realpath
4814+#define realpath php_realpath
4815+#endif
4816+#endif
4817+
4818 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4819 #undef PHP_DEBUG
4820 #define PHP_DEBUG ZEND_DEBUG
4821@@ -407,6 +415,10 @@
4822 #endif
4823 #endif /* !XtOffsetOf */
4824
4825+#if HARDENING_PATCH
4826+#include "hardening_patch.h"
4827+#endif
4828+
4829 #endif
4830
4831 /*
4832diff -Nura php-4.4.1/main/php_variables.c hardening-patch-4.4.1-0.4.6/main/php_variables.c
4833--- php-4.4.1/main/php_variables.c 2005-10-02 13:33:27.000000000 +0200
4834+++ hardening-patch-4.4.1-0.4.6/main/php_variables.c 2005-11-05 13:04:08.000000000 +0100
4835@@ -236,17 +236,28 @@
4836 while (var) {
4837 val = strchr(var, '=');
4838 if (val) { /* have a value */
4839- int val_len;
4840+ unsigned int val_len, new_val_len;
4841
4842 *val++ = '\0';
4843 php_url_decode(var, strlen(var));
4844 val_len = php_url_decode(val, strlen(val));
4845- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4846+ val = estrndup(val, val_len);
4847+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4848+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4849+ }
4850+ efree(val);
4851 }
4852 var = php_strtok_r(NULL, "&", &strtok_buf);
4853 }
4854 }
4855
4856+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
4857+{
4858+ /* TODO: check .ini setting here and apply user-defined input filter */
4859+ *new_val_len = val_len;
4860+ return 1;
4861+}
4862+
4863 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
4864 {
4865 char *res = NULL, *var, *val, *separator=NULL;
4866@@ -324,15 +335,26 @@
4867 while (var) {
4868 val = strchr(var, '=');
4869 if (val) { /* have a value */
4870- int val_len;
4871+ unsigned int val_len, new_val_len;
4872
4873 *val++ = '\0';
4874 php_url_decode(var, strlen(var));
4875 val_len = php_url_decode(val, strlen(val));
4876- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4877+ val = estrndup(val, val_len);
4878+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4879+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4880+ }
4881+ efree(val);
4882 } else {
4883+ unsigned int val_len, new_val_len;
4884+
4885 php_url_decode(var, strlen(var));
4886- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
4887+ val_len = 0;
4888+ val = estrndup("", 0);
4889+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4890+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4891+ }
4892+ efree(val);
4893 }
4894 var = php_strtok_r(NULL, separator, &strtok_buf);
4895 }
4896diff -Nura php-4.4.1/main/rfc1867.c hardening-patch-4.4.1-0.4.6/main/rfc1867.c
4897--- php-4.4.1/main/rfc1867.c 2005-07-13 22:47:56.000000000 +0200
4898+++ hardening-patch-4.4.1-0.4.6/main/rfc1867.c 2005-11-05 13:04:08.000000000 +0100
4899@@ -128,6 +128,8 @@
4900 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4901 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4902 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4903+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
4904+
4905
4906 void php_rfc1867_register_constants(TSRMLS_D)
4907 {
4908@@ -138,6 +140,7 @@
4909 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4910 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4911 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4912+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4913 }
4914
4915 static void normalize_protected_variable(char *varname TSRMLS_DC)
4916@@ -849,6 +852,7 @@
4917 char buff[FILLUNIT];
4918 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4919 int blen=0, wlen=0;
4920+ unsigned long offset;
4921
4922 zend_llist_clean(&header);
4923
4924@@ -897,21 +901,24 @@
4925 if (!filename && param) {
4926
4927 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
4928+ unsigned int new_val_len; /* Dummy variable */
4929
4930 if (!value) {
4931 value = estrdup("");
4932 }
4933
4934+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
4935 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
4936- if (php_mb_encoding_translation(TSRMLS_C)) {
4937- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4938- &num_vars, &num_vars_max TSRMLS_CC);
4939- } else {
4940- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4941- }
4942+ if (php_mb_encoding_translation(TSRMLS_C)) {
4943+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4944+ &num_vars, &num_vars_max TSRMLS_CC);
4945+ } else {
4946+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4947+ }
4948 #else
4949- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4950+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4951 #endif
4952+ }
4953 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
4954 max_file_size = atol(value);
4955 }
4956@@ -963,7 +970,11 @@
4957 tmp++;
4958 }
4959 }
4960-
4961+
4962+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4963+ skip_upload = 1;
4964+ }
4965+
4966 total_bytes = cancel_upload = 0;
4967
4968 if (!skip_upload) {
4969@@ -987,6 +998,11 @@
4970 cancel_upload = UPLOAD_ERROR_D;
4971 }
4972
4973+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4974+ cancel_upload = UPLOAD_ERROR_X;
4975+ }
4976+
4977+ offset = 0;
4978 end = 0;
4979 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4980 {
4981@@ -997,6 +1013,11 @@
4982 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
4983 cancel_upload = UPLOAD_ERROR_B;
4984 } else if (blen > 0) {
4985+
4986+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4987+ cancel_upload = UPLOAD_ERROR_X;
4988+ }
4989+
4990 wlen = write(fd, buff, blen);
4991
4992 if (wlen < blen) {
4993@@ -1004,6 +1025,7 @@
4994 cancel_upload = UPLOAD_ERROR_F;
4995 } else {
4996 total_bytes += wlen;
4997+ offset += wlen;
4998 }
4999 }
5000 }
5001@@ -1025,6 +1047,10 @@
5002 }
5003 #endif
5004
5005+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5006+ cancel_upload = UPLOAD_ERROR_X;
5007+ }
5008+
5009 if (cancel_upload) {
5010 if (temp_filename) {
5011 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5012diff -Nura php-4.4.1/main/SAPI.c hardening-patch-4.4.1-0.4.6/main/SAPI.c
5013--- php-4.4.1/main/SAPI.c 2005-10-19 22:36:19.000000000 +0200
5014+++ hardening-patch-4.4.1-0.4.6/main/SAPI.c 2005-11-05 13:04:08.000000000 +0100
5015@@ -837,6 +837,37 @@
5016 return SUCCESS;
5017 }
5018
5019+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))
5020+{
5021+ sapi_module.input_filter = input_filter;
5022+ return SUCCESS;
5023+}
5024+
5025+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5026+{
5027+ sapi_module.upload_varname_filter = upload_varname_filter;
5028+ return SUCCESS;
5029+}
5030+
5031+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5032+{
5033+ sapi_module.pre_upload_filter = pre_upload_filter;
5034+ return SUCCESS;
5035+}
5036+
5037+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
5038+{
5039+ sapi_module.upload_content_filter = upload_content_filter;
5040+ return SUCCESS;
5041+}
5042+
5043+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5044+{
5045+ sapi_module.post_upload_filter = post_upload_filter;
5046+ return SUCCESS;
5047+}
5048+
5049+
5050
5051 SAPI_API int sapi_flush(TSRMLS_D)
5052 {
5053diff -Nura php-4.4.1/main/SAPI.h hardening-patch-4.4.1-0.4.6/main/SAPI.h
5054--- php-4.4.1/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
5055+++ hardening-patch-4.4.1-0.4.6/main/SAPI.h 2005-11-05 13:04:08.000000000 +0100
5056@@ -101,9 +101,10 @@
5057 char *current_user;
5058 int current_user_length;
5059
5060- /* this is necessary for CLI module */
5061- int argc;
5062- char **argv;
5063+ /* this is necessary for CLI module */
5064+ int argc;
5065+ char **argv;
5066+
5067 } sapi_request_info;
5068
5069
5070@@ -177,6 +178,10 @@
5071 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5072 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5073 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5074+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));
5075+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5076+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
5077+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5078
5079 SAPI_API int sapi_flush(TSRMLS_D);
5080 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5081@@ -238,8 +243,16 @@
5082 int (*get_target_uid)(uid_t * TSRMLS_DC);
5083 int (*get_target_gid)(gid_t * TSRMLS_DC);
5084
5085+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5086+
5087+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5088+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5089+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5090+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5091+
5092 void (*ini_defaults)(HashTable *configuration_hash);
5093 int phpinfo_as_text;
5094+
5095 };
5096
5097
5098@@ -262,16 +275,27 @@
5099
5100 #define SAPI_DEFAULT_MIMETYPE "text/html"
5101 #define SAPI_DEFAULT_CHARSET ""
5102+
5103+#if HARDENING_PATCH
5104+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5105+#else
5106 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5107+#endif
5108
5109 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5110 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5111
5112 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5113+#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)
5114+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5115+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5116+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
5117+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5118
5119 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5120 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5121 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5122+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5123
5124 #define STANDARD_SAPI_MODULE_PROPERTIES
5125
5126diff -Nura php-4.4.1/main/snprintf.c hardening-patch-4.4.1-0.4.6/main/snprintf.c
5127--- php-4.4.1/main/snprintf.c 2005-04-08 07:44:53.000000000 +0200
5128+++ hardening-patch-4.4.1-0.4.6/main/snprintf.c 2005-11-05 13:04:08.000000000 +0100
5129@@ -1013,7 +1013,11 @@
5130
5131
5132 case 'n':
5133+#if HARDENING_PATCH_FMT_PROTECT
5134+ php_security_log(S_MISC, "'n' specifier within format string");
5135+#else
5136 *(va_arg(ap, int *)) = cc;
5137+#endif
5138 break;
5139
5140 /*
5141diff -Nura php-4.4.1/main/spprintf.c hardening-patch-4.4.1-0.4.6/main/spprintf.c
5142--- php-4.4.1/main/spprintf.c 2005-04-08 07:44:53.000000000 +0200
5143+++ hardening-patch-4.4.1-0.4.6/main/spprintf.c 2005-11-05 13:04:08.000000000 +0100
5144@@ -630,7 +630,11 @@
5145
5146
5147 case 'n':
5148+#if HARDENING_PATCH_FMT_PROTECT
5149+ php_security_log(S_MISC, "'n' specifier within format string");
5150+#else
5151 *(va_arg(ap, int *)) = xbuf->len;
5152+#endif
5153 break;
5154
5155 /*
5156diff -Nura php-4.4.1/php.ini-dist hardening-patch-4.4.1-0.4.6/php.ini-dist
5157--- php-4.4.1/php.ini-dist 2005-04-28 15:14:45.000000000 +0200
5158+++ hardening-patch-4.4.1-0.4.6/php.ini-dist 2005-11-15 21:44:41.000000000 +0100
5159@@ -1112,6 +1112,209 @@
5160 ;exif.decode_jis_motorola = JIS
5161 ;exif.decode_jis_intel = JIS
5162
5163+[hardening-patch]
5164+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5165+; Hardening-Patch's logging ;
5166+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5167+
5168+;
5169+; hphp.log.syslog - Configures level for alerts reported through syslog
5170+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5171+; hphp.log.script - Configures level for alerts reported through external script
5172+;
5173+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5174+; Or each number up to get desired Hardening-Patch's reporting level
5175+;
5176+; S_ALL - All alerts
5177+; S_MEMORY - All canary violations and the safe unlink protection use this class
5178+; S_VARS - All variable filters trigger this class
5179+; S_FILES - All violation of uploaded files filter use this class
5180+; S_INCLUDE - The protection against malicious include filenames use this class
5181+; S_SQL - Failed SQL queries in MySQL are logged with this class
5182+; S_EXECUTOR - The execution depth protection uses this logging class
5183+; S_MISC - All other log messages (f.e. format string protection) use this class
5184+;
5185+; Example:
5186+;
5187+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5188+; memory alerts through syslog and SQL+Include alerts fo the script
5189+;
5190+;hphp.log.syslog = S_MEMORY
5191+;hphp.log.sapi = S_ALL & ~S_MEMORY
5192+;hphp.log.script = S_INCLUDE | S_SQL
5193+;
5194+; Syslog logging:
5195+;
5196+; - Facility configuration: one of the following facilities
5197+;
5198+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5199+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5200+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5201+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5202+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5203+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5204+; LOG_PERROR
5205+;
5206+; - Priority configuration: one of the followinf priorities
5207+;
5208+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5209+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5210+;
5211+hphp.log.syslog.priority = LOG_ALERT
5212+hphp.log.syslog.facility = LOG_USER
5213+;
5214+; Script logging:
5215+;
5216+;hphp.log.script.name = /home/hphp/log_script
5217+;
5218+; Alert configuration:
5219+;
5220+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5221+;
5222+;hphp.log.use-x-forwarded-for = On
5223+;
5224+
5225+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5226+; Hardening-Patch's Executor options ;
5227+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5228+
5229+; Execution depth limit
5230+;hphp.executor.max_depth = 8000
5231+
5232+; White-/blacklist for function calls during normal execution
5233+;hphp.executor.func.whitelist = ord,chr
5234+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5235+
5236+; White-/blacklist for function calls during eval() execution
5237+;hphp.executor.eval.whitelist = ord,chr
5238+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5239+
5240+; White-/blacklist for URLs allowes in include filenames
5241+;
5242+; - When both options are not set all URLs are forbidden
5243+;
5244+; - When both options are set whitelist is taken and blacklist ignored
5245+;
5246+; - An entry in the lists is either a URL sheme like: http, https
5247+; or the beginning of an URL like: php://input
5248+;
5249+;hphp.executor.include.whitelist = cookietest
5250+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5251+
5252+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5253+; Hardening-Patch's REQUEST variable filters ;
5254+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5255+
5256+; Limits the number of REQUEST variables
5257+hphp.request.max_vars = 200
5258+
5259+; Limits the length of variable names (without indices)
5260+hphp.request.max_varname_length = 64
5261+
5262+; Limits the length of complete variable names (with indices)
5263+hphp.request.max_totalname_length = 256
5264+
5265+; Limits the length of array indices
5266+hphp.request.max_array_index_length = 64
5267+
5268+; Limits the depth of arrays
5269+hphp.request.max_array_depth = 100
5270+
5271+; Limits the length of variable values
5272+hphp.request.max_value_length = 65000
5273+
5274+; Disallow ASCII-NUL characters in input
5275+hphp.request.disallow_nul = 1
5276+
5277+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5278+; Hardening-Patch's COOKIE variable filters ;
5279+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5280+
5281+; Limits the number of COOKIE variables
5282+hphp.cookie.max_vars = 100
5283+
5284+; Limits the length of variable names (without indices)
5285+hphp.cookie.max_name_length = 64
5286+
5287+; Limits the length of complete variable names (with indices)
5288+hphp.cookie.max_totalname_length = 256
5289+
5290+; Limits the length of array indices
5291+hphp.cookie.max_array_index_length = 64
5292+
5293+; Limits the depth of arrays
5294+hphp.cookie.max_array_depth = 100
5295+
5296+; Limits the length of variable values
5297+hphp.cookie.max_value_length = 10000
5298+
5299+; Disallow ASCII-NUL characters in input
5300+hphp.cookie.disallow_nul = 1
5301+
5302+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5303+; Hardening-Patch's GET variable filters ;
5304+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5305+
5306+; Limits the number of COOKIE variables
5307+hphp.get.max_vars = 100
5308+
5309+; Limits the length of variable names (without indices)
5310+hphp.get.max_name_length = 64
5311+
5312+; Limits the length of complete variable names (with indices)
5313+hphp.get.max_totalname_length = 256
5314+
5315+; Limits the length of array indices
5316+hphp.get.max_array_index_length = 64
5317+
5318+; Limits the depth of arrays
5319+hphp.get.max_array_depth = 50
5320+
5321+; Limits the length of variable values
5322+hphp.get.max_value_length = 512
5323+
5324+; Disallow ASCII-NUL characters in input
5325+hphp.get.disallow_nul = 1
5326+
5327+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5328+; Hardening-Patch's POST variable filters ;
5329+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5330+
5331+; Limits the number of POST variables
5332+hphp.post.max_vars = 200
5333+
5334+; Limits the length of variable names (without indices)
5335+hphp.post.max_name_length = 64
5336+
5337+; Limits the length of complete variable names (with indices)
5338+hphp.post.max_totalname_length = 256
5339+
5340+; Limits the length of array indices
5341+hphp.post.max_array_index_length = 64
5342+
5343+; Limits the depth of arrays
5344+hphp.post.max_array_depth = 100
5345+
5346+; Limits the length of variable values
5347+hphp.post.max_value_length = 65000
5348+
5349+; Disallow ASCII-NUL characters in input
5350+hphp.post.disallow_nul = 1
5351+
5352+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5353+; Hardening-Patch's fileupload variable filters ;
5354+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5355+
5356+; Limits the number of uploadable files
5357+hphp.upload.max_uploads = 25
5358+
5359+; Filter out the upload of ELF executables
5360+hphp.upload.disallow_elf_files = On
5361+
5362+; External filterscript for upload verification
5363+;hphp.upload.verification_script = /home/hphp/verify_script
5364+
5365+
5366 ; Local Variables:
5367 ; tab-width: 4
5368 ; End:
5369diff -Nura php-4.4.1/php.ini-recommended hardening-patch-4.4.1-0.4.6/php.ini-recommended
5370--- php-4.4.1/php.ini-recommended 2005-04-28 15:14:46.000000000 +0200
5371+++ hardening-patch-4.4.1-0.4.6/php.ini-recommended 2005-11-15 21:45:02.000000000 +0100
5372@@ -1110,6 +1110,209 @@
5373 ;exif.decode_jis_motorola = JIS
5374 ;exif.decode_jis_intel = JIS
5375
5376+[hardening-patch]
5377+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5378+; Hardening-Patch's logging ;
5379+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5380+
5381+;
5382+; hphp.log.syslog - Configures level for alerts reported through syslog
5383+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5384+; hphp.log.script - Configures level for alerts reported through external script
5385+;
5386+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5387+; Or each number up to get desired Hardening-Patch's reporting level
5388+;
5389+; S_ALL - All alerts
5390+; S_MEMORY - All canary violations and the safe unlink protection use this class
5391+; S_VARS - All variable filters trigger this class
5392+; S_FILES - All violation of uploaded files filter use this class
5393+; S_INCLUDE - The protection against malicious include filenames use this class
5394+; S_SQL - Failed SQL queries in MySQL are logged with this class
5395+; S_EXECUTOR - The execution depth protection uses this logging class
5396+; S_MISC - All other log messages (f.e. format string protection) use this class
5397+;
5398+; Example:
5399+;
5400+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5401+; memory alerts through syslog and SQL+Include alerts fo the script
5402+;
5403+;hphp.log.syslog = S_MEMORY
5404+;hphp.log.sapi = S_ALL & ~S_MEMORY
5405+;hphp.log.script = S_INCLUDE | S_SQL
5406+;
5407+; Syslog logging:
5408+;
5409+; - Facility configuration: one of the following facilities
5410+;
5411+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5412+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5413+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5414+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5415+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5416+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5417+; LOG_PERROR
5418+;
5419+; - Priority configuration: one of the followinf priorities
5420+;
5421+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5422+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5423+;
5424+hphp.log.syslog.priority = LOG_ALERT
5425+hphp.log.syslog.facility = LOG_USER
5426+;
5427+; Script logging:
5428+;
5429+;hphp.log.script.name = /home/hphp/log_script
5430+;
5431+; Alert configuration:
5432+;
5433+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5434+;
5435+;hphp.log.use-x-forwarded-for = On
5436+;
5437+
5438+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5439+; Hardening-Patch's Executor options ;
5440+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5441+
5442+; Execution depth limit
5443+;hphp.executor.max_depth = 8000
5444+
5445+; White-/blacklist for function calls during normal execution
5446+;hphp.executor.func.whitelist = ord,chr
5447+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5448+
5449+; White-/blacklist for function calls during eval() execution
5450+;hphp.executor.eval.whitelist = ord,chr
5451+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5452+
5453+; White-/blacklist for URLs allowes in include filenames
5454+;
5455+; - When both options are not set all URLs are forbidden
5456+;
5457+; - When both options are set whitelist is taken and blacklist ignored
5458+;
5459+; - An entry in the lists is either a URL sheme like: http, https
5460+; or the beginning of an URL like: php://input
5461+;
5462+;hphp.executor.include.whitelist = cookietest
5463+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5464+
5465+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5466+; Hardening-Patch's REQUEST variable filters ;
5467+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5468+
5469+; Limits the number of REQUEST variables
5470+hphp.request.max_vars = 200
5471+
5472+; Limits the length of variable names (without indices)
5473+hphp.request.max_varname_length = 64
5474+
5475+; Limits the length of complete variable names (with indices)
5476+hphp.request.max_totalname_length = 256
5477+
5478+; Limits the length of array indices
5479+hphp.request.max_array_index_length = 64
5480+
5481+; Limits the depth of arrays
5482+hphp.request.max_array_depth = 100
5483+
5484+; Limits the length of variable values
5485+hphp.request.max_value_length = 65000
5486+
5487+; Disallow ASCII-NUL characters in input
5488+hphp.request.disallow_nul = 1
5489+
5490+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5491+; Hardening-Patch's COOKIE variable filters ;
5492+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5493+
5494+; Limits the number of COOKIE variables
5495+hphp.cookie.max_vars = 100
5496+
5497+; Limits the length of variable names (without indices)
5498+hphp.cookie.max_name_length = 64
5499+
5500+; Limits the length of complete variable names (with indices)
5501+hphp.cookie.max_totalname_length = 256
5502+
5503+; Limits the length of array indices
5504+hphp.cookie.max_array_index_length = 64
5505+
5506+; Limits the depth of arrays
5507+hphp.cookie.max_array_depth = 100
5508+
5509+; Limits the length of variable values
5510+hphp.cookie.max_value_length = 10000
5511+
5512+; Disallow ASCII-NUL characters in input
5513+hphp.cookie.disallow_nul = 1
5514+
5515+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5516+; Hardening-Patch's GET variable filters ;
5517+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5518+
5519+; Limits the number of COOKIE variables
5520+hphp.get.max_vars = 100
5521+
5522+; Limits the length of variable names (without indices)
5523+hphp.get.max_name_length = 64
5524+
5525+; Limits the length of complete variable names (with indices)
5526+hphp.get.max_totalname_length = 256
5527+
5528+; Limits the length of array indices
5529+hphp.get.max_array_index_length = 64
5530+
5531+; Limits the depth of arrays
5532+hphp.get.max_array_depth = 50
5533+
5534+; Limits the length of variable values
5535+hphp.get.max_value_length = 512
5536+
5537+; Disallow ASCII-NUL characters in input
5538+hphp.get.disallow_nul = 1
5539+
5540+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5541+; Hardening-Patch's POST variable filters ;
5542+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5543+
5544+; Limits the number of POST variables
5545+hphp.post.max_vars = 200
5546+
5547+; Limits the length of variable names (without indices)
5548+hphp.post.max_name_length = 64
5549+
5550+; Limits the length of complete variable names (with indices)
5551+hphp.post.max_totalname_length = 256
5552+
5553+; Limits the length of array indices
5554+hphp.post.max_array_index_length = 64
5555+
5556+; Limits the depth of arrays
5557+hphp.post.max_array_depth = 100
5558+
5559+; Limits the length of variable values
5560+hphp.post.max_value_length = 65000
5561+
5562+; Disallow ASCII-NUL characters in input
5563+hphp.post.disallow_nul = 1
5564+
5565+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5566+; Hardening-Patch's fileupload variable filters ;
5567+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5568+
5569+; Limits the number of uploadable files
5570+hphp.upload.max_uploads = 25
5571+
5572+; Filter out the upload of ELF executables
5573+hphp.upload.disallow_elf_files = On
5574+
5575+; External filterscript for upload verification
5576+;hphp.upload.verification_script = /home/hphp/verify_script
5577+
5578+
5579 ; Local Variables:
5580 ; tab-width: 4
5581 ; End:
5582diff -Nura php-4.4.1/README.input_filter hardening-patch-4.4.1-0.4.6/README.input_filter
5583--- php-4.4.1/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5584+++ hardening-patch-4.4.1-0.4.6/README.input_filter 2005-11-05 13:04:08.000000000 +0100
5585@@ -0,0 +1,193 @@
5586+Input Filter Support ported from PHP 5
5587+--------------------------------------
5588+
5589+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5590+and can be quite difficult to prevent. Whenever you accept user data
5591+and somehow display this data back to users, you are likely vulnerable
5592+to XSS hacks.
5593+
5594+The Input Filter support in PHP 5 is aimed at providing the framework
5595+through which a company-wide or site-wide security policy can be
5596+enforced. It is implemented as a SAPI hook and is called from the
5597+treat_data and post handler functions. To implement your own security
5598+policy you will need to write a standard PHP extension.
5599+
5600+A simple implementation might look like the following. This stores the
5601+original raw user data and adds a my_get_raw() function while the normal
5602+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5603+data. In this simple example all I am doing is calling strip_tags() on
5604+the data. If register_globals is turned on, the default globals that
5605+are created will be stripped ($foo) while a $RAW_foo is created with the
5606+original user input.
5607+
5608+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5609+ zval *post_array;
5610+ zval *get_array;
5611+ zval *cookie_array;
5612+ZEND_END_MODULE_GLOBALS(my_input_filter)
5613+
5614+#ifdef ZTS
5615+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5616+#else
5617+#define IF_G(v) (my_input_filter_globals.v)
5618+#endif
5619+
5620+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5621+
5622+function_entry my_input_filter_functions[] = {
5623+ PHP_FE(my_get_raw, NULL)
5624+ {NULL, NULL, NULL}
5625+};
5626+
5627+zend_module_entry my_input_filter_module_entry = {
5628+ STANDARD_MODULE_HEADER,
5629+ "my_input_filter",
5630+ my_input_filter_functions,
5631+ PHP_MINIT(my_input_filter),
5632+ PHP_MSHUTDOWN(my_input_filter),
5633+ NULL,
5634+ PHP_RSHUTDOWN(my_input_filter),
5635+ PHP_MINFO(my_input_filter),
5636+ "0.1",
5637+ STANDARD_MODULE_PROPERTIES
5638+};
5639+
5640+PHP_MINIT_FUNCTION(my_input_filter)
5641+{
5642+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5643+
5644+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5645+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5646+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5647+
5648+ sapi_register_input_filter(my_sapi_input_filter);
5649+ return SUCCESS;
5650+}
5651+
5652+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5653+{
5654+ if(IF_G(get_array)) {
5655+ zval_ptr_dtor(&IF_G(get_array));
5656+ IF_G(get_array) = NULL;
5657+ }
5658+ if(IF_G(post_array)) {
5659+ zval_ptr_dtor(&IF_G(post_array));
5660+ IF_G(post_array) = NULL;
5661+ }
5662+ if(IF_G(cookie_array)) {
5663+ zval_ptr_dtor(&IF_G(cookie_array));
5664+ IF_G(cookie_array) = NULL;
5665+ }
5666+ return SUCCESS;
5667+}
5668+
5669+PHP_MINFO_FUNCTION(my_input_filter)
5670+{
5671+ php_info_print_table_start();
5672+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5673+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5674+ php_info_print_table_end();
5675+}
5676+
5677+/* The filter handler. If you return 1 from it, then PHP also registers the
5678+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5679+ * you can use this if your filter already registers the variable under a
5680+ * different name, or if you just don't want the variable registered at all. */
5681+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5682+{
5683+ zval new_var;
5684+ zval *array_ptr = NULL;
5685+ char *raw_var;
5686+ int var_len;
5687+
5688+ assert(*val != NULL);
5689+
5690+ switch(arg) {
5691+ case PARSE_GET:
5692+ if(!IF_G(get_array)) {
5693+ ALLOC_ZVAL(array_ptr);
5694+ array_init(array_ptr);
5695+ INIT_PZVAL(array_ptr);
5696+ }
5697+ IF_G(get_array) = array_ptr;
5698+ break;
5699+ case PARSE_POST:
5700+ if(!IF_G(post_array)) {
5701+ ALLOC_ZVAL(array_ptr);
5702+ array_init(array_ptr);
5703+ INIT_PZVAL(array_ptr);
5704+ }
5705+ IF_G(post_array) = array_ptr;
5706+ break;
5707+ case PARSE_COOKIE:
5708+ if(!IF_G(cookie_array)) {
5709+ ALLOC_ZVAL(array_ptr);
5710+ array_init(array_ptr);
5711+ INIT_PZVAL(array_ptr);
5712+ }
5713+ IF_G(cookie_array) = array_ptr;
5714+ break;
5715+ }
5716+ Z_STRLEN(new_var) = val_len;
5717+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5718+ Z_TYPE(new_var) = IS_STRING;
5719+
5720+ var_len = strlen(var);
5721+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5722+ strcpy(raw_var, "RAW_");
5723+ strlcat(raw_var,var,var_len+5);
5724+
5725+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5726+
5727+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5728+
5729+ *new_val_len = strlen(*val);
5730+ return 1;
5731+}
5732+
5733+PHP_FUNCTION(my_get_raw)
5734+{
5735+ long arg;
5736+ char *var;
5737+ int var_len;
5738+ zval **tmp;
5739+ zval *array_ptr = NULL;
5740+ HashTable *hash_ptr;
5741+ char *raw_var;
5742+
5743+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
5744+ return;
5745+ }
5746+
5747+ switch(arg) {
5748+ case PARSE_GET:
5749+ array_ptr = IF_G(get_array);
5750+ break;
5751+ case PARSE_POST:
5752+ array_ptr = IF_G(post_array);
5753+ break;
5754+ case PARSE_COOKIE:
5755+ array_ptr = IF_G(post_array);
5756+ break;
5757+ }
5758+
5759+ if(!array_ptr) RETURN_FALSE;
5760+
5761+ /*
5762+ * I'm changing the variable name here because when running with register_globals on,
5763+ * the variable will end up in the global symbol table
5764+ */
5765+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5766+ strcpy(raw_var, "RAW_");
5767+ strlcat(raw_var,var,var_len+5);
5768+ hash_ptr = HASH_OF(array_ptr);
5769+
5770+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
5771+ *return_value = **tmp;
5772+ zval_copy_ctor(return_value);
5773+ } else {
5774+ RETVAL_FALSE;
5775+ }
5776+ efree(raw_var);
5777+}
5778+
5779diff -Nura php-4.4.1/run-tests.php hardening-patch-4.4.1-0.4.6/run-tests.php
5780--- php-4.4.1/run-tests.php 2005-06-19 00:54:07.000000000 +0200
5781+++ hardening-patch-4.4.1-0.4.6/run-tests.php 2005-11-15 21:42:20.000000000 +0100
5782@@ -152,6 +152,10 @@
5783 'error_reporting=2047',
5784 'display_errors=1',
5785 'log_errors=0',
5786+ 'hphp.executor.include.whitelist=cookietest',
5787+ 'hphp.log.syslog=0',
5788+ 'hphp.log.sapi=0',
5789+ 'hphp.log.script=0',
5790 'html_errors=0',
5791 'track_errors=1',
5792 'report_memleaks=1',
5793diff -Nura php-4.4.1/sapi/apache/mod_php4.c hardening-patch-4.4.1-0.4.6/sapi/apache/mod_php4.c
5794--- php-4.4.1/sapi/apache/mod_php4.c 2005-05-19 18:14:46.000000000 +0200
5795+++ hardening-patch-4.4.1-0.4.6/sapi/apache/mod_php4.c 2005-11-05 13:04:08.000000000 +0100
5796@@ -452,7 +452,7 @@
5797 sapi_apache_get_fd,
5798 sapi_apache_force_http_10,
5799 sapi_apache_get_target_uid,
5800- sapi_apache_get_target_gid
5801+ sapi_apache_get_target_gid,
5802 };
5803 /* }}} */
5804
5805@@ -898,7 +898,11 @@
5806 {
5807 TSRMLS_FETCH();
5808 if (PG(expose_php)) {
5809+#if HARDENING_PATCH
5810+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5811+#else
5812 ap_add_version_component("PHP/" PHP_VERSION);
5813+#endif
5814 }
5815 }
5816 #endif
5817diff -Nura php-4.4.1/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.1-0.4.6/sapi/apache2filter/sapi_apache2.c
5818--- php-4.4.1/sapi/apache2filter/sapi_apache2.c 2005-08-03 16:49:50.000000000 +0200
5819+++ hardening-patch-4.4.1-0.4.6/sapi/apache2filter/sapi_apache2.c 2005-11-05 13:04:08.000000000 +0100
5820@@ -562,7 +562,11 @@
5821 {
5822 TSRMLS_FETCH();
5823 if (PG(expose_php)) {
5824+#if HARDENING_PATCH
5825+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5826+#else
5827 ap_add_version_component(p, "PHP/" PHP_VERSION);
5828+#endif
5829 }
5830 }
5831
5832diff -Nura php-4.4.1/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.1-0.4.6/sapi/apache2handler/sapi_apache2.c
5833--- php-4.4.1/sapi/apache2handler/sapi_apache2.c 2005-10-12 23:41:36.000000000 +0200
5834+++ hardening-patch-4.4.1-0.4.6/sapi/apache2handler/sapi_apache2.c 2005-11-05 13:04:08.000000000 +0100
5835@@ -340,7 +340,11 @@
5836 {
5837 TSRMLS_FETCH();
5838 if (PG(expose_php)) {
5839+#if HARDENING_PATCH
5840+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5841+#else
5842 ap_add_version_component(p, "PHP/" PHP_VERSION);
5843+#endif
5844 }
5845 }
5846
5847diff -Nura php-4.4.1/sapi/cgi/cgi_main.c hardening-patch-4.4.1-0.4.6/sapi/cgi/cgi_main.c
5848--- php-4.4.1/sapi/cgi/cgi_main.c 2005-10-06 22:39:26.000000000 +0200
5849+++ hardening-patch-4.4.1-0.4.6/sapi/cgi/cgi_main.c 2005-11-05 13:04:08.000000000 +0100
5850@@ -1440,11 +1440,19 @@
5851 SG(headers_sent) = 1;
5852 SG(request_info).no_headers = 1;
5853 }
5854+#if HARDENING_PATCH
5855+#if ZEND_DEBUG
5856+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5857+#else
5858+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5859+#endif
5860+#else
5861 #if ZEND_DEBUG
5862 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());
5863 #else
5864 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());
5865 #endif
5866+#endif
5867 php_end_ob_buffers(1 TSRMLS_CC);
5868 exit(0);
5869 break;
5870diff -Nura php-4.4.1/sapi/cli/php_cli.c hardening-patch-4.4.1-0.4.6/sapi/cli/php_cli.c
5871--- php-4.4.1/sapi/cli/php_cli.c 2005-10-11 20:59:23.000000000 +0200
5872+++ hardening-patch-4.4.1-0.4.6/sapi/cli/php_cli.c 2005-11-05 13:04:08.000000000 +0100
5873@@ -654,11 +654,19 @@
5874 if (php_request_startup(TSRMLS_C)==FAILURE) {
5875 goto err;
5876 }
5877+#if HARDENING_PATCH
5878+#if ZEND_DEBUG
5879+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5880+#else
5881+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
5882+#endif
5883+#else
5884 #if ZEND_DEBUG
5885 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());
5886 #else
5887 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());
5888 #endif
5889+#endif
5890 php_end_ob_buffers(1 TSRMLS_CC);
5891 exit_status=0;
5892 goto out;
5893diff -Nura php-4.4.1/TSRM/TSRM.h hardening-patch-4.4.1-0.4.6/TSRM/TSRM.h
5894--- php-4.4.1/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
5895+++ hardening-patch-4.4.1-0.4.6/TSRM/TSRM.h 2005-11-05 13:04:08.000000000 +0100
5896@@ -33,6 +33,13 @@
5897 # define TSRM_API
5898 #endif
5899
5900+#if HARDENING_PATCH
5901+# if HAVE_REALPATH
5902+# undef realpath
5903+# define realpath php_realpath
5904+# endif
5905+#endif
5906+
5907 /* Only compile multi-threading functions if we're in ZTS mode */
5908 #ifdef ZTS
5909
5910@@ -84,6 +91,7 @@
5911
5912 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5913
5914+
5915 #ifdef __cplusplus
5916 extern "C" {
5917 #endif
5918diff -Nura php-4.4.1/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.1-0.4.6/TSRM/tsrm_virtual_cwd.c
5919--- php-4.4.1/TSRM/tsrm_virtual_cwd.c 2005-08-03 16:51:24.000000000 +0200
5920+++ hardening-patch-4.4.1-0.4.6/TSRM/tsrm_virtual_cwd.c 2005-11-05 13:07:14.000000000 +0100
5921@@ -179,6 +179,165 @@
5922 return p;
5923 }
5924
5925+#if HARDENING_PATCH
5926+CWD_API char *php_realpath(const char *path, char *resolved)
5927+{
5928+ struct stat sb;
5929+ char *p, *q, *s;
5930+ size_t left_len, resolved_len;
5931+ unsigned symlinks;
5932+ int serrno, slen;
5933+ int is_dir = 1;
5934+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5935+
5936+ serrno = errno;
5937+ symlinks = 0;
5938+ if (path[0] == '/') {
5939+ resolved[0] = '/';
5940+ resolved[1] = '\0';
5941+ if (path[1] == '\0')
5942+ return (resolved);
5943+ resolved_len = 1;
5944+ left_len = strlcpy(left, path + 1, sizeof(left));
5945+ } else {
5946+ if (getcwd(resolved, PATH_MAX) == NULL) {
5947+ strlcpy(resolved, ".", PATH_MAX);
5948+ return (NULL);
5949+ }
5950+ resolved_len = strlen(resolved);
5951+ left_len = strlcpy(left, path, sizeof(left));
5952+ }
5953+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5954+ errno = ENAMETOOLONG;
5955+ return (NULL);
5956+ }
5957+
5958+ /*
5959+ * Iterate over path components in `left'.
5960+ */
5961+ while (left_len != 0) {
5962+ /*
5963+ * Extract the next path component and adjust `left'
5964+ * and its length.
5965+ */
5966+ p = strchr(left, '/');
5967+ s = p ? p : left + left_len;
5968+ if (s - left >= sizeof(next_token)) {
5969+ errno = ENAMETOOLONG;
5970+ return (NULL);
5971+ }
5972+ memcpy(next_token, left, s - left);
5973+ next_token[s - left] = '\0';
5974+ left_len -= s - left;
5975+ if (p != NULL)
5976+ memmove(left, s + 1, left_len + 1);
5977+ if (resolved[resolved_len - 1] != '/') {
5978+ if (resolved_len + 1 >= PATH_MAX) {
5979+ errno = ENAMETOOLONG;
5980+ return (NULL);
5981+ }
5982+ resolved[resolved_len++] = '/';
5983+ resolved[resolved_len] = '\0';
5984+ }
5985+ if (next_token[0] == '\0')
5986+ continue;
5987+ else if (strcmp(next_token, ".") == 0)
5988+ continue;
5989+ else if (strcmp(next_token, "..") == 0) {
5990+ /*
5991+ * Strip the last path component except when we have
5992+ * single "/"
5993+ */
5994+ if (!is_dir) {
5995+ errno = ENOENT;
5996+ return (NULL);
5997+ }
5998+ if (resolved_len > 1) {
5999+ resolved[resolved_len - 1] = '\0';
6000+ q = strrchr(resolved, '/');
6001+ *q = '\0';
6002+ resolved_len = q - resolved;
6003+ }
6004+ continue;
6005+ }
6006+
6007+ /*
6008+ * Append the next path component and lstat() it. If
6009+ * lstat() fails we still can return successfully if
6010+ * there are no more path components left.
6011+ */
6012+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6013+ if (resolved_len >= PATH_MAX) {
6014+ errno = ENAMETOOLONG;
6015+ return (NULL);
6016+ }
6017+ if (lstat(resolved, &sb) != 0) {
6018+ if (errno == ENOENT && p == NULL) {
6019+ errno = serrno;
6020+ return (resolved);
6021+ }
6022+ return (NULL);
6023+ }
6024+ if (S_ISLNK(sb.st_mode)) {
6025+ if (symlinks++ > MAXSYMLINKS) {
6026+ errno = ELOOP;
6027+ return (NULL);
6028+ }
6029+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6030+ if (slen < 0)
6031+ return (NULL);
6032+ symlink[slen] = '\0';
6033+ if (symlink[0] == '/') {
6034+ resolved[1] = 0;
6035+ resolved_len = 1;
6036+ } else if (resolved_len > 1) {
6037+ /* Strip the last path component. */
6038+ resolved[resolved_len - 1] = '\0';
6039+ q = strrchr(resolved, '/');
6040+ *q = '\0';
6041+ resolved_len = q - resolved;
6042+ }
6043+
6044+ /*
6045+ * If there are any path components left, then
6046+ * append them to symlink. The result is placed
6047+ * in `left'.
6048+ */
6049+ if (p != NULL) {
6050+ if (symlink[slen - 1] != '/') {
6051+ if (slen + 1 >= sizeof(symlink)) {
6052+ errno = ENAMETOOLONG;
6053+ return (NULL);
6054+ }
6055+ symlink[slen] = '/';
6056+ symlink[slen + 1] = 0;
6057+ }
6058+ left_len = strlcat(symlink, left, sizeof(left));
6059+ if (left_len >= sizeof(left)) {
6060+ errno = ENAMETOOLONG;
6061+ return (NULL);
6062+ }
6063+ }
6064+ left_len = strlcpy(left, symlink, sizeof(left));
6065+ } else {
6066+ if (S_ISDIR(sb.st_mode)) {
6067+ is_dir = 1;
6068+ } else {
6069+ is_dir = 0;
6070+ }
6071+ }
6072+ }
6073+
6074+ /*
6075+ * Remove trailing slash except when the resolved pathname
6076+ * is a single "/".
6077+ */
6078+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6079+ resolved[resolved_len - 1] = '\0';
6080+ return (resolved);
6081+}
6082+#endif
6083+
6084 CWD_API void virtual_cwd_startup(void)
6085 {
6086 char cwd[MAXPATHLEN];
6087@@ -300,8 +459,11 @@
6088
6089 if (path_length == 0)
6090 return (0);
6091- if (path_length >= MAXPATHLEN)
6092+ if (path_length >= MAXPATHLEN) {
6093+ state->cwd[0] = 0;
6094+ state->cwd_length = 0;
6095 return (1);
6096+ }
6097
6098 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6099 /* cwd_length can be 0 when getcwd() fails.
6100@@ -313,8 +475,9 @@
6101 path = resolved_path;
6102 path_length = strlen(path);
6103 } else {
6104- /* disable for now
6105- return 1; */
6106+ state->cwd[0] = 0;
6107+ state->cwd_length = 0;
6108+ return 1;
6109 }
6110 }
6111 } else { /* Concat current directory with relative path and then run realpath() on it */
6112@@ -323,6 +486,8 @@
6113
6114 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6115 if (!tmp) {
6116+ state->cwd[0] = 0;
6117+ state->cwd_length = 0;
6118 return 1;
6119 }
6120 memcpy(ptr, state->cwd, state->cwd_length);
6121@@ -332,6 +497,8 @@
6122 ptr += path_length;
6123 *ptr = '\0';
6124 if (strlen(tmp) >= MAXPATHLEN) {
6125+ state->cwd[0] = 0;
6126+ state->cwd_length = 0;
6127 free(tmp);
6128 return 1;
6129 }
6130@@ -340,9 +507,10 @@
6131 path = resolved_path;
6132 path_length = strlen(path);
6133 } else {
6134- /* disable for now
6135+ state->cwd[0] = 0;
6136+ state->cwd_length = 0;
6137 free(tmp);
6138- return 1; */
6139+ return 1;
6140 }
6141 }
6142 free(tmp);
6143diff -Nura php-4.4.1/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.1-0.4.6/TSRM/tsrm_virtual_cwd.h
6144--- php-4.4.1/TSRM/tsrm_virtual_cwd.h 2005-08-03 16:51:24.000000000 +0200
6145+++ hardening-patch-4.4.1-0.4.6/TSRM/tsrm_virtual_cwd.h 2005-11-05 13:04:08.000000000 +0100
6146@@ -128,6 +128,22 @@
6147
6148 typedef int (*verify_path_func)(const cwd_state *);
6149
6150+#ifndef HAVE_STRLCPY
6151+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6152+#undef strlcpy
6153+#define strlcpy php_strlcpy
6154+#endif
6155+
6156+#ifndef HAVE_STRLCAT
6157+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6158+#undef strlcat
6159+#define strlcat php_strlcat
6160+#endif
6161+
6162+
6163+#if HARDENING_PATCH
6164+CWD_API char *php_realpath(const char *path, char *resolved);
6165+#endif
6166 CWD_API void virtual_cwd_startup(void);
6167 CWD_API void virtual_cwd_shutdown(void);
6168 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6169diff -Nura php-4.4.1/Zend/zend_alloc.c hardening-patch-4.4.1-0.4.6/Zend/zend_alloc.c
6170--- php-4.4.1/Zend/zend_alloc.c 2005-08-18 17:14:48.000000000 +0200
6171+++ hardening-patch-4.4.1-0.4.6/Zend/zend_alloc.c 2005-11-05 13:04:08.000000000 +0100
6172@@ -56,6 +56,11 @@
6173 # define END_MAGIC_SIZE 0
6174 #endif
6175
6176+#if HARDENING_PATCH_MM_PROTECT
6177+# define CANARY_SIZE sizeof(unsigned int)
6178+#else
6179+# define CANARY_SIZE 0
6180+#endif
6181
6182 # if MEMORY_LIMIT
6183 # if ZEND_DEBUG
6184@@ -96,9 +101,17 @@
6185 if (p==AG(head)) { \
6186 AG(head) = p->pNext; \
6187 } else { \
6188+ if (p != p->pLast->pNext) { \
6189+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6190+ exit(1); \
6191+ } \
6192 p->pLast->pNext = p->pNext; \
6193 } \
6194 if (p->pNext) { \
6195+ if (p != p->pNext->pLast) { \
6196+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6197+ exit(1); \
6198+ } \
6199 p->pNext->pLast = p->pLast; \
6200 }
6201
6202@@ -130,6 +143,12 @@
6203 DECLARE_CACHE_VARS();
6204 TSRMLS_FETCH();
6205
6206+#if HARDENING_PATCH_MM_PROTECT
6207+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6208+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6209+ exit(1);
6210+ }
6211+#endif
6212 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6213
6214 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6215@@ -147,6 +166,10 @@
6216 AG(cache_stats)[CACHE_INDEX][1]++;
6217 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6218 #endif
6219+#if HARDENING_PATCH_MM_PROTECT
6220+ p->canary = HG(canary_1);
6221+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6222+#endif
6223 p->cached = 0;
6224 p->size = size;
6225 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6226@@ -162,7 +185,7 @@
6227 AG(allocated_memory_peak) = AG(allocated_memory);
6228 }
6229 #endif
6230- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6231+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6232 }
6233
6234 HANDLE_BLOCK_INTERRUPTIONS();
6235@@ -192,7 +215,10 @@
6236 # endif
6237 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6238 #endif
6239-
6240+#if HARDENING_PATCH_MM_PROTECT
6241+ p->canary = HG(canary_1);
6242+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6243+#endif
6244 HANDLE_UNBLOCK_INTERRUPTIONS();
6245 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6246 }
6247@@ -219,17 +245,36 @@
6248 return emalloc_rel(lval + offset);
6249 }
6250 }
6251-
6252+
6253+#if HARDENING_PATCH
6254+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6255+#endif
6256 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6257 return 0;
6258 }
6259
6260 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6261 {
6262+#if HARDENING_PATCH_MM_PROTECT
6263+ unsigned int canary_2;
6264+#endif
6265 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6266 DECLARE_CACHE_VARS();
6267 TSRMLS_FETCH();
6268
6269+#if HARDENING_PATCH_MM_PROTECT
6270+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6271+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6272+ if (canary_2 != HG(canary_2)) {
6273+efree_canary_mismatch:
6274+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6275+ exit(1);
6276+ }
6277+ /* to catch double efree()s */
6278+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6279+ p->canary = 0;
6280+#endif
6281+
6282 #if defined(ZTS) && TSRM_DEBUG
6283 if (p->thread_id != tsrm_thread_id()) {
6284 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6285@@ -274,6 +319,9 @@
6286 size_t _size = nmemb * size;
6287
6288 if (nmemb && (_size/nmemb!=size)) {
6289+#if HARDENING_PATCH
6290+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6291+#endif
6292 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6293 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6294 kill(getpid(), SIGSEGV);
6295@@ -293,6 +341,9 @@
6296
6297 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6298 {
6299+#if HARDENING_PATCH_MM_PROTECT
6300+ unsigned int canary_2;
6301+#endif
6302 zend_mem_header *p;
6303 zend_mem_header *orig;
6304 DECLARE_CACHE_VARS();
6305@@ -304,6 +355,16 @@
6306
6307 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6308
6309+#if HARDENING_PATCH_MM_PROTECT
6310+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6311+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6312+ if (canary_2 != HG(canary_2)) {
6313+erealloc_canary_mismatch:
6314+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6315+ exit(1);
6316+ }
6317+#endif
6318+
6319 #if defined(ZTS) && TSRM_DEBUG
6320 if (p->thread_id != tsrm_thread_id()) {
6321 void *new_p;
6322@@ -327,7 +388,7 @@
6323 }
6324 #endif
6325 REMOVE_POINTER_FROM_LIST(p);
6326- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6327+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6328 if (!p) {
6329 if (!allow_failure) {
6330 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6331@@ -349,6 +410,9 @@
6332 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6333 #endif
6334
6335+#if HARDENING_PATCH_MM_PROTECT
6336+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6337+#endif
6338 p->size = size;
6339
6340 HANDLE_UNBLOCK_INTERRUPTIONS();
6341@@ -423,6 +487,10 @@
6342 {
6343 AG(head) = NULL;
6344
6345+#if HARDENING_PATCH_MM_PROTECT
6346+ HG(canary_1) = zend_canary();
6347+ HG(canary_2) = zend_canary();
6348+#endif
6349 #if MEMORY_LIMIT
6350 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6351 AG(allocated_memory) = 0;
6352diff -Nura php-4.4.1/Zend/zend_alloc.h hardening-patch-4.4.1-0.4.6/Zend/zend_alloc.h
6353--- php-4.4.1/Zend/zend_alloc.h 2005-06-07 15:37:33.000000000 +0200
6354+++ hardening-patch-4.4.1-0.4.6/Zend/zend_alloc.h 2005-11-05 13:04:08.000000000 +0100
6355@@ -32,6 +32,9 @@
6356 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6357
6358 typedef struct _zend_mem_header {
6359+#if HARDENING_PATCH_MM_PROTECT
6360+ unsigned int canary;
6361+#endif
6362 #if ZEND_DEBUG
6363 long magic;
6364 char *filename;
6365diff -Nura php-4.4.1/Zend/zend_builtin_functions.c hardening-patch-4.4.1-0.4.6/Zend/zend_builtin_functions.c
6366--- php-4.4.1/Zend/zend_builtin_functions.c 2005-06-23 14:20:47.000000000 +0200
6367+++ hardening-patch-4.4.1-0.4.6/Zend/zend_builtin_functions.c 2005-11-05 13:04:08.000000000 +0100
6368@@ -49,6 +49,9 @@
6369 static ZEND_FUNCTION(crash);
6370 #endif
6371 #endif
6372+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6373+static ZEND_FUNCTION(heap_overflow);
6374+#endif
6375 static ZEND_FUNCTION(get_included_files);
6376 static ZEND_FUNCTION(is_subclass_of);
6377 static ZEND_FUNCTION(is_a);
6378@@ -101,6 +104,9 @@
6379 ZEND_FE(crash, NULL)
6380 #endif
6381 #endif
6382+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6383+ ZEND_FE(heap_overflow, NULL)
6384+#endif
6385 ZEND_FE(get_included_files, NULL)
6386 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6387 ZEND_FE(is_subclass_of, NULL)
6388@@ -805,6 +811,19 @@
6389
6390 #endif /* ZEND_DEBUG */
6391
6392+
6393+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6394+ZEND_FUNCTION(heap_overflow)
6395+{
6396+ char *nowhere = emalloc(10);
6397+
6398+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6399+
6400+ efree(nowhere);
6401+}
6402+#endif
6403+
6404+
6405 /* {{{ proto array get_included_files(void)
6406 Returns an array with the file names that were include_once()'d */
6407 ZEND_FUNCTION(get_included_files)
6408diff -Nura php-4.4.1/Zend/zend.c hardening-patch-4.4.1-0.4.6/Zend/zend.c
6409--- php-4.4.1/Zend/zend.c 2005-06-09 12:14:25.000000000 +0200
6410+++ hardening-patch-4.4.1-0.4.6/Zend/zend.c 2005-11-26 00:10:28.000000000 +0100
6411@@ -53,6 +53,12 @@
6412 ZEND_API void (*zend_unblock_interruptions)(void);
6413 ZEND_API void (*zend_ticks_function)(int ticks);
6414 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6415+#if HARDENING_PATCH
6416+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6417+#endif
6418+#if HARDENING_PATCH_INC_PROTECT
6419+ZEND_API int (*zend_is_valid_include)(zval *z);
6420+#endif
6421
6422 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6423
6424@@ -70,9 +76,390 @@
6425 return SUCCESS;
6426 }
6427
6428+#if HARDENING_PATCH
6429+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6430+{
6431+ if (!new_value) {
6432+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6433+ } else {
6434+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6435+ }
6436+ return SUCCESS;
6437+}
6438+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6439+{
6440+ if (!new_value) {
6441+ EG(hphp_log_syslog_facility) = LOG_USER;
6442+ } else {
6443+ EG(hphp_log_syslog_facility) = atoi(new_value);
6444+ }
6445+ return SUCCESS;
6446+}
6447+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6448+{
6449+ if (!new_value) {
6450+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6451+ } else {
6452+ EG(hphp_log_syslog_priority) = atoi(new_value);
6453+ }
6454+ return SUCCESS;
6455+}
6456+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6457+{
6458+ if (!new_value) {
6459+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6460+ } else {
6461+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6462+ }
6463+ return SUCCESS;
6464+}
6465+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6466+{
6467+ if (!new_value) {
6468+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6469+ } else {
6470+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6471+ }
6472+ return SUCCESS;
6473+}
6474+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6475+{
6476+ if (EG(hphp_log_scriptname)) {
6477+ pefree(EG(hphp_log_scriptname),1);
6478+ }
6479+ EG(hphp_log_scriptname) = NULL;
6480+ if (new_value) {
6481+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6482+ }
6483+ return SUCCESS;
6484+}
6485+
6486+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6487+{
6488+ char *s = NULL, *e, *val;
6489+ unsigned long dummy = 1;
6490+
6491+ if (!new_value) {
6492+include_whitelist_destroy:
6493+ if (HG(include_whitelist)) {
6494+ zend_hash_destroy(HG(include_whitelist));
6495+ pefree(HG(include_whitelist),1);
6496+ }
6497+ HG(include_whitelist) = NULL;
6498+ return SUCCESS;
6499+ }
6500+ if (!(*new_value)) {
6501+ goto include_whitelist_destroy;
6502+ }
6503+
6504+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6505+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6506+
6507+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6508+ e = val;
6509+
6510+ while (*e) {
6511+ switch (*e) {
6512+ case ' ':
6513+ case ',':
6514+ if (s) {
6515+ *e = '\0';
6516+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6517+ s = NULL;
6518+ }
6519+ break;
6520+ default:
6521+ if (!s) {
6522+ s = e;
6523+ }
6524+ break;
6525+ }
6526+ e++;
6527+ }
6528+ if (s) {
6529+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6530+ }
6531+ efree(val);
6532+
6533+ return SUCCESS;
6534+}
6535+
6536+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6537+{
6538+ char *s = NULL, *e, *val;
6539+ unsigned long dummy = 1;
6540+
6541+ if (!new_value) {
6542+include_blacklist_destroy:
6543+ if (HG(include_blacklist)) {
6544+ zend_hash_destroy(HG(include_blacklist));
6545+ pefree(HG(include_blacklist),1);
6546+ }
6547+ HG(include_blacklist) = NULL;
6548+ return SUCCESS;
6549+ }
6550+ if (!(*new_value)) {
6551+ goto include_blacklist_destroy;
6552+ }
6553+
6554+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6555+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6556+
6557+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6558+ e = val;
6559+
6560+ while (*e) {
6561+ switch (*e) {
6562+ case ' ':
6563+ case ',':
6564+ if (s) {
6565+ *e = '\0';
6566+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6567+ s = NULL;
6568+ }
6569+ break;
6570+ default:
6571+ if (!s) {
6572+ s = e;
6573+ }
6574+ break;
6575+ }
6576+ e++;
6577+ }
6578+ if (s) {
6579+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6580+ }
6581+ efree(val);
6582+
6583+ return SUCCESS;
6584+}
6585+
6586+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6587+{
6588+ char *s = NULL, *e, *val;
6589+ unsigned long dummy = 1;
6590+
6591+ if (!new_value) {
6592+eval_whitelist_destroy:
6593+ if (HG(eval_whitelist)) {
6594+ zend_hash_destroy(HG(eval_whitelist));
6595+ pefree(HG(eval_whitelist),1);
6596+ }
6597+ HG(eval_whitelist) = NULL;
6598+ return SUCCESS;
6599+ }
6600+ if (!(*new_value)) {
6601+ goto eval_whitelist_destroy;
6602+ }
6603+
6604+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6605+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6606+
6607+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6608+ e = val;
6609+
6610+ while (*e) {
6611+ switch (*e) {
6612+ case ' ':
6613+ case ',':
6614+ if (s) {
6615+ *e = '\0';
6616+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6617+ s = NULL;
6618+ }
6619+ break;
6620+ default:
6621+ if (!s) {
6622+ s = e;
6623+ }
6624+ break;
6625+ }
6626+ e++;
6627+ }
6628+ if (s) {
6629+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6630+ }
6631+ efree(val);
6632+
6633+ return SUCCESS;
6634+}
6635+
6636+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6637+{
6638+ char *s = NULL, *e, *val;
6639+ unsigned long dummy = 1;
6640+
6641+ if (!new_value) {
6642+eval_blacklist_destroy:
6643+ if (HG(eval_blacklist)) {
6644+ zend_hash_destroy(HG(eval_blacklist));
6645+ pefree(HG(eval_blacklist), 1);
6646+ }
6647+ HG(eval_blacklist) = NULL;
6648+ return SUCCESS;
6649+ }
6650+ if (!(*new_value)) {
6651+ goto eval_blacklist_destroy;
6652+ }
6653+
6654+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6655+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6656+
6657+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6658+ e = val;
6659+
6660+ while (*e) {
6661+ switch (*e) {
6662+ case ' ':
6663+ case ',':
6664+ if (s) {
6665+ *e = '\0';
6666+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6667+ s = NULL;
6668+ }
6669+ break;
6670+ default:
6671+ if (!s) {
6672+ s = e;
6673+ }
6674+ break;
6675+ }
6676+ e++;
6677+ }
6678+ if (s) {
6679+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6680+ }
6681+ efree(val);
6682+
6683+
6684+ return SUCCESS;
6685+}
6686+
6687+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6688+{
6689+ char *s = NULL, *e, *val;
6690+ unsigned long dummy = 1;
6691+
6692+ if (!new_value) {
6693+func_whitelist_destroy:
6694+ if (HG(func_whitelist)) {
6695+ zend_hash_destroy(HG(func_whitelist));
6696+ pefree(HG(func_whitelist),1);
6697+ }
6698+ HG(func_whitelist) = NULL;
6699+ return SUCCESS;
6700+ }
6701+ if (!(*new_value)) {
6702+ goto func_whitelist_destroy;
6703+ }
6704+
6705+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6706+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6707+
6708+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6709+ e = val;
6710+
6711+ while (*e) {
6712+ switch (*e) {
6713+ case ' ':
6714+ case ',':
6715+ if (s) {
6716+ *e = '\0';
6717+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6718+ s = NULL;
6719+ }
6720+ break;
6721+ default:
6722+ if (!s) {
6723+ s = e;
6724+ }
6725+ break;
6726+ }
6727+ e++;
6728+ }
6729+ if (s) {
6730+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6731+ }
6732+ efree(val);
6733+
6734+ return SUCCESS;
6735+}
6736+
6737+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6738+{
6739+ char *s = NULL, *e, *val;
6740+ unsigned long dummy = 1;
6741+
6742+ if (!new_value) {
6743+func_blacklist_destroy:
6744+ if (HG(func_blacklist)) {
6745+ zend_hash_destroy(HG(func_blacklist));
6746+ pefree(HG(func_blacklist),1);
6747+ }
6748+ HG(func_blacklist) = NULL;
6749+ return SUCCESS;
6750+ }
6751+ if (!(*new_value)) {
6752+ goto func_blacklist_destroy;
6753+ }
6754+
6755+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6756+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6757+
6758+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6759+ e = val;
6760+
6761+ while (*e) {
6762+ switch (*e) {
6763+ case ' ':
6764+ case ',':
6765+ if (s) {
6766+ *e = '\0';
6767+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6768+ s = NULL;
6769+ }
6770+ break;
6771+ default:
6772+ if (!s) {
6773+ s = e;
6774+ }
6775+ break;
6776+ }
6777+ e++;
6778+ }
6779+ if (s) {
6780+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6781+ }
6782+ efree(val);
6783+
6784+
6785+ return SUCCESS;
6786+}
6787+
6788+#endif
6789
6790 ZEND_INI_BEGIN()
6791 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6792+#if HARDENING_PATCH
6793+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6794+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6795+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6796+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6797+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6798+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6799+ STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for", "0", ZEND_INI_SYSTEM, OnUpdateBool, hphp_log_use_x_forwarded_for, zend_executor_globals, executor_globals)
6800+
6801+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6802+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6803+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6804+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6805+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6806+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6807+
6808+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
6809+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
6810+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6811+#endif
6812 ZEND_INI_END()
6813
6814
6815@@ -354,8 +741,12 @@
6816 zend_init_rsrc_plist(TSRMLS_C);
6817 EG(lambda_count)=0;
6818 EG(user_error_handler) = NULL;
6819+ EG(in_code_type) = 0;
6820 EG(in_execution) = 0;
6821 EG(current_execute_data) = NULL;
6822+#if HARDENING_PATCH
6823+ EG(hphp_log_scriptname) = NULL;
6824+#endif
6825 }
6826
6827
6828@@ -420,6 +811,14 @@
6829 extern zend_scanner_globals language_scanner_globals;
6830 #endif
6831
6832+ /* Set up Hardening-Patch utility functions first */
6833+#if HARDENING_PATCH
6834+ zend_security_log = utility_functions->security_log_function;
6835+#endif
6836+#if HARDENING_PATCH_INC_PROTECT
6837+ zend_is_valid_include = utility_functions->is_valid_include;
6838+#endif
6839+
6840 #ifdef ZTS
6841 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6842 #else
6843@@ -623,6 +1022,7 @@
6844 }
6845 CG(unclean_shutdown) = 1;
6846 CG(in_compilation) = EG(in_execution) = 0;
6847+ EG(in_code_type) = 0;
6848 EG(current_execute_data) = NULL;
6849 longjmp(EG(bailout), FAILURE);
6850 }
6851diff -Nura php-4.4.1/Zend/zend_canary.c hardening-patch-4.4.1-0.4.6/Zend/zend_canary.c
6852--- php-4.4.1/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6853+++ hardening-patch-4.4.1-0.4.6/Zend/zend_canary.c 2005-11-05 13:04:08.000000000 +0100
6854@@ -0,0 +1,58 @@
6855+/*
6856+ +----------------------------------------------------------------------+
6857+ | Hardening-Patch for PHP |
6858+ +----------------------------------------------------------------------+
6859+ | Copyright (c) 2004-2005 Stefan Esser |
6860+ +----------------------------------------------------------------------+
6861+ | This source file is subject to version 2.02 of the PHP license, |
6862+ | that is bundled with this package in the file LICENSE, and is |
6863+ | available at through the world-wide-web at |
6864+ | http://www.php.net/license/2_02.txt. |
6865+ | If you did not receive a copy of the PHP license and are unable to |
6866+ | obtain it through the world-wide-web, please send a note to |
6867+ | license@php.net so we can mail you a copy immediately. |
6868+ +----------------------------------------------------------------------+
6869+ | Author: Stefan Esser <sesser@hardened-php.net> |
6870+ +----------------------------------------------------------------------+
6871+ */
6872+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6873+
6874+#include "zend.h"
6875+
6876+#include <stdio.h>
6877+#include <stdlib.h>
6878+
6879+
6880+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6881+
6882+/* will be replaced later with more compatible method */
6883+ZEND_API unsigned int zend_canary()
6884+{
6885+ time_t t;
6886+ unsigned int canary;
6887+ int fd;
6888+
6889+ fd = open("/dev/urandom", 0);
6890+ if (fd != -1) {
6891+ int r = read(fd, &canary, sizeof(canary));
6892+ close(fd);
6893+ if (r == sizeof(canary)) {
6894+ return (canary);
6895+ }
6896+ }
6897+ /* not good but we never want to do this */
6898+ time(&t);
6899+ canary = *(unsigned int *)&t + getpid() << 16;
6900+ return (canary);
6901+}
6902+#endif
6903+
6904+
6905+/*
6906+ * Local variables:
6907+ * tab-width: 4
6908+ * c-basic-offset: 4
6909+ * End:
6910+ * vim600: sw=4 ts=4 fdm=marker
6911+ * vim<600: sw=4 ts=4
6912+ */
6913diff -Nura php-4.4.1/Zend/zend_compile.c hardening-patch-4.4.1-0.4.6/Zend/zend_compile.c
6914--- php-4.4.1/Zend/zend_compile.c 2005-10-07 10:42:49.000000000 +0200
6915+++ hardening-patch-4.4.1-0.4.6/Zend/zend_compile.c 2005-11-05 13:04:08.000000000 +0100
6916@@ -768,6 +768,13 @@
6917 op_array.function_name = name;
6918 op_array.arg_types = NULL;
6919 op_array.return_reference = return_reference;
6920+#if HARDENING_PATCH
6921+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6922+ op_array.created_by_eval = 1;
6923+ } else {
6924+ op_array.created_by_eval = 0;
6925+ }
6926+#endif
6927
6928 if (is_method) {
6929 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
6930diff -Nura php-4.4.1/Zend/zend_compile.h hardening-patch-4.4.1-0.4.6/Zend/zend_compile.h
6931--- php-4.4.1/Zend/zend_compile.h 2005-06-06 11:30:09.000000000 +0200
6932+++ hardening-patch-4.4.1-0.4.6/Zend/zend_compile.h 2005-11-05 13:04:08.000000000 +0100
6933@@ -106,6 +106,9 @@
6934 char *filename;
6935
6936 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6937+#if HARDENING_PATCH
6938+ zend_bool created_by_eval;
6939+#endif
6940 };
6941
6942
6943@@ -549,6 +552,7 @@
6944 #define ZEND_USER_FUNCTION 2
6945 #define ZEND_OVERLOADED_FUNCTION 3
6946 #define ZEND_EVAL_CODE 4
6947+#define ZEND_SANDBOX_CODE 6
6948
6949 #define ZEND_INTERNAL_CLASS 1
6950 #define ZEND_USER_CLASS 2
6951diff -Nura php-4.4.1/Zend/zend_constants.c hardening-patch-4.4.1-0.4.6/Zend/zend_constants.c
6952--- php-4.4.1/Zend/zend_constants.c 2004-07-13 21:29:45.000000000 +0200
6953+++ hardening-patch-4.4.1-0.4.6/Zend/zend_constants.c 2005-11-05 13:04:08.000000000 +0100
6954@@ -111,6 +111,73 @@
6955 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6956
6957 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6958+#if HARDENING_PATCH
6959+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6960+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6961+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6962+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6963+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6964+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6965+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6966+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6967+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6968+
6969+ /* error levels */
6970+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6971+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6972+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6973+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6974+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6975+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6976+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6977+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6978+ /* facility: type of program logging the message */
6979+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6980+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6981+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6982+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6983+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6984+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6985+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6986+#ifdef LOG_NEWS
6987+ /* No LOG_NEWS on HP-UX */
6988+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6989+#endif
6990+#ifdef LOG_UUCP
6991+ /* No LOG_UUCP on HP-UX */
6992+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6993+#endif
6994+#ifdef LOG_CRON
6995+ /* apparently some systems don't have this one */
6996+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6997+#endif
6998+#ifdef LOG_AUTHPRIV
6999+ /* AIX doesn't have LOG_AUTHPRIV */
7000+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7001+#endif
7002+#if !defined(PHP_WIN32) && !defined(NETWARE)
7003+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7004+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7005+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7006+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7007+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7008+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7009+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7010+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7011+#endif
7012+ /* options */
7013+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7014+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7015+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7016+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7017+#ifdef LOG_NOWAIT
7018+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7019+#endif
7020+#ifdef LOG_PERROR
7021+ /* AIX doesn't have LOG_PERROR */
7022+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7023+#endif
7024+#endif
7025
7026 /* true/false constants */
7027 {
7028diff -Nura php-4.4.1/Zend/zend_errors.h hardening-patch-4.4.1-0.4.6/Zend/zend_errors.h
7029--- php-4.4.1/Zend/zend_errors.h 2002-12-31 17:22:59.000000000 +0100
7030+++ hardening-patch-4.4.1-0.4.6/Zend/zend_errors.h 2005-11-05 13:04:08.000000000 +0100
7031@@ -36,5 +36,17 @@
7032 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
7033 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7034
7035+#if HARDENING_PATCH
7036+#define S_MEMORY (1<<0L)
7037+#define S_VARS (1<<1L)
7038+#define S_FILES (1<<2L)
7039+#define S_INCLUDE (1<<3L)
7040+#define S_SQL (1<<4L)
7041+#define S_EXECUTOR (1<<5L)
7042+#define S_MISC (1<<30L)
7043+#define S_INTERNAL (1<<29L)
7044+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
7045+#endif
7046+
7047 #endif /* ZEND_ERRORS_H */
7048
7049diff -Nura php-4.4.1/Zend/zend_execute_API.c hardening-patch-4.4.1-0.4.6/Zend/zend_execute_API.c
7050--- php-4.4.1/Zend/zend_execute_API.c 2005-08-02 19:52:33.000000000 +0200
7051+++ hardening-patch-4.4.1-0.4.6/Zend/zend_execute_API.c 2005-11-05 13:04:08.000000000 +0100
7052@@ -142,6 +142,7 @@
7053 EG(class_table) = CG(class_table);
7054
7055 EG(in_execution) = 0;
7056+ EG(in_code_type) = 0;
7057
7058 zend_ptr_stack_init(&EG(argument_stack));
7059
7060@@ -431,12 +432,14 @@
7061 zend_execute_data execute_data;
7062
7063 /* Initialize execute_data */
7064+ memset(&execute_data, 0, sizeof(execute_data));
7065 EX(fbc) = NULL;
7066 EX(object).ptr = NULL;
7067 EX(ce) = NULL;
7068 EX(Ts) = NULL;
7069 EX(op_array) = NULL;
7070 EX(opline) = NULL;
7071+ EX(execute_depth) = 0;
7072
7073 *retval_ptr_ptr = NULL;
7074
7075@@ -494,6 +497,39 @@
7076 zval_dtor(&function_name_copy);
7077 return FAILURE;
7078 }
7079+#if HARDENING_PATCH
7080+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7081+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7082+ if (HG(eval_whitelist) != NULL) {
7083+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7084+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7085+ zval_dtor(&function_name_copy);
7086+ zend_bailout();
7087+ }
7088+ } else if (HG(eval_blacklist) != NULL) {
7089+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7090+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7091+ zval_dtor(&function_name_copy);
7092+ zend_bailout();
7093+ }
7094+ }
7095+ }
7096+
7097+ if (HG(func_whitelist) != NULL) {
7098+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7099+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7100+ zval_dtor(&function_name_copy);
7101+ zend_bailout();
7102+ }
7103+ } else if (HG(func_blacklist) != NULL) {
7104+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7105+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7106+ zval_dtor(&function_name_copy);
7107+ zend_bailout();
7108+ }
7109+ }
7110+ }
7111+#endif
7112 zval_dtor(&function_name_copy);
7113
7114 for (i=0; i<param_count; i++) {
7115@@ -606,8 +642,7 @@
7116 return SUCCESS;
7117 }
7118
7119-
7120-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7121+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7122 {
7123 zval pv;
7124 zend_op_array *new_op_array;
7125@@ -640,6 +675,7 @@
7126 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7127 zend_op **original_opline_ptr = EG(opline_ptr);
7128
7129+ new_op_array->type = type;
7130 EG(return_value_ptr_ptr) = &local_retval_ptr;
7131 EG(active_op_array) = new_op_array;
7132 EG(no_extensions)=1;
7133@@ -673,6 +709,10 @@
7134 return retval;
7135 }
7136
7137+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7138+{
7139+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7140+}
7141
7142 void execute_new_code(TSRMLS_D)
7143 {
7144diff -Nura php-4.4.1/Zend/zend_execute.c hardening-patch-4.4.1-0.4.6/Zend/zend_execute.c
7145--- php-4.4.1/Zend/zend_execute.c 2005-10-13 10:46:27.000000000 +0200
7146+++ hardening-patch-4.4.1-0.4.6/Zend/zend_execute.c 2005-11-05 13:04:08.000000000 +0100
7147@@ -1042,6 +1042,7 @@
7148 zend_execute_data execute_data;
7149
7150 /* Initialize execute_data */
7151+ memset(&execute_data, 0, sizeof(execute_data));
7152 EX(fbc) = NULL;
7153 EX(ce) = NULL;
7154 EX(object).ptr = NULL;
7155@@ -1053,9 +1054,21 @@
7156 }
7157 EX(prev_execute_data) = EG(current_execute_data);
7158 EX(original_in_execution)=EG(in_execution);
7159+ EX(original_in_code_type)=EG(in_code_type);
7160
7161 EG(current_execute_data) = &execute_data;
7162
7163+#if HARDENING_PATCH
7164+ EX(execute_depth) = 0;
7165+
7166+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7167+ EG(in_code_type) = ZEND_EVAL_CODE;
7168+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7169+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7170+ op_array->type = ZEND_EVAL_CODE;
7171+ }
7172+#endif
7173+
7174 EG(in_execution) = 1;
7175 if (op_array->start_op) {
7176 EX(opline) = op_array->start_op;
7177@@ -1087,6 +1100,19 @@
7178 }
7179 }
7180
7181+#if HARDENING_PATCH
7182+ if (EX(prev_execute_data) == NULL) {
7183+ EX(execute_depth) = 0;
7184+ } else {
7185+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7186+ }
7187+
7188+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7189+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7190+ zend_bailout();
7191+ }
7192+#endif
7193+
7194 while (1) {
7195 #ifdef ZEND_WIN32
7196 if (EG(timed_out)) {
7197@@ -1634,6 +1660,36 @@
7198 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7199 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7200 }
7201+#if HARDENING_PATCH
7202+ if (active_function_table == EG(function_table)) {
7203+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7204+ if (HG(eval_whitelist) != NULL) {
7205+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7206+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7207+ zend_bailout();
7208+ }
7209+ } else if (HG(eval_blacklist) != NULL) {
7210+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7211+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7212+ zend_bailout();
7213+ }
7214+ }
7215+ }
7216+
7217+ if (HG(func_whitelist) != NULL) {
7218+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7219+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7220+ zend_bailout();
7221+ }
7222+ } else if (HG(func_blacklist) != NULL) {
7223+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7224+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7225+ zend_bailout();
7226+ }
7227+ }
7228+ }
7229+#endif
7230+
7231 zval_dtor(&tmp);
7232 EX(fbc) = function;
7233 overloaded_function_call_cont:
7234@@ -1649,6 +1705,35 @@
7235 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7236 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7237 }
7238+#if HARDENING_PATCH
7239+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7240+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7241+ if (HG(eval_whitelist) != NULL) {
7242+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7243+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7244+ zend_bailout();
7245+ }
7246+ } else if (HG(eval_blacklist) != NULL) {
7247+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7248+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7249+ zend_bailout();
7250+ }
7251+ }
7252+ }
7253+
7254+ if (HG(func_whitelist) != NULL) {
7255+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7256+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7257+ zend_bailout();
7258+ }
7259+ } else if (HG(func_blacklist) != NULL) {
7260+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7261+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7262+ zend_bailout();
7263+ }
7264+ }
7265+ }
7266+#endif
7267 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7268 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7269 EX(object).ptr = NULL;
7270@@ -1821,6 +1906,7 @@
7271 efree(EX(Ts));
7272 }
7273 EG(in_execution) = EX(original_in_execution);
7274+ EG(in_code_type) = EX(original_in_code_type);
7275 EG(current_execute_data) = EX(prev_execute_data);
7276 return;
7277 }
7278@@ -2210,7 +2296,12 @@
7279 int dummy = 1;
7280 zend_file_handle file_handle = {0};
7281
7282+#if HARDENING_PATCH_INC_PROTECT
7283+ if (zend_is_valid_include(inc_filename)
7284+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7285+#else
7286 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7287+#endif
7288 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7289
7290 file_handle.filename = inc_filename->value.str.val;
7291@@ -2239,6 +2330,11 @@
7292 break;
7293 case ZEND_INCLUDE:
7294 case ZEND_REQUIRE:
7295+#if HARDENING_PATCH_INC_PROTECT
7296+ if (!zend_is_valid_include(inc_filename)) {
7297+ break;
7298+ }
7299+#endif
7300 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7301 break;
7302 case ZEND_EVAL: {
7303diff -Nura php-4.4.1/Zend/zend_execute_globals.h hardening-patch-4.4.1-0.4.6/Zend/zend_execute_globals.h
7304--- php-4.4.1/Zend/zend_execute_globals.h 2005-06-06 11:30:09.000000000 +0200
7305+++ hardening-patch-4.4.1-0.4.6/Zend/zend_execute_globals.h 2005-11-05 13:04:08.000000000 +0100
7306@@ -60,6 +60,8 @@
7307 object_info object;
7308 temp_variable *Ts;
7309 zend_bool original_in_execution;
7310+ zend_uint original_in_code_type;
7311+ zend_uint execute_depth;
7312 zend_op_array *op_array;
7313 struct _zend_execute_data *prev_execute_data;
7314 } zend_execute_data;
7315diff -Nura php-4.4.1/Zend/zend_extensions.c hardening-patch-4.4.1-0.4.6/Zend/zend_extensions.c
7316--- php-4.4.1/Zend/zend_extensions.c 2003-03-19 19:00:57.000000000 +0100
7317+++ hardening-patch-4.4.1-0.4.6/Zend/zend_extensions.c 2005-11-05 13:04:08.000000000 +0100
7318@@ -54,23 +54,44 @@
7319 return FAILURE;
7320 }
7321
7322+ /* check if module is compiled against Hardening-Patch */
7323+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7324+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7325+ "The Hardening-Patch version %d is installed.\n\n",
7326+ new_extension->name,
7327+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7328+ DL_UNLOAD(handle);
7329+ return FAILURE;
7330+ }
7331+
7332+
7333+ /* check if module is compiled against correct Hardening-Patch version */
7334+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7335+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7336+ "The Hardening-Patch version %d is installed.\n\n",
7337+ new_extension->name,
7338+ extension_version_info->zend_extension_api_no,
7339+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7340+ DL_UNLOAD(handle);
7341+ return FAILURE;
7342+ }
7343
7344 /* allow extension to proclaim compatibility with any Zend version */
7345- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7346- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7347+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7348+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7349 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7350 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7351 new_extension->name,
7352- extension_version_info->zend_extension_api_no,
7353+ extension_version_info->real_zend_extension_api_no,
7354 ZEND_EXTENSION_API_NO);
7355 DL_UNLOAD(handle);
7356 return FAILURE;
7357- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7358+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7359 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7360 "The Zend Engine API version %d which is installed, is newer.\n"
7361 "Contact %s at %s for a later version of %s.\n\n",
7362 new_extension->name,
7363- extension_version_info->zend_extension_api_no,
7364+ extension_version_info->real_zend_extension_api_no,
7365 ZEND_EXTENSION_API_NO,
7366 new_extension->author,
7367 new_extension->URL,
7368diff -Nura php-4.4.1/Zend/zend_extensions.h hardening-patch-4.4.1-0.4.6/Zend/zend_extensions.h
7369--- php-4.4.1/Zend/zend_extensions.h 2005-06-06 11:44:59.000000000 +0200
7370+++ hardening-patch-4.4.1-0.4.6/Zend/zend_extensions.h 2005-11-05 13:04:08.000000000 +0100
7371@@ -23,6 +23,9 @@
7372
7373 #include "zend_compile.h"
7374
7375+/* Create own API version number for Hardening-Patch */
7376+
7377+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7378 #define ZEND_EXTENSION_API_NO 20050606
7379
7380 typedef struct _zend_extension_version_info {
7381@@ -30,6 +33,7 @@
7382 char *required_zend_version;
7383 unsigned char thread_safe;
7384 unsigned char debug;
7385+ int real_zend_extension_api_no;
7386 } zend_extension_version_info;
7387
7388
7389@@ -96,7 +100,7 @@
7390
7391
7392 #define ZEND_EXTENSION() \
7393- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7394+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
7395
7396 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7397 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7398diff -Nura php-4.4.1/Zend/zend_globals.h hardening-patch-4.4.1-0.4.6/Zend/zend_globals.h
7399--- php-4.4.1/Zend/zend_globals.h 2004-11-04 00:15:05.000000000 +0100
7400+++ hardening-patch-4.4.1-0.4.6/Zend/zend_globals.h 2005-11-05 13:04:08.000000000 +0100
7401@@ -163,6 +163,16 @@
7402
7403 int error_reporting;
7404 int orig_error_reporting;
7405+#if HARDENING_PATCH
7406+ int hphp_log_syslog;
7407+ int hphp_log_syslog_facility;
7408+ int hphp_log_syslog_priority;
7409+ int hphp_log_sapi;
7410+ int hphp_log_script;
7411+ char *hphp_log_scriptname;
7412+ zend_bool hphp_log_use_x_forwarded_for;
7413+ long hphp_executor_max_depth;
7414+#endif
7415 int exit_status;
7416
7417 zend_op_array *active_op_array;
7418@@ -176,6 +186,7 @@
7419 int ticks_count;
7420
7421 zend_bool in_execution;
7422+ zend_uint in_code_type;
7423 zend_bool bailout_set;
7424 zend_bool full_tables_cleanup;
7425
7426diff -Nura php-4.4.1/Zend/zend.h hardening-patch-4.4.1-0.4.6/Zend/zend.h
7427--- php-4.4.1/Zend/zend.h 2005-07-23 13:58:40.000000000 +0200
7428+++ hardening-patch-4.4.1-0.4.6/Zend/zend.h 2005-11-05 13:04:08.000000000 +0100
7429@@ -274,9 +274,10 @@
7430 struct _zval_struct {
7431 /* Variable information */
7432 zvalue_value value; /* value */
7433+ zend_uint refcount;
7434+ zend_ushort flags;
7435 zend_uchar type; /* active type */
7436 zend_uchar is_ref;
7437- zend_ushort refcount;
7438 };
7439
7440
7441@@ -337,6 +338,12 @@
7442 void (*ticks_function)(int ticks);
7443 void (*on_timeout)(int seconds TSRMLS_DC);
7444 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7445+#if HARDENING_PATCH
7446+ void (*security_log_function)(int loglevel, char *fmt, ...);
7447+#endif
7448+#if HARDENING_PATCH_INC_PROTECT
7449+ int (*is_valid_include)(zval *z);
7450+#endif
7451 } zend_utility_functions;
7452
7453
7454@@ -468,7 +475,16 @@
7455 extern ZEND_API void (*zend_ticks_function)(int ticks);
7456 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);
7457 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7458+#if HARDENING_PATCH
7459+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7460+#endif
7461+#if HARDENING_PATCH_INC_PROTECT
7462+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7463+#endif
7464
7465+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7466+ZEND_API unsigned int zend_canary(void);
7467+#endif
7468
7469 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7470
7471@@ -575,6 +591,11 @@
7472
7473 #define ZEND_MAX_RESERVED_RESOURCES 4
7474
7475+#if HARDENING_PATCH
7476+#include "hardened_globals.h"
7477+#include "php_syslog.h"
7478+#endif
7479+
7480 #endif /* ZEND_H */
7481
7482 /*
7483diff -Nura php-4.4.1/Zend/zend_hash.c hardening-patch-4.4.1-0.4.6/Zend/zend_hash.c
7484--- php-4.4.1/Zend/zend_hash.c 2005-04-28 09:34:32.000000000 +0200
7485+++ hardening-patch-4.4.1-0.4.6/Zend/zend_hash.c 2005-11-05 13:04:08.000000000 +0100
7486@@ -26,6 +26,17 @@
7487 # include <stdlib.h>
7488 #endif
7489
7490+#if HARDENING_PATCH_HASH_PROTECT
7491+ unsigned int zend_hash_canary = 0x1234567;
7492+ zend_bool zend_hash_canary_inited = 0;
7493+#endif
7494+
7495+#define CHECK_HASH_CANARY(hash) \
7496+ if (zend_hash_canary != (hash)->canary) { \
7497+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7498+ exit(1); \
7499+ }
7500+
7501 #define HANDLE_NUMERIC(key, length, func) { \
7502 register char *tmp=key; \
7503 \
7504@@ -175,6 +186,9 @@
7505 {
7506 uint i = 3;
7507 Bucket **tmp;
7508+#if HARDENING_PATCH_HASH_PROTECT
7509+ TSRMLS_FETCH();
7510+#endif
7511
7512 SET_INCONSISTENT(HT_OK);
7513
7514@@ -184,6 +198,13 @@
7515
7516 ht->nTableSize = 1 << i;
7517 ht->nTableMask = ht->nTableSize - 1;
7518+#if HARDENING_PATCH_HASH_PROTECT
7519+ if (zend_hash_canary_inited==0) {
7520+ zend_hash_canary = zend_canary();
7521+ zend_hash_canary_inited = 1;
7522+ }
7523+ ht->canary = zend_hash_canary;
7524+#endif
7525 ht->pDestructor = pDestructor;
7526 ht->pListHead = NULL;
7527 ht->pListTail = NULL;
7528@@ -259,6 +280,9 @@
7529 }
7530 #endif
7531 if (ht->pDestructor) {
7532+#if HARDENING_PATCH_HASH_PROTECT
7533+ CHECK_HASH_CANARY(ht);
7534+#endif
7535 ht->pDestructor(p->pData);
7536 }
7537 UPDATE_DATA(ht, p, pData, nDataSize);
7538@@ -327,6 +351,9 @@
7539 }
7540 #endif
7541 if (ht->pDestructor) {
7542+#if HARDENING_PATCH_HASH_PROTECT
7543+ CHECK_HASH_CANARY(ht);
7544+#endif
7545 ht->pDestructor(p->pData);
7546 }
7547 UPDATE_DATA(ht, p, pData, nDataSize);
7548@@ -402,6 +429,9 @@
7549 }
7550 #endif
7551 if (ht->pDestructor) {
7552+#if HARDENING_PATCH_HASH_PROTECT
7553+ CHECK_HASH_CANARY(ht);
7554+#endif
7555 ht->pDestructor(p->pData);
7556 }
7557 UPDATE_DATA(ht, p, pData, nDataSize);
7558@@ -450,7 +480,7 @@
7559 IS_CONSISTENT(ht);
7560
7561 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7562- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7563+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7564 if (t) {
7565 HANDLE_BLOCK_INTERRUPTIONS();
7566 ht->arBuckets = t;
7567@@ -460,6 +490,7 @@
7568 HANDLE_UNBLOCK_INTERRUPTIONS();
7569 return SUCCESS;
7570 }
7571+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7572 return FAILURE;
7573 }
7574 return SUCCESS;
7575@@ -524,6 +555,9 @@
7576 ht->pInternalPointer = p->pListNext;
7577 }
7578 if (ht->pDestructor) {
7579+#if HARDENING_PATCH_HASH_PROTECT
7580+ CHECK_HASH_CANARY(ht);
7581+#endif
7582 ht->pDestructor(p->pData);
7583 }
7584 if (!p->pDataPtr) {
7585@@ -553,6 +587,9 @@
7586 q = p;
7587 p = p->pListNext;
7588 if (ht->pDestructor) {
7589+#if HARDENING_PATCH_HASH_PROTECT
7590+ CHECK_HASH_CANARY(ht);
7591+#endif
7592 ht->pDestructor(q->pData);
7593 }
7594 if (!q->pDataPtr && q->pData) {
7595@@ -579,6 +616,9 @@
7596 q = p;
7597 p = p->pListNext;
7598 if (ht->pDestructor) {
7599+#if HARDENING_PATCH_HASH_PROTECT
7600+ CHECK_HASH_CANARY(ht);
7601+#endif
7602 ht->pDestructor(q->pData);
7603 }
7604 if (!q->pDataPtr && q->pData) {
7605@@ -608,6 +648,9 @@
7606 HANDLE_BLOCK_INTERRUPTIONS();
7607
7608 if (ht->pDestructor) {
7609+#if HARDENING_PATCH_HASH_PROTECT
7610+ CHECK_HASH_CANARY(ht);
7611+#endif
7612 ht->pDestructor(p->pData);
7613 }
7614 if (!p->pDataPtr) {
7615diff -Nura php-4.4.1/Zend/zend_hash.h hardening-patch-4.4.1-0.4.6/Zend/zend_hash.h
7616--- php-4.4.1/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
7617+++ hardening-patch-4.4.1-0.4.6/Zend/zend_hash.h 2005-11-05 13:04:08.000000000 +0100
7618@@ -54,6 +54,9 @@
7619 } Bucket;
7620
7621 typedef struct _hashtable {
7622+#if HARDENING_PATCH_HASH_PROTECT
7623+ unsigned int canary;
7624+#endif
7625 uint nTableSize;
7626 uint nTableMask;
7627 uint nNumOfElements;
7628diff -Nura php-4.4.1/Zend/zend_ini.h hardening-patch-4.4.1-0.4.6/Zend/zend_ini.h
7629--- php-4.4.1/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7630+++ hardening-patch-4.4.1-0.4.6/Zend/zend_ini.h 2005-11-05 13:04:08.000000000 +0100
7631@@ -174,6 +174,7 @@
7632 /* Standard message handlers */
7633 BEGIN_EXTERN_C()
7634 ZEND_API ZEND_INI_MH(OnUpdateBool);
7635+#define OnUpdateLong OnUpdateInt
7636 ZEND_API ZEND_INI_MH(OnUpdateInt);
7637 ZEND_API ZEND_INI_MH(OnUpdateReal);
7638 ZEND_API ZEND_INI_MH(OnUpdateString);
7639diff -Nura php-4.4.1/Zend/zend_language_scanner.l hardening-patch-4.4.1-0.4.6/Zend/zend_language_scanner.l
7640--- php-4.4.1/Zend/zend_language_scanner.l 2005-03-09 16:07:19.000000000 +0100
7641+++ hardening-patch-4.4.1-0.4.6/Zend/zend_language_scanner.l 2005-11-05 13:04:08.000000000 +0100
7642@@ -393,6 +393,13 @@
7643 compilation_successful=0;
7644 } else {
7645 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7646+#if HARDENING_PATCH
7647+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7648+ op_array->created_by_eval = 1;
7649+ } else {
7650+ op_array->created_by_eval = 0;
7651+ }
7652+#endif
7653 CG(in_compilation) = 1;
7654 CG(active_op_array) = op_array;
7655 compiler_result = zendparse(TSRMLS_C);
7656diff -Nura php-4.4.1/Zend/zend_language_scanner.c hardening-patch-4.4.1-0.4.6/Zend/zend_language_scanner.c
7657--- php-4.4.1/Zend/zend_language_scanner.c 2005-10-30 12:06:40.000000000 +0100
7658+++ hardening-patch-4.4.1-0.4.6/Zend/zend_language_scanner.c 2005-11-15 22:09:54.000000000 +0100
7659@@ -3121,6 +3121,13 @@
7660 compilation_successful=0;
7661 } else {
7662 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7663+#if HARDENING_PATCH
7664+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7665+ op_array->created_by_eval = 1;
7666+ } else {
7667+ op_array->created_by_eval = 0;
7668+ }
7669+#endif
7670 CG(in_compilation) = 1;
7671 CG(active_op_array) = op_array;
7672 compiler_result = zendparse(TSRMLS_C);
7673diff -Nura php-4.4.1/Zend/zend_llist.c hardening-patch-4.4.1-0.4.6/Zend/zend_llist.c
7674--- php-4.4.1/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
7675+++ hardening-patch-4.4.1-0.4.6/Zend/zend_llist.c 2005-11-05 13:04:08.000000000 +0100
7676@@ -21,9 +21,34 @@
7677 #include "zend.h"
7678 #include "zend_llist.h"
7679 #include "zend_qsort.h"
7680+#include "zend_globals.h"
7681+
7682+#define CHECK_LIST_CANARY(list) \
7683+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
7684+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7685+ exit(1); \
7686+ }
7687+
7688+#define CHECK_LISTELEMENT_CANARY(elem) \
7689+ if (HG(canary_3) != (elem)->canary) { \
7690+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7691+ exit(1); \
7692+ }
7693+
7694
7695 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7696 {
7697+#if HARDENING_PATCH_LL_PROTECT
7698+ TSRMLS_FETCH();
7699+
7700+ if (!HG(ll_canary_inited)) {
7701+ HG(canary_3) = zend_canary();
7702+ HG(canary_4) = zend_canary();
7703+ HG(ll_canary_inited) = 1;
7704+ }
7705+ l->canary_h = HG(canary_3);
7706+ l->canary_t = HG(canary_4);
7707+#endif
7708 l->head = NULL;
7709 l->tail = NULL;
7710 l->count = 0;
7711@@ -37,6 +62,11 @@
7712 {
7713 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7714
7715+#if HARDENING_PATCH_LL_PROTECT
7716+ TSRMLS_FETCH();
7717+ CHECK_LIST_CANARY(l)
7718+ tmp->canary = HG(canary_3);
7719+#endif
7720 tmp->prev = l->tail;
7721 tmp->next = NULL;
7722 if (l->tail) {
7723@@ -55,6 +85,11 @@
7724 {
7725 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7726
7727+#if HARDENING_PATCH_LL_PROTECT
7728+ TSRMLS_FETCH();
7729+ CHECK_LIST_CANARY(l)
7730+ tmp->canary = HG(canary_3);
7731+#endif
7732 tmp->next = l->head;
7733 tmp->prev = NULL;
7734 if (l->head) {
7735@@ -91,10 +126,20 @@
7736 zend_llist_element *current=l->head;
7737 zend_llist_element *next;
7738
7739+#if HARDENING_PATCH_LL_PROTECT
7740+ TSRMLS_FETCH();
7741+ CHECK_LIST_CANARY(l)
7742+#endif
7743 while (current) {
7744+#if HARDENING_PATCH_LL_PROTECT
7745+ CHECK_LISTELEMENT_CANARY(current)
7746+#endif
7747 next = current->next;
7748 if (compare(current->data, element)) {
7749 DEL_LLIST_ELEMENT(current, l);
7750+#if HARDENING_PATCH_LL_PROTECT
7751+ current->canary = 0;
7752+#endif
7753 break;
7754 }
7755 current = next;
7756@@ -106,7 +151,14 @@
7757 {
7758 zend_llist_element *current=l->head, *next;
7759
7760+#if HARDENING_PATCH_LL_PROTECT
7761+ TSRMLS_FETCH();
7762+ CHECK_LIST_CANARY(l)
7763+#endif
7764 while (current) {
7765+#if HARDENING_PATCH_LL_PROTECT
7766+ CHECK_LISTELEMENT_CANARY(current)
7767+#endif
7768 next = current->next;
7769 if (l->dtor) {
7770 l->dtor(current->data);
7771@@ -131,7 +183,14 @@
7772 zend_llist_element *old_tail;
7773 void *data;
7774
7775+#if HARDENING_PATCH_LL_PROTECT
7776+ TSRMLS_FETCH();
7777+ CHECK_LIST_CANARY(l)
7778+#endif
7779 if ((old_tail = l->tail)) {
7780+#if HARDENING_PATCH_LL_PROTECT
7781+ CHECK_LISTELEMENT_CANARY(old_tail)
7782+#endif
7783 if (l->tail->prev) {
7784 l->tail->prev->next = NULL;
7785 }
7786@@ -157,9 +216,16 @@
7787 {
7788 zend_llist_element *ptr;
7789
7790+#if HARDENING_PATCH_LL_PROTECT
7791+ TSRMLS_FETCH();
7792+ CHECK_LIST_CANARY(src)
7793+#endif
7794 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7795 ptr = src->head;
7796 while (ptr) {
7797+#if HARDENING_PATCH_LL_PROTECT
7798+ CHECK_LISTELEMENT_CANARY(ptr)
7799+#endif
7800 zend_llist_add_element(dst, ptr->data);
7801 ptr = ptr->next;
7802 }
7803@@ -170,11 +236,21 @@
7804 {
7805 zend_llist_element *element, *next;
7806
7807+#if HARDENING_PATCH_LL_PROTECT
7808+ TSRMLS_FETCH();
7809+ CHECK_LIST_CANARY(l)
7810+#endif
7811 element=l->head;
7812 while (element) {
7813+#if HARDENING_PATCH_LL_PROTECT
7814+ CHECK_LISTELEMENT_CANARY(element)
7815+#endif
7816 next = element->next;
7817 if (func(element->data)) {
7818 DEL_LLIST_ELEMENT(element, l);
7819+#if HARDENING_PATCH_LL_PROTECT
7820+ element->canary = 0;
7821+#endif
7822 }
7823 element = next;
7824 }
7825@@ -185,7 +261,13 @@
7826 {
7827 zend_llist_element *element;
7828
7829+#if HARDENING_PATCH_LL_PROTECT
7830+ CHECK_LIST_CANARY(l)
7831+#endif
7832 for (element=l->head; element; element=element->next) {
7833+#if HARDENING_PATCH_LL_PROTECT
7834+ CHECK_LISTELEMENT_CANARY(element)
7835+#endif
7836 func(element->data TSRMLS_CC);
7837 }
7838 }
7839@@ -197,6 +279,9 @@
7840 zend_llist_element **elements;
7841 zend_llist_element *element, **ptr;
7842
7843+#if HARDENING_PATCH_LL_PROTECT
7844+ CHECK_LIST_CANARY(l)
7845+#endif
7846 if (l->count <= 0) {
7847 return;
7848 }
7849@@ -206,6 +291,9 @@
7850 ptr = &elements[0];
7851
7852 for (element=l->head; element; element=element->next) {
7853+#if HARDENING_PATCH_LL_PROTECT
7854+ CHECK_LISTELEMENT_CANARY(element)
7855+#endif
7856 *ptr++ = element;
7857 }
7858
7859@@ -228,7 +316,13 @@
7860 {
7861 zend_llist_element *element;
7862
7863+#if HARDENING_PATCH_LL_PROTECT
7864+ CHECK_LIST_CANARY(l)
7865+#endif
7866 for (element=l->head; element; element=element->next) {
7867+#if HARDENING_PATCH_LL_PROTECT
7868+ CHECK_LISTELEMENT_CANARY(element)
7869+#endif
7870 func(element->data, arg TSRMLS_CC);
7871 }
7872 }
7873@@ -239,8 +333,14 @@
7874 zend_llist_element *element;
7875 va_list args;
7876
7877+#if HARDENING_PATCH_LL_PROTECT
7878+ CHECK_LIST_CANARY(l)
7879+#endif
7880 va_start(args, num_args);
7881 for (element=l->head; element; element=element->next) {
7882+#if HARDENING_PATCH_LL_PROTECT
7883+ CHECK_LISTELEMENT_CANARY(element)
7884+#endif
7885 func(element->data, num_args, args TSRMLS_CC);
7886 }
7887 va_end(args);
7888@@ -249,6 +349,10 @@
7889
7890 ZEND_API int zend_llist_count(zend_llist *l)
7891 {
7892+#if HARDENING_PATCH_LL_PROTECT
7893+ TSRMLS_FETCH();
7894+ CHECK_LIST_CANARY(l)
7895+#endif
7896 return l->count;
7897 }
7898
7899@@ -256,8 +360,15 @@
7900 {
7901 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7902
7903+#if HARDENING_PATCH_LL_PROTECT
7904+ TSRMLS_FETCH();
7905+ CHECK_LIST_CANARY(l)
7906+#endif
7907 *current = l->head;
7908 if (*current) {
7909+#if HARDENING_PATCH_LL_PROTECT
7910+ CHECK_LISTELEMENT_CANARY(*current)
7911+#endif
7912 return (*current)->data;
7913 } else {
7914 return NULL;
7915@@ -269,8 +380,15 @@
7916 {
7917 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7918
7919+#if HARDENING_PATCH_LL_PROTECT
7920+ TSRMLS_FETCH();
7921+ CHECK_LIST_CANARY(l)
7922+#endif
7923 *current = l->tail;
7924 if (*current) {
7925+#if HARDENING_PATCH_LL_PROTECT
7926+ CHECK_LISTELEMENT_CANARY(*current)
7927+#endif
7928 return (*current)->data;
7929 } else {
7930 return NULL;
7931@@ -282,9 +400,19 @@
7932 {
7933 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7934
7935+#if HARDENING_PATCH_LL_PROTECT
7936+ TSRMLS_FETCH();
7937+ CHECK_LIST_CANARY(l)
7938+#endif
7939 if (*current) {
7940+#if HARDENING_PATCH_LL_PROTECT
7941+ CHECK_LISTELEMENT_CANARY(*current)
7942+#endif
7943 *current = (*current)->next;
7944 if (*current) {
7945+#if HARDENING_PATCH_LL_PROTECT
7946+ CHECK_LISTELEMENT_CANARY(*current)
7947+#endif
7948 return (*current)->data;
7949 }
7950 }
7951@@ -296,9 +424,19 @@
7952 {
7953 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7954
7955+#if HARDENING_PATCH_LL_PROTECT
7956+ TSRMLS_FETCH();
7957+ CHECK_LIST_CANARY(l)
7958+#endif
7959 if (*current) {
7960+#if HARDENING_PATCH_LL_PROTECT
7961+ CHECK_LISTELEMENT_CANARY(*current)
7962+#endif
7963 *current = (*current)->prev;
7964 if (*current) {
7965+#if HARDENING_PATCH_LL_PROTECT
7966+ CHECK_LISTELEMENT_CANARY(*current)
7967+#endif
7968 return (*current)->data;
7969 }
7970 }
7971diff -Nura php-4.4.1/Zend/zend_llist.h hardening-patch-4.4.1-0.4.6/Zend/zend_llist.h
7972--- php-4.4.1/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
7973+++ hardening-patch-4.4.1-0.4.6/Zend/zend_llist.h 2005-11-15 21:45:52.000000000 +0100
7974@@ -24,6 +24,9 @@
7975 #include <stdlib.h>
7976
7977 typedef struct _zend_llist_element {
7978+#if HARDENING_PATCH_LL_PROTECT
7979+ unsigned int canary, padding;
7980+#endif
7981 struct _zend_llist_element *next;
7982 struct _zend_llist_element *prev;
7983 char data[1]; /* Needs to always be last in the struct */
7984@@ -36,6 +39,9 @@
7985 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7986
7987 typedef struct _zend_llist {
7988+#if HARDENING_PATCH_LL_PROTECT
7989+ unsigned int canary_h; /* head */
7990+#endif
7991 zend_llist_element *head;
7992 zend_llist_element *tail;
7993 size_t size;
7994@@ -43,6 +49,9 @@
7995 llist_dtor_func_t dtor;
7996 unsigned char persistent;
7997 zend_llist_element *traverse_ptr;
7998+#if HARDENING_PATCH_LL_PROTECT
7999+ unsigned int canary_t; /* tail */
8000+#endif
8001 } zend_llist;
8002
8003 typedef zend_llist_element* zend_llist_position;
8004diff -Nura php-4.4.1/Zend/zend_modules.h hardening-patch-4.4.1-0.4.6/Zend/zend_modules.h
8005--- php-4.4.1/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
8006+++ hardening-patch-4.4.1-0.4.6/Zend/zend_modules.h 2005-11-15 21:46:49.000000000 +0100
8007@@ -34,6 +34,7 @@
8008 ZEND_API extern unsigned char second_arg_force_ref[];
8009 ZEND_API extern unsigned char third_arg_force_ref[];
8010
8011+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8012 #define ZEND_MODULE_API_NO 20020429
8013 #ifdef ZTS
8014 #define USING_ZTS 1
8015@@ -41,9 +42,9 @@
8016 #define USING_ZTS 0
8017 #endif
8018
8019-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8020+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8021
8022-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8023+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8024
8025 #define STANDARD_MODULE_PROPERTIES \
8026 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8027@@ -75,6 +76,7 @@
8028 unsigned char type;
8029 void *handle;
8030 int module_number;
8031+ unsigned int real_zend_api;
8032 };
8033
8034
8035diff -Nura php-4.4.1/Zend/zend_opcode.c hardening-patch-4.4.1-0.4.6/Zend/zend_opcode.c
8036--- php-4.4.1/Zend/zend_opcode.c 2002-12-31 17:23:04.000000000 +0100
8037+++ hardening-patch-4.4.1-0.4.6/Zend/zend_opcode.c 2005-11-05 13:04:08.000000000 +0100
8038@@ -88,6 +88,9 @@
8039 op_array->done_pass_two = 0;
8040
8041 op_array->start_op = NULL;
8042+#if HARDENING_PATCH
8043+ op_array->created_by_eval = 0;
8044+#endif
8045
8046 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8047 }
8048diff -Nura php-4.4.1/Zend/zend_operators.c hardening-patch-4.4.1-0.4.6/Zend/zend_operators.c
8049--- php-4.4.1/Zend/zend_operators.c 2005-03-31 10:18:39.000000000 +0200
8050+++ hardening-patch-4.4.1-0.4.6/Zend/zend_operators.c 2005-11-05 13:04:08.000000000 +0100
8051@@ -1604,6 +1604,20 @@
8052 return (op->value.lval ? 1 : 0);
8053 }
8054
8055+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8056+{
8057+ register unsigned char *str = (unsigned char*)source;
8058+ register unsigned char *result = (unsigned char*)dest;
8059+ register unsigned char *end = str + length;
8060+
8061+ while (str < end) {
8062+ *result++ = tolower((int)*str++);
8063+ }
8064+ *result = *end;
8065+
8066+ return dest;
8067+}
8068+
8069 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8070 {
8071 register char *p=str, *end=p+length;
8072diff -Nura php-4.4.1/Zend/zend_operators.h hardening-patch-4.4.1-0.4.6/Zend/zend_operators.h
8073--- php-4.4.1/Zend/zend_operators.h 2005-03-31 10:18:40.000000000 +0200
8074+++ hardening-patch-4.4.1-0.4.6/Zend/zend_operators.h 2005-11-05 13:04:08.000000000 +0100
8075@@ -174,6 +174,14 @@
8076 #endif
8077
8078 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8079+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8080+
8081+static inline char *
8082+zend_str_tolower_dup(const char *source, unsigned int length)
8083+{
8084+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8085+}
8086+
8087 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8088 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8089 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
diff --git a/0.4.9/hardening-patch-4.4.2-0.4.9.patch b/0.4.9/hardening-patch-4.4.2-0.4.9.patch
new file mode 100644
index 0000000..1a82e70
--- /dev/null
+++ b/0.4.9/hardening-patch-4.4.2-0.4.9.patch
@@ -0,0 +1,8369 @@
1diff -Nura php-4.4.2/acinclude.m4 hardening-patch-4.4.2-0.4.9/acinclude.m4
2--- php-4.4.2/acinclude.m4 2005-12-19 23:29:11.000000000 +0100
3+++ hardening-patch-4.4.2-0.4.9/acinclude.m4 2006-05-02 16:46:34.000000000 +0200
4@@ -1186,6 +1186,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.4.2/configure hardening-patch-4.4.2-0.4.9/configure
42--- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100
43+++ hardening-patch-4.4.2-0.4.9/configure 2006-05-02 16:46:34.000000000 +0200
44@@ -402,6 +402,16 @@
45 ac_default_prefix=/usr/local
46 # Any additions from configure.in:
47 ac_help="$ac_help
48+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
49+ac_help="$ac_help
50+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
51+ac_help="$ac_help
52+ --disable-hardening-patch-inc-protect Disable include/require protection."
53+ac_help="$ac_help
54+ --disable-hardening-patch-fmt-protect Disable format string protection."
55+ac_help="$ac_help
56+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
57+ac_help="$ac_help
58
59 SAPI modules:
60 "
61@@ -854,6 +864,8 @@
62 ac_help="$ac_help
63 --disable-tokenizer Disable tokenizer support"
64 ac_help="$ac_help
65+ --disable-varfilter Disable Hardening-Patch's variable filter"
66+ac_help="$ac_help
67 --enable-wddx Enable WDDX support."
68 ac_help="$ac_help
69 --disable-xml Disable XML support using bundled expat lib"
70@@ -2942,6 +2954,157 @@
71
72
73
74+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
75+if test "${enable_hardening_patch_mm_protect+set}" = set; then
76+ enableval="$enable_hardening_patch_mm_protect"
77+
78+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
79+
80+else
81+
82+ DO_HARDENING_PATCH_MM_PROTECT=yes
83+
84+fi
85+
86+
87+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
88+if test "${enable_hardening_patch_ll_protect+set}" = set; then
89+ enableval="$enable_hardening_patch_ll_protect"
90+
91+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
92+
93+else
94+
95+ DO_HARDENING_PATCH_LL_PROTECT=yes
96+
97+fi
98+
99+
100+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
101+if test "${enable_hardening_patch_inc_protect+set}" = set; then
102+ enableval="$enable_hardening_patch_inc_protect"
103+
104+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
105+
106+else
107+
108+ DO_HARDENING_PATCH_INC_PROTECT=yes
109+
110+fi
111+
112+
113+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
114+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
115+ enableval="$enable_hardening_patch_fmt_protect"
116+
117+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
118+
119+else
120+
121+ DO_HARDENING_PATCH_FMT_PROTECT=yes
122+
123+fi
124+
125+
126+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
127+if test "${enable_hardening_patch_hash_protect+set}" = set; then
128+ enableval="$enable_hardening_patch_hash_protect"
129+
130+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
131+
132+else
133+
134+ DO_HARDENING_PATCH_HASH_PROTECT=yes
135+
136+fi
137+
138+
139+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
140+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
141+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
142+
143+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
144+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
145+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
146+
147+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
148+echo "configure:2733: checking whether to protect include/require statements" >&5
149+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
150+
151+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
152+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
153+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
154+
155+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
156+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
157+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
158+
159+
160+cat >> confdefs.h <<\EOF
161+#define HARDENING_PATCH 1
162+EOF
163+
164+
165+
166+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
167+ cat >> confdefs.h <<\EOF
168+#define HARDENING_PATCH_MM_PROTECT 1
169+EOF
170+
171+else
172+ cat >> confdefs.h <<\EOF
173+#define HARDENING_PATCH_MM_PROTECT 0
174+EOF
175+
176+fi
177+
178+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
179+ cat >> confdefs.h <<\EOF
180+#define HARDENING_PATCH_LL_PROTECT 1
181+EOF
182+
183+else
184+ cat >> confdefs.h <<\EOF
185+#define HARDENING_PATCH_LL_PROTECT 0
186+EOF
187+
188+fi
189+
190+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
191+ cat >> confdefs.h <<\EOF
192+#define HARDENING_PATCH_INC_PROTECT 1
193+EOF
194+
195+else
196+ cat >> confdefs.h <<\EOF
197+#define HARDENING_PATCH_INC_PROTECT 0
198+EOF
199+
200+fi
201+
202+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
203+ cat >> confdefs.h <<\EOF
204+#define HARDENING_PATCH_FMT_PROTECT 1
205+EOF
206+
207+else
208+ cat >> confdefs.h <<\EOF
209+#define HARDENING_PATCH_FMT_PROTECT 0
210+EOF
211+
212+fi
213+
214+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
215+ cat >> confdefs.h <<\EOF
216+#define HARDENING_PATCH_HASH_PROTECT 1
217+EOF
218+
219+else
220+ cat >> confdefs.h <<\EOF
221+#define HARDENING_PATCH_HASH_PROTECT 0
222+EOF
223+
224+fi
225
226
227
228@@ -16017,6 +16180,62 @@
229 fi
230
231
232+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
233+echo "configure:14928: checking whether realpath is broken" >&5
234+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
235+ echo $ac_n "(cached) $ac_c" 1>&6
236+else
237+
238+ if test "$cross_compiling" = yes; then
239+
240+ ac_cv_broken_realpath=no
241+
242+else
243+ cat > conftest.$ac_ext <<EOF
244+#line 14939 "configure"
245+#include "confdefs.h"
246+
247+main() {
248+ char buf[4096+1];
249+ buf[0] = 0;
250+ realpath("/etc/hosts/../passwd", buf);
251+ exit(strcmp(buf, "/etc/passwd")==0);
252+}
253+
254+EOF
255+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
256+then
257+
258+ ac_cv_broken_realpath=no
259+
260+else
261+ echo "configure: failed program was:" >&5
262+ cat conftest.$ac_ext >&5
263+ rm -fr conftest*
264+
265+ ac_cv_broken_realpath=yes
266+
267+fi
268+rm -fr conftest*
269+fi
270+
271+
272+fi
273+
274+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
275+ if test "$ac_cv_broken_realpath" = "yes"; then
276+ cat >> confdefs.h <<\EOF
277+#define PHP_BROKEN_REALPATH 1
278+EOF
279+
280+ else
281+ cat >> confdefs.h <<\EOF
282+#define PHP_BROKEN_REALPATH 0
283+EOF
284+
285+ fi
286+
287+
288 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
289 echo "configure:16022: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -86718,7 +86937,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -87420,7 +87639,7 @@
301 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
302 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
303 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
304- var_unserializer.c ftok.c aggregation.c sha1.c ; do
305+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -87475,7 +87694,7 @@
310 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
311 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
312 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
313- var_unserializer.c ftok.c aggregation.c sha1.c ; do
314+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -87601,7 +87820,7 @@
319 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
320 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
321 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
322- var_unserializer.c ftok.c aggregation.c sha1.c ; do
323+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -87653,7 +87872,7 @@
328 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
329 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
330 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
331- var_unserializer.c ftok.c aggregation.c sha1.c ; do
332+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -91124,6 +91343,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.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" ;;
428+ *.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" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.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" ;;
474+ *.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" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(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)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.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" ;;
538+ *.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" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.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" ;;
581+ *.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" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -104088,7 +104566,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 streams.c network.c php_open_temporary_file.c php_logos.c \
606- output.c memory_streams.c user_streams.c; do
607+ output.c memory_streams.c user_streams.c hardening_patch.c; do
608
609 IFS=.
610 set $ac_src
611@@ -104273,7 +104751,7 @@
612 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
613 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
614 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
615- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
616+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.9/configure.in
621--- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100
622+++ hardening-patch-4.4.2-0.4.9/configure.in 2006-05-02 16:46:34.000000000 +0200
623@@ -247,7 +247,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -621,6 +621,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1260,7 +1261,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 streams.c network.c php_open_temporary_file.c php_logos.c \
644- output.c memory_streams.c user_streams.c)
645+ output.c memory_streams.c user_streams.c hardening_patch.c)
646 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
647 case $host_alias in
648 *netware*)
649@@ -1281,7 +1282,7 @@
650 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
654+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
658diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.9/ext/curl/curl.c
659--- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100
660+++ hardening-patch-4.4.2-0.4.9/ext/curl/curl.c 2006-05-02 16:46:34.000000000 +0200
661@@ -111,7 +111,7 @@
662
663 #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
664 if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
665- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
666+ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \
667 { \
668 php_url *tmp_url; \
669 \
670diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.9/ext/fbsql/php_fbsql.c
671--- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100
672+++ hardening-patch-4.4.2-0.4.9/ext/fbsql/php_fbsql.c 2006-05-02 16:46:34.000000000 +0200
673@@ -1797,8 +1797,24 @@
674 }
675 else if (fbcmdErrorsFound(md))
676 {
677+#if HARDENING_PATCH
678+ char* query_copy;
679+ int i;
680+#endif
681 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
682 char* emg = fbcemdAllErrorMessages(emd);
683+#if HARDENING_PATCH
684+ query_copy=estrdup(query_copy);
685+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
686+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
687+ efree(query_copy);
688+ if (HG(hphp_sql_bailout_on_error)) {
689+ free(emg);
690+ fbcemdRelease(emd);
691+ result = 0;
692+ zend_bailout();
693+ }
694+#endif
695 if (FB_SQL_G(generateWarnings))
696 {
697 if (emg)
698diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.9/ext/mbstring/mbstring.c
699--- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100
700+++ hardening-patch-4.4.2-0.4.9/ext/mbstring/mbstring.c 2006-05-02 16:46:34.000000000 +0200
701@@ -1488,6 +1488,7 @@
702 char *strtok_buf = NULL, **val_list;
703 zval *array_ptr = (zval *) arg;
704 int n, num, val_len, *len_list;
705+ unsigned int new_val_len;
706 enum mbfl_no_encoding from_encoding;
707 mbfl_string string, resvar, resval;
708 mbfl_encoding_detector *identd = NULL;
709@@ -1610,8 +1611,14 @@
710 val_len = len_list[n];
711 }
712 n++;
713- /* add variable to symbol table */
714- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
715+ /* we need val to be emalloc()ed */
716+ val = estrndup(val, val_len);
717+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
718+ /* add variable to symbol table */
719+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
720+ }
721+ efree(val);
722+
723 if (convd != NULL){
724 mbfl_string_clear(&resvar);
725 mbfl_string_clear(&resval);
726diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.9/ext/mysql/php_mysql.c
727--- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100
728+++ hardening-patch-4.4.2-0.4.9/ext/mysql/php_mysql.c 2006-05-02 16:46:34.000000000 +0200
729@@ -1218,6 +1218,8 @@
730 {
731 php_mysql_conn *mysql;
732 MYSQL_RES *mysql_result;
733+ char *copy_query;
734+ int i;
735
736 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
737
738@@ -1268,6 +1270,13 @@
739 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
740 }
741 }
742+ copy_query = estrdup(Z_STRVAL_PP(query));
743+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
744+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
745+ efree(copy_query);
746+ if (HG(hphp_sql_bailout_on_error)) {
747+ zend_bailout();
748+ }
749 RETURN_FALSE;
750 }
751 #else
752@@ -1275,12 +1284,20 @@
753 /* check possible error */
754 if (MySG(trace_mode)){
755 if (mysql_errno(&mysql->conn)){
756- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
757+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
758 }
759 }
760+ copy_query = estrdup(Z_STRVAL_PP(query));
761+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
762+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
763+ efree(copy_query);
764+ if (HG(hphp_sql_bailout_on_error)) {
765+ zend_bailout();
766+ }
767 RETURN_FALSE;
768 }
769 #endif
770+
771 if(use_store == MYSQL_USE_RESULT) {
772 mysql_result=mysql_use_result(&mysql->conn);
773 } else {
774diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.9/ext/pgsql/pgsql.c
775--- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100
776+++ hardening-patch-4.4.2-0.4.9/ext/pgsql/pgsql.c 2006-05-02 16:46:34.000000000 +0200
777@@ -1001,10 +1001,28 @@
778 case PGRES_EMPTY_QUERY:
779 case PGRES_BAD_RESPONSE:
780 case PGRES_NONFATAL_ERROR:
781- case PGRES_FATAL_ERROR:
782- PHP_PQ_ERROR("Query failed: %s", pgsql);
783- PQclear(pgsql_result);
784- RETURN_FALSE;
785+ case PGRES_FATAL_ERROR:
786+ {
787+#if HARDENING_PATCH
788+ int i;
789+ char *query_copy;
790+#endif
791+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
792+ PQclear(pgsql_result);
793+#if HARDENING_PATCH
794+ query_copy = estrdup(Z_STRVAL_PP(query));
795+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
796+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
797+ efree(query_copy);
798+ if (HG(hphp_sql_bailout_on_error)) {
799+ efree(msgbuf);
800+ zend_bailout();
801+ }
802+#endif
803+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
804+ efree(msgbuf);
805+ RETURN_FALSE;
806+ }
807 break;
808 case PGRES_COMMAND_OK: /* successful command that did not return rows */
809 default:
810diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.9/ext/session/mod_files.c
811--- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100
812+++ hardening-patch-4.4.2-0.4.9/ext/session/mod_files.c 2006-05-02 16:48:05.000000000 +0200
813@@ -16,7 +16,7 @@
814 +----------------------------------------------------------------------+
815 */
816
817-/* $Id: mod_files.c,v 1.83.2.9.2.2 2006/01/01 13:46:56 sniper Exp $ */
818+/* $Id: mod_files.c,v 1.83.2.9.2.3 2006/04/17 23:29:37 iliaa Exp $ */
819
820 #include "php.h"
821
822@@ -364,10 +364,12 @@
823 if (!ps_files_path_create(buf, sizeof(buf), data, key))
824 return FAILURE;
825
826- ps_files_close(data);
827+ if (data->fd != -1) {
828+ ps_files_close(data);
829
830- if (VCWD_UNLINK(buf) == -1) {
831- return FAILURE;
832+ if (VCWD_UNLINK(buf) == -1) {
833+ return FAILURE;
834+ }
835 }
836
837 return SUCCESS;
838@@ -389,6 +391,34 @@
839 return SUCCESS;
840 }
841
842+PS_VALIDATE_SID_FUNC(files)
843+{
844+ char buf[MAXPATHLEN];
845+ int fd;
846+ PS_FILES_DATA;
847+
848+ if (!ps_files_valid_key(key)) {
849+ return FAILURE;
850+ }
851+
852+ if (!PS(use_strict_mode)) {
853+ return SUCCESS;
854+ }
855+
856+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
857+ return FAILURE;
858+ }
859+
860+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
861+
862+ if (fd != -1) {
863+ close(fd);
864+ return SUCCESS;
865+ }
866+
867+ return FAILURE;
868+}
869+
870 /*
871 * Local variables:
872 * tab-width: 4
873diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.9/ext/session/mod_mm.c
874--- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100
875+++ hardening-patch-4.4.2-0.4.9/ext/session/mod_mm.c 2006-05-02 16:46:34.000000000 +0200
876@@ -425,6 +425,42 @@
877 return SUCCESS;
878 }
879
880+PS_VALIDATE_SID_FUNC(mm)
881+{
882+ PS_MM_DATA;
883+ ps_sd *sd;
884+ const char *p;
885+ char c;
886+ int ret = SUCCESS;
887+
888+ for (p = key; (c = *p); p++) {
889+ /* valid characters are a..z,A..Z,0..9 */
890+ if (!((c >= 'a' && c <= 'z')
891+ || (c >= 'A' && c <= 'Z')
892+ || (c >= '0' && c <= '9')
893+ || c == ','
894+ || c == '-')) {
895+ return FAILURE;
896+ }
897+ }
898+
899+ if (!PS(use_strict_mode)) {
900+ return SUCCESS;
901+ }
902+
903+ mm_lock(data->mm, MM_LOCK_RD);
904+
905+ sd = ps_sd_lookup(data, key, 0);
906+ if (sd) {
907+ mm_unlock(data->mm);
908+ return SUCCESS;
909+ }
910+
911+ mm_unlock(data->mm);
912+
913+ return FAILURE;
914+}
915+
916 #endif
917
918 /*
919diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.9/ext/session/mod_user.c
920--- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100
921+++ hardening-patch-4.4.2-0.4.9/ext/session/mod_user.c 2006-05-02 16:46:34.000000000 +0200
922@@ -23,7 +23,7 @@
923 #include "mod_user.h"
924
925 ps_module ps_mod_user = {
926- PS_MOD(user)
927+ PS_MOD_SID(user)
928 };
929
930 #define SESS_ZVAL_LONG(val, a) \
931@@ -174,6 +174,83 @@
932 FINISH;
933 }
934
935+PS_CREATE_SID_FUNC(user)
936+{
937+ int i;
938+ char *val = NULL;
939+ zval *retval;
940+ ps_user *mdata = PS_GET_MOD_DATA();
941+
942+ if (!mdata)
943+ return estrndup("", 0);
944+
945+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
946+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
947+ }
948+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
949+
950+ if (retval) {
951+ if (Z_TYPE_P(retval) == IS_STRING) {
952+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
953+ } else {
954+ val = estrndup("", 0);
955+ }
956+ zval_ptr_dtor(&retval);
957+ } else {
958+ val = estrndup("", 0);
959+ }
960+
961+ return val;
962+}
963+
964+static int ps_user_valid_key(const char *key TSRMLS_DC)
965+{
966+ size_t len;
967+ const char *p;
968+ char c;
969+ int ret = SUCCESS;
970+
971+ for (p = key; (c = *p); p++) {
972+ /* valid characters are a..z,A..Z,0..9 */
973+ if (!((c >= 'a' && c <= 'z')
974+ || (c >= 'A' && c <= 'Z')
975+ || (c >= '0' && c <= '9')
976+ || c == ','
977+ || c == '-')) {
978+ ret = FAILURE;
979+ break;
980+ }
981+ }
982+
983+ len = p - key;
984+
985+ if (len == 0)
986+ ret = FAILURE;
987+
988+ return ret;
989+}
990+
991+PS_VALIDATE_SID_FUNC(user)
992+{
993+ zval *args[1];
994+ STDVARS;
995+
996+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
997+ return ps_user_valid_key(key TSRMLS_CC);
998+ }
999+ SESS_ZVAL_STRING(key, args[0]);
1000+
1001+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1002+
1003+ if (retval) {
1004+ convert_to_long(retval);
1005+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1006+ zval_ptr_dtor(&retval);
1007+ }
1008+
1009+ return ret;
1010+}
1011+
1012 /*
1013 * Local variables:
1014 * tab-width: 4
1015diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.9/ext/session/mod_user.h
1016--- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100
1017+++ hardening-patch-4.4.2-0.4.9/ext/session/mod_user.h 2006-05-02 16:46:34.000000000 +0200
1018@@ -22,7 +22,7 @@
1019 #define MOD_USER_H
1020
1021 typedef union {
1022- zval *names[6];
1023+ zval *names[8];
1024 struct {
1025 zval *ps_open;
1026 zval *ps_close;
1027@@ -30,6 +30,8 @@
1028 zval *ps_write;
1029 zval *ps_destroy;
1030 zval *ps_gc;
1031+ zval *ps_create;
1032+ zval *ps_validate;
1033 } name;
1034 } ps_user;
1035
1036diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.9/ext/session/php_session.h
1037--- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100
1038+++ hardening-patch-4.4.2-0.4.9/ext/session/php_session.h 2006-05-02 16:46:34.000000000 +0200
1039@@ -23,7 +23,7 @@
1040
1041 #include "ext/standard/php_var.h"
1042
1043-#define PHP_SESSION_API 20020330
1044+#define PHP_SESSION_API 20051121
1045
1046 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1047 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1048@@ -32,6 +32,7 @@
1049 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1050 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1051 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1052+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1053
1054 /* default create id function */
1055 char *php_session_create_id(PS_CREATE_SID_ARGS);
1056@@ -45,6 +46,7 @@
1057 int (*s_destroy)(PS_DESTROY_ARGS);
1058 int (*s_gc)(PS_GC_ARGS);
1059 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1060+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1061 } ps_module;
1062
1063 #define PS_GET_MOD_DATA() *mod_data
1064@@ -57,6 +59,7 @@
1065 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1066 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1067 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1068+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1069
1070 #define PS_FUNCS(x) \
1071 PS_OPEN_FUNC(x); \
1072@@ -65,11 +68,12 @@
1073 PS_WRITE_FUNC(x); \
1074 PS_DESTROY_FUNC(x); \
1075 PS_GC_FUNC(x); \
1076- PS_CREATE_SID_FUNC(x)
1077+ PS_CREATE_SID_FUNC(x); \
1078+ PS_VALIDATE_SID_FUNC(x)
1079
1080 #define PS_MOD(x) \
1081 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1082- ps_delete_##x, ps_gc_##x, php_session_create_id
1083+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1084
1085 /* SID enabled module handler definitions */
1086 #define PS_FUNCS_SID(x) \
1087@@ -79,11 +83,12 @@
1088 PS_WRITE_FUNC(x); \
1089 PS_DESTROY_FUNC(x); \
1090 PS_GC_FUNC(x); \
1091- PS_CREATE_SID_FUNC(x)
1092+ PS_CREATE_SID_FUNC(x); \
1093+ PS_VALIDATE_SID(x)
1094
1095 #define PS_MOD_SID(x) \
1096 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1097- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1098+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1099
1100 typedef enum {
1101 php_session_disabled,
1102@@ -120,6 +125,7 @@
1103 zend_bool use_only_cookies;
1104 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1105 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1106+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1107 int send_cookie;
1108 int define_sid;
1109 } php_ps_globals;
1110diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.9/ext/session/session.c
1111--- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100
1112+++ hardening-patch-4.4.2-0.4.9/ext/session/session.c 2006-05-02 16:48:19.000000000 +0200
1113@@ -17,7 +17,7 @@
1114 +----------------------------------------------------------------------+
1115 */
1116
1117-/* $Id: session.c,v 1.336.2.53.2.4 2006/01/01 13:46:56 sniper Exp $ */
1118+/* $Id: session.c,v 1.336.2.53.2.5 2006/01/15 16:52:10 iliaa Exp $ */
1119
1120 #ifdef HAVE_CONFIG_H
1121 #include "config.h"
1122@@ -155,6 +155,7 @@
1123 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1124 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1125 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1126+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1127 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1128 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1129 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1130@@ -626,6 +627,12 @@
1131 char *val;
1132 int vallen;
1133
1134+ /* check session name for invalid characters */
1135+ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
1136+ efree(PS(id));
1137+ PS(id) = NULL;
1138+ }
1139+
1140 if (!PS(mod)) {
1141 php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session.");
1142 return;
1143@@ -637,6 +644,15 @@
1144 return;
1145 }
1146
1147+ /* If there is an ID, use session module to verify it */
1148+ if (PS(id)) {
1149+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1150+ efree(PS(id));
1151+ PS(id) = NULL;
1152+ PS(send_cookie) = 1;
1153+ }
1154+ }
1155+
1156 /* If there is no ID, use session module to create one */
1157 if (!PS(id))
1158 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1159@@ -1256,22 +1272,31 @@
1160 }
1161 /* }}} */
1162
1163-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1164+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1165 Sets user-level functions */
1166 PHP_FUNCTION(session_set_save_handler)
1167 {
1168- zval **args[6];
1169- int i;
1170+ zval **args[8];
1171+ int i, numargs;
1172 ps_user *mdata;
1173 char *name;
1174
1175+ numargs = ZEND_NUM_ARGS();
1176+ args[6] = NULL;
1177+ args[7] = NULL;
1178+
1179+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1180+ WRONG_PARAM_COUNT;
1181 if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1182 WRONG_PARAM_COUNT;
1183
1184 if (PS(session_status) != php_session_none)
1185 RETURN_FALSE;
1186
1187- for (i = 0; i < 6; i++) {
1188+ for (i = 0; i < 8; i++) {
1189+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1190+ continue;
1191+ }
1192 if (!zend_is_callable(*args[i], 0, &name)) {
1193 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1194 efree(name);
1195@@ -1284,7 +1309,11 @@
1196
1197 mdata = emalloc(sizeof(*mdata));
1198
1199- for (i = 0; i < 6; i++) {
1200+ for (i = 0; i < 8; i++) {
1201+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1202+ mdata->names[i] = NULL;
1203+ continue;
1204+ }
1205 ZVAL_ADDREF(*args[i]);
1206 mdata->names[i] = *args[i];
1207 }
1208@@ -1345,8 +1374,20 @@
1209 Update the current session id with a newly generated one. */
1210 PHP_FUNCTION(session_regenerate_id)
1211 {
1212+ zend_bool del_ses = 0;
1213+
1214+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1215+ WRONG_PARAM_COUNT;
1216+ }
1217+
1218 if (PS(session_status) == php_session_active) {
1219- if (PS(id)) efree(PS(id));
1220+ if (PS(id)) {
1221+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1222+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1223+ RETURN_FALSE;
1224+ }
1225+ efree(PS(id));
1226+ }
1227
1228 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1229
1230diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.9/ext/session/tests/014.phpt
1231--- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1232+++ hardening-patch-4.4.2-0.4.9/ext/session/tests/014.phpt 2006-05-02 16:46:34.000000000 +0200
1233@@ -5,6 +5,7 @@
1234 --INI--
1235 session.use_trans_sid=1
1236 session.use_cookies=0
1237+session.use_strict_mode=0
1238 session.cache_limiter=
1239 register_globals=1
1240 session.bug_compat_42=1
1241diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.9/ext/session/tests/015.phpt
1242--- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1243+++ hardening-patch-4.4.2-0.4.9/ext/session/tests/015.phpt 2006-05-02 16:46:34.000000000 +0200
1244@@ -5,6 +5,7 @@
1245 --INI--
1246 session.use_trans_sid=1
1247 session.use_cookies=0
1248+session.use_strict_mode=0
1249 session.cache_limiter=
1250 arg_separator.output=&
1251 session.name=PHPSESSID
1252diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.9/ext/session/tests/018.phpt
1253--- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1254+++ hardening-patch-4.4.2-0.4.9/ext/session/tests/018.phpt 2006-05-02 16:46:34.000000000 +0200
1255@@ -4,6 +4,7 @@
1256 <?php include('skipif.inc'); ?>
1257 --INI--
1258 session.use_cookies=0
1259+session.use_strict_mode=0
1260 session.cache_limiter=
1261 session.use_trans_sid=1
1262 session.name=PHPSESSID
1263diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.9/ext/session/tests/020.phpt
1264--- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1265+++ hardening-patch-4.4.2-0.4.9/ext/session/tests/020.phpt 2006-05-02 16:46:34.000000000 +0200
1266@@ -4,6 +4,7 @@
1267 <?php include('skipif.inc'); ?>
1268 --INI--
1269 session.use_cookies=0
1270+session.use_strict_mode=0
1271 session.cache_limiter=
1272 session.use_trans_sid=1
1273 arg_separator.output=&amp;
1274diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.9/ext/session/tests/021.phpt
1275--- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1276+++ hardening-patch-4.4.2-0.4.9/ext/session/tests/021.phpt 2006-05-02 16:46:34.000000000 +0200
1277@@ -4,6 +4,7 @@
1278 <?php include('skipif.inc'); ?>
1279 --INI--
1280 session.use_cookies=0
1281+session.use_strict_mode=0
1282 session.cache_limiter=
1283 session.use_trans_sid=1
1284 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1285diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.9/ext/standard/array.c
1286--- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100
1287+++ hardening-patch-4.4.2-0.4.9/ext/standard/array.c 2006-05-02 16:46:34.000000000 +0200
1288@@ -1162,6 +1162,32 @@
1289 }
1290 }
1291 }
1292+
1293+ if (var_name[0] == 'H') {
1294+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1295+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1296+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1297+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1298+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1299+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1300+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1301+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1302+ return 0;
1303+ }
1304+ } else if (var_name[0] == '_') {
1305+ if ((strcmp(var_name, "_COOKIE")==0)||
1306+ (strcmp(var_name, "_ENV")==0)||
1307+ (strcmp(var_name, "_FILES")==0)||
1308+ (strcmp(var_name, "_GET")==0)||
1309+ (strcmp(var_name, "_POST")==0)||
1310+ (strcmp(var_name, "_REQUEST")==0)||
1311+ (strcmp(var_name, "_SESSION")==0)||
1312+ (strcmp(var_name, "_SERVER")==0)) {
1313+ return 0;
1314+ }
1315+ } else if (strcmp(var_name, "GLOBALS")==0) {
1316+ return 0;
1317+ }
1318
1319 return 1;
1320 }
1321diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.9/ext/standard/basic_functions.c
1322--- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100
1323+++ hardening-patch-4.4.2-0.4.9/ext/standard/basic_functions.c 2006-05-02 16:46:34.000000000 +0200
1324@@ -107,12 +107,14 @@
1325 typedef struct _php_shutdown_function_entry {
1326 zval **arguments;
1327 int arg_count;
1328+ zend_bool created_by_eval;
1329 } php_shutdown_function_entry;
1330
1331 typedef struct _user_tick_function_entry {
1332 zval **arguments;
1333 int arg_count;
1334 int calling;
1335+ zend_bool created_by_eval;
1336 } user_tick_function_entry;
1337
1338 /* some prototypes for local functions */
1339@@ -295,6 +297,8 @@
1340 PHP_FE(get_html_translation_table, NULL)
1341 PHP_FE(sha1, NULL)
1342 PHP_FE(sha1_file, NULL)
1343+ PHP_FE(sha256, NULL)
1344+ PHP_FE(sha256_file, NULL)
1345 PHP_NAMED_FE(md5,php_if_md5, NULL)
1346 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1347 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1348@@ -676,7 +680,7 @@
1349 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1350
1351 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1352- PHP_FE(realpath, NULL)
1353+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1354 #endif
1355
1356 #ifdef HAVE_FNMATCH
1357@@ -2096,6 +2100,13 @@
1358 {
1359 zval retval;
1360 char *function_name = NULL;
1361+#if HARDENING_PATCH
1362+ zend_uint orig_code_type = EG(in_code_type);
1363+
1364+ if (shutdown_function_entry->created_by_eval) {
1365+ EG(in_code_type) = ZEND_EVAL_CODE;
1366+ }
1367+#endif
1368
1369 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1370 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1371@@ -2111,6 +2122,9 @@
1372 if (function_name) {
1373 efree(function_name);
1374 }
1375+#if HARDENING_PATCH
1376+ EG(in_code_type) = orig_code_type;
1377+#endif
1378 return 0;
1379 }
1380
1381@@ -2118,6 +2132,13 @@
1382 {
1383 zval retval;
1384 zval *function = tick_fe->arguments[0];
1385+#if HARDENING_PATCH
1386+ zend_uint orig_code_type = EG(in_code_type);
1387+
1388+ if (tick_fe->created_by_eval) {
1389+ EG(in_code_type) = ZEND_EVAL_CODE;
1390+ }
1391+#endif
1392
1393 /* Prevent reentrant calls to the same user ticks function */
1394 if (! tick_fe->calling) {
1395@@ -2149,6 +2170,9 @@
1396
1397 tick_fe->calling = 0;
1398 }
1399+#if HARDENING_PATCH
1400+ EG(in_code_type) = orig_code_type;
1401+#endif
1402 }
1403
1404 static void run_user_tick_functions(int tick_count)
1405@@ -2216,6 +2240,13 @@
1406 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1407 RETURN_FALSE;
1408 }
1409+#if HARDENING_PATCH
1410+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1411+ shutdown_function_entry.created_by_eval = 1;
1412+ } else {
1413+ shutdown_function_entry.created_by_eval = 0;
1414+ }
1415+#endif
1416
1417 /* Prevent entering of anything but valid callback (syntax check only!) */
1418 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1419@@ -2753,6 +2784,13 @@
1420 }
1421
1422 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1423+#if HARDENING_PATCH
1424+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1425+ tick_fe.created_by_eval = 1;
1426+ } else {
1427+ tick_fe.created_by_eval = 0;
1428+ }
1429+#endif
1430
1431 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1432 RETURN_FALSE;
1433@@ -3050,6 +3088,35 @@
1434 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1435 }
1436
1437+ if (new_key[0] == 'H') {
1438+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1439+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1440+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1441+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1442+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1443+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1444+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1445+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1446+ efree(new_key);
1447+ return 0;
1448+ }
1449+ } else if (new_key[0] == '_') {
1450+ if ((strcmp(new_key, "_COOKIE")==0)||
1451+ (strcmp(new_key, "_ENV")==0)||
1452+ (strcmp(new_key, "_FILES")==0)||
1453+ (strcmp(new_key, "_GET")==0)||
1454+ (strcmp(new_key, "_POST")==0)||
1455+ (strcmp(new_key, "_REQUEST")==0)||
1456+ (strcmp(new_key, "_SESSION")==0)||
1457+ (strcmp(new_key, "_SERVER")==0)) {
1458+ efree(new_key);
1459+ return 0;
1460+ }
1461+ } else if (strcmp(new_key, "GLOBALS")==0) {
1462+ efree(new_key);
1463+ return 0;
1464+ }
1465+
1466 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1467 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1468
1469diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.9/ext/standard/config.m4
1470--- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1471+++ hardening-patch-4.4.2-0.4.9/ext/standard/config.m4 2006-05-02 16:46:34.000000000 +0200
1472@@ -203,7 +203,7 @@
1473 if test "$ac_cv_crypt_blowfish" = "yes"; then
1474 ac_result=1
1475 else
1476- ac_result=0
1477+ ac_result=1
1478 fi
1479 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1480 ])
1481@@ -419,6 +419,6 @@
1482 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1483 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1484 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1485- var_unserializer.c ftok.c aggregation.c sha1.c )
1486+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1487
1488 PHP_ADD_MAKEFILE_FRAGMENT
1489diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.9/ext/standard/crypt_blowfish.c
1490--- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1491+++ hardening-patch-4.4.2-0.4.9/ext/standard/crypt_blowfish.c 2006-05-02 16:46:34.000000000 +0200
1492@@ -0,0 +1,748 @@
1493+/*
1494+ * This code comes from John the Ripper password cracker, with reentrant
1495+ * and crypt(3) interfaces added, but optimizations specific to password
1496+ * cracking removed.
1497+ *
1498+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1499+ * placed in the public domain.
1500+ *
1501+ * There's absolutely no warranty.
1502+ *
1503+ * It is my intent that you should be able to use this on your system,
1504+ * as a part of a software package, or anywhere else to improve security,
1505+ * ensure compatibility, or for any other purpose. I would appreciate
1506+ * it if you give credit where it is due and keep your modifications in
1507+ * the public domain as well, but I don't require that in order to let
1508+ * you place this code and any modifications you make under a license
1509+ * of your choice.
1510+ *
1511+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1512+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1513+ * ideas. The password hashing algorithm was designed by David Mazieres
1514+ * <dm at lcs.mit.edu>.
1515+ *
1516+ * There's a paper on the algorithm that explains its design decisions:
1517+ *
1518+ * http://www.usenix.org/events/usenix99/provos.html
1519+ *
1520+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1521+ * Blowfish library (I can't be sure if I would think of something if I
1522+ * hadn't seen his code).
1523+ */
1524+
1525+#include <string.h>
1526+
1527+#include <errno.h>
1528+#ifndef __set_errno
1529+#define __set_errno(val) errno = (val)
1530+#endif
1531+
1532+#undef __CONST
1533+#ifdef __GNUC__
1534+#define __CONST __const
1535+#else
1536+#define __CONST
1537+#endif
1538+
1539+#ifdef __i386__
1540+#define BF_ASM 0
1541+#define BF_SCALE 1
1542+#elif defined(__alpha__) || defined(__hppa__)
1543+#define BF_ASM 0
1544+#define BF_SCALE 1
1545+#else
1546+#define BF_ASM 0
1547+#define BF_SCALE 0
1548+#endif
1549+
1550+typedef unsigned int BF_word;
1551+
1552+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1553+#define BF_N 16
1554+
1555+typedef BF_word BF_key[BF_N + 2];
1556+
1557+typedef struct {
1558+ BF_word S[4][0x100];
1559+ BF_key P;
1560+} BF_ctx;
1561+
1562+/*
1563+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1564+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1565+ */
1566+static BF_word BF_magic_w[6] = {
1567+ 0x4F727068, 0x65616E42, 0x65686F6C,
1568+ 0x64657253, 0x63727944, 0x6F756274
1569+};
1570+
1571+/*
1572+ * P-box and S-box tables initialized with digits of Pi.
1573+ */
1574+static BF_ctx BF_init_state = {
1575+ {
1576+ {
1577+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1578+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1579+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1580+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1581+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1582+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1583+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1584+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1585+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1586+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1587+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1588+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1589+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1590+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1591+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1592+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1593+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1594+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1595+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1596+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1597+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1598+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1599+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1600+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1601+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1602+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1603+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1604+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1605+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1606+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1607+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1608+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1609+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1610+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1611+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1612+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1613+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1614+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1615+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1616+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1617+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1618+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1619+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1620+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1621+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1622+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1623+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1624+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1625+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1626+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1627+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1628+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1629+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1630+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1631+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1632+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1633+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1634+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1635+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1636+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1637+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1638+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1639+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1640+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1641+ }, {
1642+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1643+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1644+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1645+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1646+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1647+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1648+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1649+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1650+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1651+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1652+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1653+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1654+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1655+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1656+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1657+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1658+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1659+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1660+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1661+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1662+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1663+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1664+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1665+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1666+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1667+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1668+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1669+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1670+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1671+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1672+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1673+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1674+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1675+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1676+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1677+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1678+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1679+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1680+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1681+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1682+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1683+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1684+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1685+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1686+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1687+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1688+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1689+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1690+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1691+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1692+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1693+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1694+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1695+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1696+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1697+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1698+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1699+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1700+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1701+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1702+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1703+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1704+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1705+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1706+ }, {
1707+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1708+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1709+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1710+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1711+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1712+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1713+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1714+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1715+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1716+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1717+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1718+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1719+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1720+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1721+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1722+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1723+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1724+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1725+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1726+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1727+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1728+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1729+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1730+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1731+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1732+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1733+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1734+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1735+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1736+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1737+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1738+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1739+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1740+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1741+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1742+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1743+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1744+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1745+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1746+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1747+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1748+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1749+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1750+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1751+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1752+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1753+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1754+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1755+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1756+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1757+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1758+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1759+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1760+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1761+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1762+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1763+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1764+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1765+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1766+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1767+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1768+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1769+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1770+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1771+ }, {
1772+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1773+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1774+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1775+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1776+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1777+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1778+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1779+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1780+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1781+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1782+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1783+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1784+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1785+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1786+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1787+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1788+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1789+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1790+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1791+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1792+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1793+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1794+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1795+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1796+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1797+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1798+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1799+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1800+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1801+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1802+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1803+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1804+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1805+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1806+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1807+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1808+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1809+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1810+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1811+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1812+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1813+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1814+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1815+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1816+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1817+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1818+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1819+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1820+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1821+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1822+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1823+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1824+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1825+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1826+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1827+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1828+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1829+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1830+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1831+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1832+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1833+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1834+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1835+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1836+ }
1837+ }, {
1838+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1839+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1840+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1841+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1842+ 0x9216d5d9, 0x8979fb1b
1843+ }
1844+};
1845+
1846+static unsigned char BF_itoa64[64 + 1] =
1847+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1848+
1849+static unsigned char BF_atoi64[0x60] = {
1850+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1851+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1852+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1853+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1854+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1855+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1856+};
1857+
1858+/*
1859+ * This may be optimized out if built with function inlining and no BF_ASM.
1860+ */
1861+static void clean(void *data, int size)
1862+{
1863+#if BF_ASM
1864+ extern void _BF_clean(void *data);
1865+#endif
1866+ memset(data, 0, size);
1867+#if BF_ASM
1868+ _BF_clean(data);
1869+#endif
1870+}
1871+
1872+#define BF_safe_atoi64(dst, src) \
1873+{ \
1874+ tmp = (unsigned char)(src); \
1875+ if (tmp == '$') break; \
1876+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1877+ tmp = BF_atoi64[tmp]; \
1878+ if (tmp > 63) return -1; \
1879+ (dst) = tmp; \
1880+}
1881+
1882+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1883+{
1884+ unsigned char *dptr = (unsigned char *)dst;
1885+ unsigned char *end = dptr + size;
1886+ unsigned char *sptr = (unsigned char *)src;
1887+ unsigned int tmp, c1, c2, c3, c4;
1888+
1889+ do {
1890+ BF_safe_atoi64(c1, *sptr++);
1891+ BF_safe_atoi64(c2, *sptr++);
1892+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1893+ if (dptr >= end) break;
1894+
1895+ BF_safe_atoi64(c3, *sptr++);
1896+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1897+ if (dptr >= end) break;
1898+
1899+ BF_safe_atoi64(c4, *sptr++);
1900+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1901+ } while (dptr < end);
1902+
1903+ while (dptr < end)
1904+ *dptr++ = 0;
1905+
1906+ return 0;
1907+}
1908+
1909+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1910+{
1911+ unsigned char *sptr = (unsigned char *)src;
1912+ unsigned char *end = sptr + size;
1913+ unsigned char *dptr = (unsigned char *)dst;
1914+ unsigned int c1, c2;
1915+
1916+ do {
1917+ c1 = *sptr++;
1918+ *dptr++ = BF_itoa64[c1 >> 2];
1919+ c1 = (c1 & 0x03) << 4;
1920+ if (sptr >= end) {
1921+ *dptr++ = BF_itoa64[c1];
1922+ break;
1923+ }
1924+
1925+ c2 = *sptr++;
1926+ c1 |= c2 >> 4;
1927+ *dptr++ = BF_itoa64[c1];
1928+ c1 = (c2 & 0x0f) << 2;
1929+ if (sptr >= end) {
1930+ *dptr++ = BF_itoa64[c1];
1931+ break;
1932+ }
1933+
1934+ c2 = *sptr++;
1935+ c1 |= c2 >> 6;
1936+ *dptr++ = BF_itoa64[c1];
1937+ *dptr++ = BF_itoa64[c2 & 0x3f];
1938+ } while (sptr < end);
1939+}
1940+
1941+static void BF_swap(BF_word *x, int count)
1942+{
1943+ static int endianness_check = 1;
1944+ char *is_little_endian = (char *)&endianness_check;
1945+ BF_word tmp;
1946+
1947+ if (*is_little_endian)
1948+ do {
1949+ tmp = *x;
1950+ tmp = (tmp << 16) | (tmp >> 16);
1951+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1952+ } while (--count);
1953+}
1954+
1955+#if BF_SCALE
1956+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1957+#define BF_ROUND(L, R, N) \
1958+ tmp1 = L & 0xFF; \
1959+ tmp2 = L >> 8; \
1960+ tmp2 &= 0xFF; \
1961+ tmp3 = L >> 16; \
1962+ tmp3 &= 0xFF; \
1963+ tmp4 = L >> 24; \
1964+ tmp1 = data.ctx.S[3][tmp1]; \
1965+ tmp2 = data.ctx.S[2][tmp2]; \
1966+ tmp3 = data.ctx.S[1][tmp3]; \
1967+ tmp3 += data.ctx.S[0][tmp4]; \
1968+ tmp3 ^= tmp2; \
1969+ R ^= data.ctx.P[N + 1]; \
1970+ tmp3 += tmp1; \
1971+ R ^= tmp3;
1972+#else
1973+/* Architectures with no complicated addressing modes supported */
1974+#define BF_INDEX(S, i) \
1975+ (*((BF_word *)(((unsigned char *)S) + (i))))
1976+#define BF_ROUND(L, R, N) \
1977+ tmp1 = L & 0xFF; \
1978+ tmp1 <<= 2; \
1979+ tmp2 = L >> 6; \
1980+ tmp2 &= 0x3FC; \
1981+ tmp3 = L >> 14; \
1982+ tmp3 &= 0x3FC; \
1983+ tmp4 = L >> 22; \
1984+ tmp4 &= 0x3FC; \
1985+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1986+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1987+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1988+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1989+ tmp3 ^= tmp2; \
1990+ R ^= data.ctx.P[N + 1]; \
1991+ tmp3 += tmp1; \
1992+ R ^= tmp3;
1993+#endif
1994+
1995+/*
1996+ * Encrypt one block, BF_N is hardcoded here.
1997+ */
1998+#define BF_ENCRYPT \
1999+ L ^= data.ctx.P[0]; \
2000+ BF_ROUND(L, R, 0); \
2001+ BF_ROUND(R, L, 1); \
2002+ BF_ROUND(L, R, 2); \
2003+ BF_ROUND(R, L, 3); \
2004+ BF_ROUND(L, R, 4); \
2005+ BF_ROUND(R, L, 5); \
2006+ BF_ROUND(L, R, 6); \
2007+ BF_ROUND(R, L, 7); \
2008+ BF_ROUND(L, R, 8); \
2009+ BF_ROUND(R, L, 9); \
2010+ BF_ROUND(L, R, 10); \
2011+ BF_ROUND(R, L, 11); \
2012+ BF_ROUND(L, R, 12); \
2013+ BF_ROUND(R, L, 13); \
2014+ BF_ROUND(L, R, 14); \
2015+ BF_ROUND(R, L, 15); \
2016+ tmp4 = R; \
2017+ R = L; \
2018+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2019+
2020+#if BF_ASM
2021+#define BF_body() \
2022+ _BF_body_r(&data.ctx);
2023+#else
2024+#define BF_body() \
2025+ L = R = 0; \
2026+ ptr = data.ctx.P; \
2027+ do { \
2028+ ptr += 2; \
2029+ BF_ENCRYPT; \
2030+ *(ptr - 2) = L; \
2031+ *(ptr - 1) = R; \
2032+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2033+\
2034+ ptr = data.ctx.S[0]; \
2035+ do { \
2036+ ptr += 2; \
2037+ BF_ENCRYPT; \
2038+ *(ptr - 2) = L; \
2039+ *(ptr - 1) = R; \
2040+ } while (ptr < &data.ctx.S[3][0xFF]);
2041+#endif
2042+
2043+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2044+{
2045+ __CONST char *ptr = key;
2046+ int i, j;
2047+ BF_word tmp;
2048+
2049+ for (i = 0; i < BF_N + 2; i++) {
2050+ tmp = 0;
2051+ for (j = 0; j < 4; j++) {
2052+ tmp <<= 8;
2053+ tmp |= *ptr;
2054+
2055+ if (!*ptr) ptr = key; else ptr++;
2056+ }
2057+
2058+ expanded[i] = tmp;
2059+ initial[i] = BF_init_state.P[i] ^ tmp;
2060+ }
2061+}
2062+
2063+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2064+ char *output, int size)
2065+{
2066+#if BF_ASM
2067+ extern void _BF_body_r(BF_ctx *ctx);
2068+#endif
2069+ struct {
2070+ BF_ctx ctx;
2071+ BF_key expanded_key;
2072+ union {
2073+ BF_word salt[4];
2074+ BF_word output[6];
2075+ } binary;
2076+ } data;
2077+ BF_word L, R;
2078+ BF_word tmp1, tmp2, tmp3, tmp4;
2079+ BF_word *ptr;
2080+ BF_word count;
2081+ int i;
2082+
2083+ if (size < 7 + 22 + 31 + 1) {
2084+ __set_errno(ERANGE);
2085+ return NULL;
2086+ }
2087+
2088+ if (setting[0] != '$' ||
2089+ setting[1] != '2' ||
2090+ setting[2] != 'a' ||
2091+ setting[3] != '$' ||
2092+ setting[4] < '0' || setting[4] > '3' ||
2093+ setting[5] < '0' || setting[5] > '9' ||
2094+ setting[6] != '$') {
2095+ __set_errno(EINVAL);
2096+ return NULL;
2097+ }
2098+
2099+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2100+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2101+ clean(data.binary.salt, sizeof(data.binary.salt));
2102+ __set_errno(EINVAL);
2103+ return NULL;
2104+ }
2105+
2106+ BF_swap(data.binary.salt, 4);
2107+
2108+ BF_set_key(key, data.expanded_key, data.ctx.P);
2109+
2110+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2111+
2112+ L = R = 0;
2113+ for (i = 0; i < BF_N + 2; i += 2) {
2114+ L ^= data.binary.salt[i & 2];
2115+ R ^= data.binary.salt[(i & 2) + 1];
2116+ BF_ENCRYPT;
2117+ data.ctx.P[i] = L;
2118+ data.ctx.P[i + 1] = R;
2119+ }
2120+
2121+ ptr = data.ctx.S[0];
2122+ do {
2123+ ptr += 4;
2124+ L ^= data.binary.salt[(BF_N + 2) & 3];
2125+ R ^= data.binary.salt[(BF_N + 3) & 3];
2126+ BF_ENCRYPT;
2127+ *(ptr - 4) = L;
2128+ *(ptr - 3) = R;
2129+
2130+ L ^= data.binary.salt[(BF_N + 4) & 3];
2131+ R ^= data.binary.salt[(BF_N + 5) & 3];
2132+ BF_ENCRYPT;
2133+ *(ptr - 2) = L;
2134+ *(ptr - 1) = R;
2135+ } while (ptr < &data.ctx.S[3][0xFF]);
2136+
2137+ do {
2138+ data.ctx.P[0] ^= data.expanded_key[0];
2139+ data.ctx.P[1] ^= data.expanded_key[1];
2140+ data.ctx.P[2] ^= data.expanded_key[2];
2141+ data.ctx.P[3] ^= data.expanded_key[3];
2142+ data.ctx.P[4] ^= data.expanded_key[4];
2143+ data.ctx.P[5] ^= data.expanded_key[5];
2144+ data.ctx.P[6] ^= data.expanded_key[6];
2145+ data.ctx.P[7] ^= data.expanded_key[7];
2146+ data.ctx.P[8] ^= data.expanded_key[8];
2147+ data.ctx.P[9] ^= data.expanded_key[9];
2148+ data.ctx.P[10] ^= data.expanded_key[10];
2149+ data.ctx.P[11] ^= data.expanded_key[11];
2150+ data.ctx.P[12] ^= data.expanded_key[12];
2151+ data.ctx.P[13] ^= data.expanded_key[13];
2152+ data.ctx.P[14] ^= data.expanded_key[14];
2153+ data.ctx.P[15] ^= data.expanded_key[15];
2154+ data.ctx.P[16] ^= data.expanded_key[16];
2155+ data.ctx.P[17] ^= data.expanded_key[17];
2156+
2157+ BF_body();
2158+
2159+ tmp1 = data.binary.salt[0];
2160+ tmp2 = data.binary.salt[1];
2161+ tmp3 = data.binary.salt[2];
2162+ tmp4 = data.binary.salt[3];
2163+ data.ctx.P[0] ^= tmp1;
2164+ data.ctx.P[1] ^= tmp2;
2165+ data.ctx.P[2] ^= tmp3;
2166+ data.ctx.P[3] ^= tmp4;
2167+ data.ctx.P[4] ^= tmp1;
2168+ data.ctx.P[5] ^= tmp2;
2169+ data.ctx.P[6] ^= tmp3;
2170+ data.ctx.P[7] ^= tmp4;
2171+ data.ctx.P[8] ^= tmp1;
2172+ data.ctx.P[9] ^= tmp2;
2173+ data.ctx.P[10] ^= tmp3;
2174+ data.ctx.P[11] ^= tmp4;
2175+ data.ctx.P[12] ^= tmp1;
2176+ data.ctx.P[13] ^= tmp2;
2177+ data.ctx.P[14] ^= tmp3;
2178+ data.ctx.P[15] ^= tmp4;
2179+ data.ctx.P[16] ^= tmp1;
2180+ data.ctx.P[17] ^= tmp2;
2181+
2182+ BF_body();
2183+ } while (--count);
2184+
2185+ for (i = 0; i < 6; i += 2) {
2186+ L = BF_magic_w[i];
2187+ R = BF_magic_w[i + 1];
2188+
2189+ count = 64;
2190+ do {
2191+ BF_ENCRYPT;
2192+ } while (--count);
2193+
2194+ data.binary.output[i] = L;
2195+ data.binary.output[i + 1] = R;
2196+ }
2197+
2198+ memcpy(output, setting, 7 + 22 - 1);
2199+ output[7 + 22 - 1] = BF_itoa64[(int)
2200+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2201+
2202+/* This has to be bug-compatible with the original implementation, so
2203+ * only encode 23 of the 24 bytes. :-) */
2204+ BF_swap(data.binary.output, 6);
2205+ BF_encode(&output[7 + 22], data.binary.output, 23);
2206+ output[7 + 22 + 31] = '\0';
2207+
2208+/* Overwrite the most obvious sensitive data we have on the stack. Note
2209+ * that this does not guarantee there's no sensitive data left on the
2210+ * stack and/or in registers; I'm not aware of portable code that does. */
2211+ clean(&data, sizeof(data));
2212+
2213+ return output;
2214+}
2215+
2216+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2217+ __CONST char *input, int size, char *output, int output_size)
2218+{
2219+ if (size < 16 || output_size < 7 + 22 + 1 ||
2220+ (count && (count < 4 || count > 31))) {
2221+ if (output_size > 0) output[0] = '\0';
2222+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2223+ return NULL;
2224+ }
2225+
2226+ if (!count) count = 5;
2227+
2228+ output[0] = '$';
2229+ output[1] = '2';
2230+ output[2] = 'a';
2231+ output[3] = '$';
2232+ output[4] = '0' + count / 10;
2233+ output[5] = '0' + count % 10;
2234+ output[6] = '$';
2235+
2236+ BF_encode(&output[7], (BF_word *)input, 16);
2237+ output[7 + 22] = '\0';
2238+
2239+ return output;
2240+}
2241diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.9/ext/standard/crypt.c
2242--- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100
2243+++ hardening-patch-4.4.2-0.4.9/ext/standard/crypt.c 2006-05-02 16:46:34.000000000 +0200
2244@@ -100,6 +100,8 @@
2245 return SUCCESS;
2246 }
2247
2248+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2249+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2250
2251 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2252
2253@@ -135,7 +137,14 @@
2254
2255 /* The automatic salt generation only covers standard DES and md5-crypt */
2256 if(!*salt) {
2257-#if PHP_MD5_CRYPT
2258+#if PHP_BLOWFISH_CRYPT
2259+ char randat[16];
2260+ int i;
2261+
2262+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2263+
2264+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2265+#elif PHP_MD5_CRYPT
2266 strcpy(salt, "$1$");
2267 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2268 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2269@@ -145,8 +154,24 @@
2270 salt[2] = '\0';
2271 #endif
2272 }
2273-
2274- RETVAL_STRING(crypt(str, salt), 1);
2275+
2276+ if (salt[0] == '$' &&
2277+ salt[1] == '2' &&
2278+ salt[2] == 'a' &&
2279+ salt[3] == '$' &&
2280+ salt[4] >= '0' && salt[4] <= '3' &&
2281+ salt[5] >= '0' && salt[5] <= '9' &&
2282+ salt[6] == '$') {
2283+
2284+ char output[PHP_MAX_SALT_LEN+1];
2285+
2286+ output[0] = 0;
2287+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2288+ RETVAL_STRING(output, 1);
2289+
2290+ } else {
2291+ RETVAL_STRING(crypt(str, salt), 1);
2292+ }
2293 }
2294 /* }}} */
2295 #endif
2296diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.9/ext/standard/dl.c
2297--- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100
2298+++ hardening-patch-4.4.2-0.4.9/ext/standard/dl.c 2006-05-02 16:46:34.000000000 +0200
2299@@ -160,8 +160,35 @@
2300 RETURN_FALSE;
2301 }
2302 module_entry = get_module();
2303+
2304+ /* check if Hardening-Patch is installed */
2305+ if (module_entry->zend_api < 1000000000) {
2306+ php_error_docref(NULL TSRMLS_CC, error_type,
2307+ "%s: Unable to initialize module\n"
2308+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2309+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2310+ "These options need to match\n",
2311+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2312+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2313+ DL_UNLOAD(handle);
2314+ RETURN_FALSE;
2315+ }
2316+
2317+ /* check if correct Hardening-Patch is installed */
2318+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2319+ php_error_docref(NULL TSRMLS_CC, error_type,
2320+ "%s: Unable to initialize module\n"
2321+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2322+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2323+ "These options need to match\n",
2324+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2325+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2326+ DL_UNLOAD(handle);
2327+ RETURN_FALSE;
2328+ }
2329+
2330 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2331- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2332+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2333 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2334 struct pre_4_1_0_module_entry {
2335 char *name;
2336@@ -195,7 +222,7 @@
2337 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2338 } else {
2339 name = module_entry->name;
2340- zend_api = module_entry->zend_api;
2341+ zend_api = module_entry->real_zend_api;
2342 zend_debug = module_entry->zend_debug;
2343 zts = module_entry->zts;
2344 }
2345diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.9/ext/standard/file.c
2346--- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100
2347+++ hardening-patch-4.4.2-0.4.9/ext/standard/file.c 2006-05-02 16:49:46.000000000 +0200
2348@@ -21,7 +21,7 @@
2349 +----------------------------------------------------------------------+
2350 */
2351
2352-/* $Id: file.c,v 1.279.2.70.2.3 2006/01/01 13:46:57 sniper Exp $ */
2353+/* $Id: file.c,v 1.279.2.70.2.7 2006/04/14 17:46:59 pollita Exp $ */
2354
2355 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
2356
2357@@ -552,7 +552,7 @@
2358 pval **arg1, **arg2;
2359 char *d;
2360 char *opened_path;
2361- char p[64];
2362+ char *p;
2363 FILE *fp;
2364
2365 if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
2366@@ -566,7 +566,11 @@
2367 }
2368
2369 d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1));
2370- strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p));
2371+
2372+ p = php_basename(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2), NULL, 0);
2373+ if (strlen(p) > 64) {
2374+ p[63] = '\0';
2375+ }
2376
2377 if ((fp = php_open_temporary_file(d, p, &opened_path TSRMLS_CC))) {
2378 fclose(fp);
2379@@ -574,6 +578,7 @@
2380 } else {
2381 RETVAL_FALSE;
2382 }
2383+ efree(p);
2384 efree(d);
2385 }
2386 /* }}} */
2387@@ -819,7 +824,7 @@
2388
2389 /* If seconds is not set to null, build the timeval, else we wait indefinitely */
2390 if (sec != NULL) {
2391- convert_to_long_ex(&sec);
2392+ convert_to_long(sec);
2393
2394 if (usec > 999999) {
2395 tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000);
2396@@ -2196,7 +2201,7 @@
2397 safe_to_copy:
2398
2399 srcstream = php_stream_open_wrapper(src, "rb",
2400- STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS,
2401+ ENFORCE_SAFE_MODE | REPORT_ERRORS,
2402 NULL);
2403
2404 if (!srcstream)
2405@@ -2522,7 +2527,7 @@
2406 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2407 /* {{{ proto string realpath(string path)
2408 Return the resolved path */
2409-PHP_FUNCTION(realpath)
2410+PHP_FUNCTION(real_path)
2411 {
2412 zval **path;
2413 char resolved_path_buff[MAXPATHLEN];
2414diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.9/ext/standard/file.h
2415--- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100
2416+++ hardening-patch-4.4.2-0.4.9/ext/standard/file.h 2006-05-02 16:46:34.000000000 +0200
2417@@ -64,7 +64,7 @@
2418 PHP_FUNCTION(fd_set);
2419 PHP_FUNCTION(fd_isset);
2420 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2421-PHP_FUNCTION(realpath);
2422+PHP_FUNCTION(real_path);
2423 #endif
2424 #ifdef HAVE_FNMATCH
2425 PHP_FUNCTION(fnmatch);
2426diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.9/ext/standard/head.c
2427--- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100
2428+++ hardening-patch-4.4.2-0.4.9/ext/standard/head.c 2006-05-02 16:46:34.000000000 +0200
2429@@ -44,7 +44,7 @@
2430 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2431 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2432 return;
2433-
2434+
2435 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2436 }
2437 /* }}} */
2438diff -Nura php-4.4.2/ext/standard/html.c hardening-patch-4.4.2-0.4.9/ext/standard/html.c
2439--- php-4.4.2/ext/standard/html.c 2006-01-01 14:46:57.000000000 +0100
2440+++ hardening-patch-4.4.2-0.4.9/ext/standard/html.c 2006-05-02 16:49:55.000000000 +0200
2441@@ -18,7 +18,7 @@
2442 +----------------------------------------------------------------------+
2443 */
2444
2445-/* $Id: html.c,v 1.63.2.23.2.1 2006/01/01 13:46:57 sniper Exp $ */
2446+/* $Id: html.c,v 1.63.2.23.2.2 2006/02/25 21:33:06 rasmus Exp $ */
2447
2448 /*
2449 * HTML entity resources:
2450@@ -793,7 +793,7 @@
2451 enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC);
2452 unsigned char replacement[15];
2453
2454- ret = estrdup(old);
2455+ ret = estrndup(old, oldlen);
2456 retlen = oldlen;
2457 if (!retlen) {
2458 goto empty_source;
2459diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.9/ext/standard/info.c
2460--- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100
2461+++ hardening-patch-4.4.2-0.4.9/ext/standard/info.c 2006-05-02 16:53:57.000000000 +0200
2462@@ -58,6 +58,23 @@
2463
2464 PHPAPI extern char *php_ini_opened_path;
2465 PHPAPI extern char *php_ini_scanned_files;
2466+
2467+static int php_info_write_wrapper(const char *str, uint str_length)
2468+{
2469+ int new_len, written;
2470+ char *elem_esc;
2471+
2472+ TSRMLS_FETCH();
2473+
2474+ elem_esc = php_escape_html_entities((char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
2475+
2476+ written = php_body_write(elem_esc, new_len TSRMLS_CC);
2477+
2478+ efree(elem_esc);
2479+
2480+ return written;
2481+}
2482+
2483
2484 /* {{{ _display_module_info
2485 */
2486@@ -133,23 +150,12 @@
2487 PUTS(" => ");
2488 }
2489 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
2490- zval *tmp3;
2491- MAKE_STD_ZVAL(tmp3);
2492 if (!sapi_module.phpinfo_as_text) {
2493 PUTS("<pre>");
2494- }
2495- php_start_ob_buffer(NULL, 4096, 1 TSRMLS_CC);
2496- zend_print_zval_r(*tmp, 0);
2497- php_ob_get_buffer(tmp3 TSRMLS_CC);
2498- php_end_ob_buffer(0, 0 TSRMLS_CC);
2499-
2500- elem_esc = php_info_html_esc(Z_STRVAL_P(tmp3) TSRMLS_CC);
2501- PUTS(elem_esc);
2502- efree(elem_esc);
2503- zval_ptr_dtor(&tmp3);
2504-
2505- if (!sapi_module.phpinfo_as_text) {
2506+ zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
2507 PUTS("</pre>");
2508+ } else {
2509+ zend_print_zval_r(*tmp, 0 TSRMLS_CC);
2510 }
2511 } else if (Z_TYPE_PP(tmp) != IS_STRING) {
2512 tmp2 = **tmp;
2513@@ -408,7 +414,7 @@
2514
2515 if (flag & PHP_INFO_GENERAL) {
2516 char *zend_version = get_zend_version();
2517- char temp_api[9];
2518+ char temp_api[11];
2519
2520 php_uname = php_get_uname('a');
2521
2522@@ -430,11 +436,22 @@
2523 }
2524 }
2525
2526+#if HARDENING_PATCH
2527+ if (!sapi_module.phpinfo_as_text) {
2528+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2529+ } else {
2530+ char temp_ver[40];
2531+
2532+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2533+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2534+ }
2535+#else
2536 if (!sapi_module.phpinfo_as_text) {
2537 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2538 } else {
2539 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2540 }
2541+#endif
2542 php_info_print_box_end();
2543 php_info_print_table_start();
2544 php_info_print_table_row(2, "System", php_uname );
2545diff -Nura php-4.4.2/ext/standard/pack.c hardening-patch-4.4.2-0.4.9/ext/standard/pack.c
2546--- php-4.4.2/ext/standard/pack.c 2006-01-01 14:46:57.000000000 +0100
2547+++ hardening-patch-4.4.2-0.4.9/ext/standard/pack.c 2006-05-02 16:50:05.000000000 +0200
2548@@ -15,7 +15,7 @@
2549 | Author: Chris Schneider <cschneid@relog.ch> |
2550 +----------------------------------------------------------------------+
2551 */
2552-/* $Id: pack.c,v 1.40.2.7.2.4 2006/01/01 13:46:57 sniper Exp $ */
2553+/* $Id: pack.c,v 1.40.2.7.2.5 2006/01/26 15:47:31 iliaa Exp $ */
2554
2555 #include "php.h"
2556
2557@@ -693,7 +693,9 @@
2558 len = size * 2;
2559 }
2560
2561- len -= argb % 2;
2562+ if (argb > 0) {
2563+ len -= argb % 2;
2564+ }
2565
2566 buf = emalloc(len + 1);
2567
2568diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.9/ext/standard/php_standard.h
2569--- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100
2570+++ hardening-patch-4.4.2-0.4.9/ext/standard/php_standard.h 2006-05-02 16:46:34.000000000 +0200
2571@@ -28,6 +28,7 @@
2572 #include "php_mail.h"
2573 #include "md5.h"
2574 #include "sha1.h"
2575+#include "sha256.h"
2576 #include "html.h"
2577 #include "exec.h"
2578 #include "file.h"
2579diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.9/ext/standard/sha256.c
2580--- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2581+++ hardening-patch-4.4.2-0.4.9/ext/standard/sha256.c 2006-05-02 16:46:34.000000000 +0200
2582@@ -0,0 +1,398 @@
2583+/*
2584+ +----------------------------------------------------------------------+
2585+ | PHP Version 5 |
2586+ +----------------------------------------------------------------------+
2587+ | Copyright (c) 1997-2004 The PHP Group |
2588+ +----------------------------------------------------------------------+
2589+ | This source file is subject to version 3.0 of the PHP license, |
2590+ | that is bundled with this package in the file LICENSE, and is |
2591+ | available through the world-wide-web at the following url: |
2592+ | http://www.php.net/license/3_0.txt. |
2593+ | If you did not receive a copy of the PHP license and are unable to |
2594+ | obtain it through the world-wide-web, please send a note to |
2595+ | license@php.net so we can mail you a copy immediately. |
2596+ +----------------------------------------------------------------------+
2597+ | Author: Stefan Esser <sesser@php.net> |
2598+ +----------------------------------------------------------------------+
2599+*/
2600+
2601+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2602+
2603+#include <stdio.h>
2604+#include "php.h"
2605+
2606+/* This code is heavily based on the PHP md5/sha1 implementations */
2607+
2608+#include "sha256.h"
2609+
2610+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2611+{
2612+ int i;
2613+
2614+ for (i = 0; i < 32; i++) {
2615+ sprintf(sha256str, "%02x", digest[i]);
2616+ sha256str += 2;
2617+ }
2618+
2619+ *sha256str = '\0';
2620+}
2621+
2622+/* {{{ proto string sha256(string str [, bool raw_output])
2623+ Calculate the sha256 hash of a string */
2624+PHP_FUNCTION(sha256)
2625+{
2626+ char *arg;
2627+ int arg_len;
2628+ zend_bool raw_output = 0;
2629+ char sha256str[65];
2630+ PHP_SHA256_CTX context;
2631+ unsigned char digest[32];
2632+
2633+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2634+ return;
2635+ }
2636+
2637+ sha256str[0] = '\0';
2638+ PHP_SHA256Init(&context);
2639+ PHP_SHA256Update(&context, arg, arg_len);
2640+ PHP_SHA256Final(digest, &context);
2641+ if (raw_output) {
2642+ RETURN_STRINGL(digest, 32, 1);
2643+ } else {
2644+ make_sha256_digest(sha256str, digest);
2645+ RETVAL_STRING(sha256str, 1);
2646+ }
2647+
2648+}
2649+
2650+/* }}} */
2651+
2652+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2653+ Calculate the sha256 hash of given filename */
2654+PHP_FUNCTION(sha256_file)
2655+{
2656+ char *arg;
2657+ int arg_len;
2658+ zend_bool raw_output = 0;
2659+ char sha256str[65];
2660+ unsigned char buf[1024];
2661+ unsigned char digest[32];
2662+ PHP_SHA256_CTX context;
2663+ int n;
2664+ FILE *fp;
2665+
2666+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2667+ return;
2668+ }
2669+
2670+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2671+ RETURN_FALSE;
2672+ }
2673+
2674+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2675+ RETURN_FALSE;
2676+ }
2677+
2678+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2679+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2680+ RETURN_FALSE;
2681+ }
2682+
2683+ PHP_SHA256Init(&context);
2684+
2685+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2686+ PHP_SHA256Update(&context, buf, n);
2687+ }
2688+
2689+ PHP_SHA256Final(digest, &context);
2690+
2691+ if (ferror(fp)) {
2692+ fclose(fp);
2693+ RETURN_FALSE;
2694+ }
2695+
2696+ fclose(fp);
2697+
2698+ if (raw_output) {
2699+ RETURN_STRINGL(digest, 32, 1);
2700+ } else {
2701+ make_sha256_digest(sha256str, digest);
2702+ RETVAL_STRING(sha256str, 1);
2703+ }
2704+}
2705+/* }}} */
2706+
2707+
2708+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2709+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2710+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2711+
2712+static unsigned char PADDING[64] =
2713+{
2714+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2715+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2716+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2717+};
2718+
2719+/* F, G, H and I are basic SHA256 functions.
2720+ */
2721+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2722+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2723+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2724+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2725+
2726+/* ROTATE_RIGHT rotates x right n bits.
2727+ */
2728+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2729+
2730+/* W[i]
2731+ */
2732+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2733+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2734+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2735+
2736+/* ROUND function of sha256
2737+ */
2738+
2739+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2740+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2741+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2742+ (d) += t1; \
2743+ }
2744+
2745+
2746+/* {{{ PHP_SHA256Init
2747+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2748+ */
2749+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2750+{
2751+ context->count[0] = context->count[1] = 0;
2752+ /* Load magic initialization constants.
2753+ */
2754+ context->state[0] = 0x6a09e667;
2755+ context->state[1] = 0xbb67ae85;
2756+ context->state[2] = 0x3c6ef372;
2757+ context->state[3] = 0xa54ff53a;
2758+ context->state[4] = 0x510e527f;
2759+ context->state[5] = 0x9b05688c;
2760+ context->state[6] = 0x1f83d9ab;
2761+ context->state[7] = 0x5be0cd19;
2762+}
2763+/* }}} */
2764+
2765+/* {{{ PHP_SHA256Update
2766+ SHA256 block update operation. Continues an SHA256 message-digest
2767+ operation, processing another message block, and updating the
2768+ context.
2769+ */
2770+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2771+ unsigned int inputLen)
2772+{
2773+ unsigned int i, index, partLen;
2774+
2775+ /* Compute number of bytes mod 64 */
2776+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2777+
2778+ /* Update number of bits */
2779+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2780+ < ((php_uint32) inputLen << 3))
2781+ context->count[1]++;
2782+ context->count[1] += ((php_uint32) inputLen >> 29);
2783+
2784+ partLen = 64 - index;
2785+
2786+ /* Transform as many times as possible.
2787+ */
2788+ if (inputLen >= partLen) {
2789+ memcpy
2790+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2791+ SHA256Transform(context->state, context->buffer);
2792+
2793+ for (i = partLen; i + 63 < inputLen; i += 64)
2794+ SHA256Transform(context->state, &input[i]);
2795+
2796+ index = 0;
2797+ } else
2798+ i = 0;
2799+
2800+ /* Buffer remaining input */
2801+ memcpy
2802+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2803+ inputLen - i);
2804+}
2805+/* }}} */
2806+
2807+/* {{{ PHP_SHA256Final
2808+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2809+ the message digest and zeroizing the context.
2810+ */
2811+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2812+{
2813+ unsigned char bits[8];
2814+ unsigned int index, padLen;
2815+
2816+ /* Save number of bits */
2817+ bits[7] = context->count[0] & 0xFF;
2818+ bits[6] = (context->count[0] >> 8) & 0xFF;
2819+ bits[5] = (context->count[0] >> 16) & 0xFF;
2820+ bits[4] = (context->count[0] >> 24) & 0xFF;
2821+ bits[3] = context->count[1] & 0xFF;
2822+ bits[2] = (context->count[1] >> 8) & 0xFF;
2823+ bits[1] = (context->count[1] >> 16) & 0xFF;
2824+ bits[0] = (context->count[1] >> 24) & 0xFF;
2825+
2826+ /* Pad out to 56 mod 64.
2827+ */
2828+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2829+ padLen = (index < 56) ? (56 - index) : (120 - index);
2830+ PHP_SHA256Update(context, PADDING, padLen);
2831+
2832+ /* Append length (before padding) */
2833+ PHP_SHA256Update(context, bits, 8);
2834+
2835+ /* Store state in digest */
2836+ SHA256Encode(digest, context->state, 32);
2837+
2838+ /* Zeroize sensitive information.
2839+ */
2840+ memset((unsigned char*) context, 0, sizeof(*context));
2841+}
2842+/* }}} */
2843+
2844+/* {{{ SHA256Transform
2845+ * SHA256 basic transformation. Transforms state based on block.
2846+ */
2847+static void SHA256Transform(state, block)
2848+php_uint32 state[8];
2849+const unsigned char block[64];
2850+{
2851+ php_uint32 a = state[0], b = state[1], c = state[2];
2852+ php_uint32 d = state[3], e = state[4], f = state[5];
2853+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2854+
2855+ SHA256Decode(x, block, 64);
2856+
2857+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2858+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2859+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2860+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2861+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2862+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2863+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2864+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2865+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2866+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2867+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2868+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2869+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2870+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2871+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2872+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2873+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2874+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2875+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2876+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2877+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2878+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2879+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2880+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2881+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2882+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2883+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2884+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2885+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2886+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2887+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2888+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2889+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2890+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2891+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2892+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2893+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2894+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2895+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2896+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2897+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2898+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2899+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2900+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2901+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2902+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2903+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2904+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2905+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2906+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2907+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2908+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2909+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2910+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2911+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2912+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2913+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2914+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2915+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2916+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2917+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2918+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2919+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2920+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2921+
2922+ state[0] += a;
2923+ state[1] += b;
2924+ state[2] += c;
2925+ state[3] += d;
2926+ state[4] += e;
2927+ state[5] += f;
2928+ state[6] += g;
2929+ state[7] += h;
2930+
2931+ /* Zeroize sensitive information. */
2932+ memset((unsigned char*) x, 0, sizeof(x));
2933+}
2934+/* }}} */
2935+
2936+/* {{{ SHA256Encode
2937+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2938+ a multiple of 4.
2939+ */
2940+static void SHA256Encode(output, input, len)
2941+unsigned char *output;
2942+php_uint32 *input;
2943+unsigned int len;
2944+{
2945+ unsigned int i, j;
2946+
2947+ for (i = 0, j = 0; j < len; i++, j += 4) {
2948+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2949+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2950+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2951+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2952+ }
2953+}
2954+/* }}} */
2955+
2956+/* {{{ SHA256Decode
2957+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2958+ a multiple of 4.
2959+ */
2960+static void SHA256Decode(output, input, len)
2961+php_uint32 *output;
2962+const unsigned char *input;
2963+unsigned int len;
2964+{
2965+ unsigned int i, j;
2966+
2967+ for (i = 0, j = 0; j < len; i++, j += 4)
2968+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2969+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2970+}
2971+/* }}} */
2972+
2973+/*
2974+ * Local variables:
2975+ * tab-width: 4
2976+ * c-basic-offset: 4
2977+ * End:
2978+ * vim600: sw=4 ts=4 fdm=marker
2979+ * vim<600: sw=4 ts=4
2980+ */
2981diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.9/ext/standard/sha256.h
2982--- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2983+++ hardening-patch-4.4.2-0.4.9/ext/standard/sha256.h 2006-05-02 16:46:34.000000000 +0200
2984@@ -0,0 +1,40 @@
2985+/*
2986+ +----------------------------------------------------------------------+
2987+ | PHP Version 5 |
2988+ +----------------------------------------------------------------------+
2989+ | Copyright (c) 1997-2004 The PHP Group |
2990+ +----------------------------------------------------------------------+
2991+ | This source file is subject to version 3.0 of the PHP license, |
2992+ | that is bundled with this package in the file LICENSE, and is |
2993+ | available through the world-wide-web at the following url: |
2994+ | http://www.php.net/license/3_0.txt. |
2995+ | If you did not receive a copy of the PHP license and are unable to |
2996+ | obtain it through the world-wide-web, please send a note to |
2997+ | license@php.net so we can mail you a copy immediately. |
2998+ +----------------------------------------------------------------------+
2999+ | Author: Stefan Esser <sesser@php.net> |
3000+ +----------------------------------------------------------------------+
3001+*/
3002+
3003+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
3004+
3005+#ifndef SHA256_H
3006+#define SHA256_H
3007+
3008+#include "ext/standard/basic_functions.h"
3009+
3010+/* SHA1 context. */
3011+typedef struct {
3012+ php_uint32 state[8]; /* state (ABCD) */
3013+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
3014+ unsigned char buffer[64]; /* input buffer */
3015+} PHP_SHA256_CTX;
3016+
3017+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
3018+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
3019+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
3020+
3021+PHP_FUNCTION(sha256);
3022+PHP_FUNCTION(sha256_file);
3023+
3024+#endif
3025diff -Nura php-4.4.2/ext/standard/string.c hardening-patch-4.4.2-0.4.9/ext/standard/string.c
3026--- php-4.4.2/ext/standard/string.c 2006-01-01 14:46:58.000000000 +0100
3027+++ hardening-patch-4.4.2-0.4.9/ext/standard/string.c 2006-05-02 16:50:16.000000000 +0200
3028@@ -18,7 +18,7 @@
3029 +----------------------------------------------------------------------+
3030 */
3031
3032-/* $Id: string.c,v 1.333.2.52.2.3 2006/01/01 13:46:58 sniper Exp $ */
3033+/* $Id: string.c,v 1.333.2.52.2.4 2006/03/13 14:41:27 iliaa Exp $ */
3034
3035 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
3036
3037@@ -672,15 +672,13 @@
3038 /* Multiple character line break or forced cut */
3039 if (linelength > 0) {
3040 chk = (int)(textlen/linelength + 1);
3041+ newtext = safe_emalloc(chk, breakcharlen, textlen + 1);
3042 alloced = textlen + chk * breakcharlen + 1;
3043 } else {
3044 chk = textlen;
3045+ newtext = safe_emalloc(textlen, (breakcharlen + 1), 1);
3046 alloced = textlen * (breakcharlen + 1) + 1;
3047 }
3048- if (alloced <= 0) {
3049- RETURN_FALSE;
3050- }
3051- newtext = emalloc(alloced);
3052
3053 /* now keep track of the actual new text length */
3054 newtextlen = 0;
3055diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.9/ext/standard/syslog.c
3056--- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100
3057+++ hardening-patch-4.4.2-0.4.9/ext/standard/syslog.c 2006-05-02 16:46:34.000000000 +0200
3058@@ -42,6 +42,8 @@
3059 */
3060 PHP_MINIT_FUNCTION(syslog)
3061 {
3062+
3063+#if !HARDENING_PATCH
3064 /* error levels */
3065 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
3066 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
3067@@ -97,7 +99,7 @@
3068 /* AIX doesn't have LOG_PERROR */
3069 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
3070 #endif
3071-
3072+#endif
3073 return SUCCESS;
3074 }
3075 /* }}} */
3076diff -Nura php-4.4.2/ext/standard/url.c hardening-patch-4.4.2-0.4.9/ext/standard/url.c
3077--- php-4.4.2/ext/standard/url.c 2006-01-01 14:46:58.000000000 +0100
3078+++ hardening-patch-4.4.2-0.4.9/ext/standard/url.c 2006-05-02 16:50:23.000000000 +0200
3079@@ -15,7 +15,7 @@
3080 | Author: Jim Winstead <jimw@php.net> |
3081 +----------------------------------------------------------------------+
3082 */
3083-/* $Id: url.c,v 1.58.2.21.2.2 2006/01/01 13:46:58 sniper Exp $ */
3084+/* $Id: url.c,v 1.58.2.21.2.3 2006/02/12 16:43:03 iliaa Exp $ */
3085
3086 #include <stdlib.h>
3087 #include <string.h>
3088@@ -137,7 +137,7 @@
3089 p++;
3090 }
3091
3092- if ((*p) == '\0' || *p == '/') {
3093+ if ((*p == '\0' || *p == '/') && (p - e) < 7) {
3094 goto parse_port;
3095 }
3096
3097diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.9/ext/varfilter/config.m4
3098--- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
3099+++ hardening-patch-4.4.2-0.4.9/ext/varfilter/config.m4 2006-05-02 16:46:34.000000000 +0200
3100@@ -0,0 +1,11 @@
3101+dnl
3102+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
3103+dnl
3104+
3105+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
3106+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
3107+
3108+if test "$PHP_VARFILTER" != "no"; then
3109+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
3110+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
3111+fi
3112diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.9/ext/varfilter/CREDITS
3113--- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
3114+++ hardening-patch-4.4.2-0.4.9/ext/varfilter/CREDITS 2006-05-02 16:46:34.000000000 +0200
3115@@ -0,0 +1,2 @@
3116+varfilter
3117+Stefan Esser
3118\ Kein Zeilenumbruch am Dateiende.
3119diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.9/ext/varfilter/php_varfilter.h
3120--- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
3121+++ hardening-patch-4.4.2-0.4.9/ext/varfilter/php_varfilter.h 2006-05-02 16:46:34.000000000 +0200
3122@@ -0,0 +1,144 @@
3123+/*
3124+ +----------------------------------------------------------------------+
3125+ | Hardened-PHP Project's varfilter extension |
3126+ +----------------------------------------------------------------------+
3127+ | Copyright (c) 2004-2005 Stefan Esser |
3128+ +----------------------------------------------------------------------+
3129+ | This source file is subject to version 2.02 of the PHP license, |
3130+ | that is bundled with this package in the file LICENSE, and is |
3131+ | available at through the world-wide-web at |
3132+ | http://www.php.net/license/2_02.txt. |
3133+ | If you did not receive a copy of the PHP license and are unable to |
3134+ | obtain it through the world-wide-web, please send a note to |
3135+ | license@php.net so we can mail you a copy immediately. |
3136+ +----------------------------------------------------------------------+
3137+ | Author: Stefan Esser <sesser@hardened-php.net> |
3138+ +----------------------------------------------------------------------+
3139+
3140+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
3141+*/
3142+
3143+#ifndef PHP_VARFILTER_H
3144+#define PHP_VARFILTER_H
3145+
3146+extern zend_module_entry varfilter_module_entry;
3147+#define phpext_varfilter_ptr &varfilter_module_entry
3148+
3149+#ifdef PHP_WIN32
3150+#define PHP_VARFILTER_API __declspec(dllexport)
3151+#else
3152+#define PHP_VARFILTER_API
3153+#endif
3154+
3155+#ifdef ZTS
3156+#include "TSRM.h"
3157+#endif
3158+
3159+#include "SAPI.h"
3160+
3161+#include "php_variables.h"
3162+
3163+#ifdef ZEND_ENGINE_2
3164+#define HASH_HTTP_GET_VARS 0x2095733f
3165+#define HASH_HTTP_POST_VARS 0xbfee1265
3166+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
3167+#define HASH_HTTP_ENV_VARS 0x1fe186a8
3168+#define HASH_HTTP_SERVER_VARS 0xc987afd6
3169+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
3170+#define HASH_HTTP_POST_FILES 0x98eb1ddc
3171+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
3172+#else
3173+#define HASH_HTTP_GET_VARS 0x8d8645bd
3174+#define HASH_HTTP_POST_VARS 0x7c699bf3
3175+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
3176+#define HASH_HTTP_ENV_VARS 0x84da3016
3177+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
3178+#define HASH_HTTP_SESSION_VARS 0x322906f5
3179+#define HASH_HTTP_POST_FILES 0xe4e4ce70
3180+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
3181+#endif
3182+
3183+PHP_MINIT_FUNCTION(varfilter);
3184+PHP_MSHUTDOWN_FUNCTION(varfilter);
3185+PHP_RINIT_FUNCTION(varfilter);
3186+PHP_RSHUTDOWN_FUNCTION(varfilter);
3187+PHP_MINFO_FUNCTION(varfilter);
3188+
3189+
3190+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3191+/* request variables */
3192+ long max_request_variables;
3193+ long cur_request_variables;
3194+ long max_varname_length;
3195+ long max_totalname_length;
3196+ long max_value_length;
3197+ long max_array_depth;
3198+ long max_array_index_length;
3199+ zend_bool disallow_nul;
3200+/* cookie variables */
3201+ long max_cookie_vars;
3202+ long cur_cookie_vars;
3203+ long max_cookie_name_length;
3204+ long max_cookie_totalname_length;
3205+ long max_cookie_value_length;
3206+ long max_cookie_array_depth;
3207+ long max_cookie_array_index_length;
3208+ zend_bool disallow_cookie_nul;
3209+/* get variables */
3210+ long max_get_vars;
3211+ long cur_get_vars;
3212+ long max_get_name_length;
3213+ long max_get_totalname_length;
3214+ long max_get_value_length;
3215+ long max_get_array_depth;
3216+ long max_get_array_index_length;
3217+ zend_bool disallow_get_nul;
3218+/* post variables */
3219+ long max_post_vars;
3220+ long cur_post_vars;
3221+ long max_post_name_length;
3222+ long max_post_totalname_length;
3223+ long max_post_value_length;
3224+ long max_post_array_depth;
3225+ long max_post_array_index_length;
3226+ zend_bool disallow_post_nul;
3227+/* fileupload */
3228+ long max_uploads;
3229+ long cur_uploads;
3230+ zend_bool disallow_elf_files;
3231+ char *verification_script;
3232+
3233+ zend_bool no_more_variables;
3234+ zend_bool no_more_get_variables;
3235+ zend_bool no_more_post_variables;
3236+ zend_bool no_more_cookie_variables;
3237+ zend_bool no_more_uploads;
3238+
3239+ZEND_END_MODULE_GLOBALS(varfilter)
3240+
3241+
3242+#ifdef ZTS
3243+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3244+#else
3245+#define VARFILTER_G(v) (varfilter_globals.v)
3246+#endif
3247+
3248+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3249+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3250+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3251+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3252+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3253+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3254+
3255+
3256+
3257+#endif /* PHP_VARFILTER_H */
3258+
3259+
3260+/*
3261+ * Local variables:
3262+ * tab-width: 4
3263+ * c-basic-offset: 4
3264+ * indent-tabs-mode: t
3265+ * End:
3266+ */
3267diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.9/ext/varfilter/varfilter.c
3268--- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3269+++ hardening-patch-4.4.2-0.4.9/ext/varfilter/varfilter.c 2006-05-02 16:54:39.000000000 +0200
3270@@ -0,0 +1,915 @@
3271+/*
3272+ +----------------------------------------------------------------------+
3273+ | Hardened-PHP Project's varfilter extension |
3274+ +----------------------------------------------------------------------+
3275+ | Copyright (c) 2004-2005 Stefan Esser |
3276+ +----------------------------------------------------------------------+
3277+ | This source file is subject to version 2.02 of the PHP license, |
3278+ | that is bundled with this package in the file LICENSE, and is |
3279+ | available at through the world-wide-web at |
3280+ | http://www.php.net/license/2_02.txt. |
3281+ | If you did not receive a copy of the PHP license and are unable to |
3282+ | obtain it through the world-wide-web, please send a note to |
3283+ | license@php.net so we can mail you a copy immediately. |
3284+ +----------------------------------------------------------------------+
3285+ | Author: Stefan Esser <sesser@hardened-php.net> |
3286+ +----------------------------------------------------------------------+
3287+
3288+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3289+*/
3290+
3291+#ifdef HAVE_CONFIG_H
3292+#include "config.h"
3293+#endif
3294+
3295+#include "php.h"
3296+#include "php_ini.h"
3297+#include "ext/standard/info.h"
3298+#include "php_varfilter.h"
3299+#include "hardening_patch.h"
3300+
3301+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3302+
3303+/* True global resources - no need for thread safety here */
3304+static int le_varfilter;
3305+
3306+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3307+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3308+static zend_bool hooked = 0;
3309+
3310+/* {{{ varfilter_module_entry
3311+ */
3312+zend_module_entry varfilter_module_entry = {
3313+#if ZEND_MODULE_API_NO >= 20010901
3314+ STANDARD_MODULE_HEADER,
3315+#endif
3316+ "varfilter",
3317+ NULL,
3318+ PHP_MINIT(varfilter),
3319+ PHP_MSHUTDOWN(varfilter),
3320+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3321+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3322+ PHP_MINFO(varfilter),
3323+#if ZEND_MODULE_API_NO >= 20010901
3324+ "0.4.9", /* Replace with version number for your extension */
3325+#endif
3326+ STANDARD_MODULE_PROPERTIES
3327+};
3328+/* }}} */
3329+
3330+#ifdef COMPILE_DL_VARFILTER
3331+ZEND_GET_MODULE(varfilter)
3332+#endif
3333+
3334+/* {{{ PHP_INI
3335+ */
3336+PHP_INI_BEGIN()
3337+ /* for backward compatibility */
3338+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3339+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3340+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3341+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3342+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3343+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3344+
3345+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3346+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3347+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3348+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3349+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3350+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3351+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3352+
3353+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3354+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3355+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3356+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3357+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3358+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_index_length, zend_varfilter_globals, varfilter_globals)
3359+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3360+
3361+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3362+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3363+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3364+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3365+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3366+ STD_PHP_INI_ENTRY("hphp.get.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_array_index_length, zend_varfilter_globals, varfilter_globals)
3367+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3368+
3369+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3370+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3371+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3372+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3373+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3374+ STD_PHP_INI_ENTRY("hphp.post.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_array_index_length, zend_varfilter_globals, varfilter_globals)
3375+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3376+
3377+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3378+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3379+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3380+
3381+
3382+PHP_INI_END()
3383+/* }}} */
3384+
3385+/* {{{ php_varfilter_init_globals
3386+ */
3387+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3388+{
3389+ varfilter_globals->max_request_variables = 200;
3390+ varfilter_globals->max_varname_length = 64;
3391+ varfilter_globals->max_value_length = 10000;
3392+ varfilter_globals->max_array_depth = 100;
3393+ varfilter_globals->max_totalname_length = 256;
3394+ varfilter_globals->max_array_index_length = 64;
3395+ varfilter_globals->disallow_nul = 1;
3396+
3397+ varfilter_globals->max_cookie_vars = 100;
3398+ varfilter_globals->max_cookie_name_length = 64;
3399+ varfilter_globals->max_cookie_totalname_length = 256;
3400+ varfilter_globals->max_cookie_value_length = 10000;
3401+ varfilter_globals->max_cookie_array_depth = 100;
3402+ varfilter_globals->max_cookie_array_index_length = 64;
3403+ varfilter_globals->disallow_cookie_nul = 1;
3404+
3405+ varfilter_globals->max_get_vars = 100;
3406+ varfilter_globals->max_get_name_length = 64;
3407+ varfilter_globals->max_get_totalname_length = 256;
3408+ varfilter_globals->max_get_value_length = 512;
3409+ varfilter_globals->max_get_array_depth = 50;
3410+ varfilter_globals->max_get_array_index_length = 64;
3411+ varfilter_globals->disallow_get_nul = 1;
3412+
3413+ varfilter_globals->max_post_vars = 200;
3414+ varfilter_globals->max_post_name_length = 64;
3415+ varfilter_globals->max_post_totalname_length = 256;
3416+ varfilter_globals->max_post_value_length = 65000;
3417+ varfilter_globals->max_post_array_depth = 100;
3418+ varfilter_globals->max_post_array_index_length = 64;
3419+ varfilter_globals->disallow_post_nul = 1;
3420+
3421+ varfilter_globals->max_uploads = 25;
3422+ varfilter_globals->disallow_elf_files = 1;
3423+ varfilter_globals->verification_script = NULL;
3424+
3425+ varfilter_globals->no_more_variables = 0;
3426+ varfilter_globals->no_more_get_variables = 0;
3427+ varfilter_globals->no_more_post_variables = 0;
3428+ varfilter_globals->no_more_cookie_variables = 0;
3429+ varfilter_globals->no_more_uploads = 0;
3430+
3431+ varfilter_globals->cur_request_variables = 0;
3432+ varfilter_globals->cur_get_vars = 0;
3433+ varfilter_globals->cur_post_vars = 0;
3434+ varfilter_globals->cur_cookie_vars = 0;
3435+
3436+ varfilter_globals->cur_uploads = 0;
3437+
3438+}
3439+/* }}} */
3440+
3441+
3442+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3443+{
3444+ HashTable *svars;
3445+ int retval, failure=0;
3446+
3447+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3448+
3449+ svars = Z_ARRVAL_P(track_vars_array);
3450+
3451+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3452+ if (retval == SUCCESS) failure = 1;
3453+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3454+ if (retval == SUCCESS) failure = 1;
3455+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3456+ if (retval == SUCCESS) failure = 1;
3457+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3458+ if (retval == SUCCESS) failure = 1;
3459+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3460+ if (retval == SUCCESS) failure = 1;
3461+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3462+ if (retval == SUCCESS) failure = 1;
3463+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3464+ if (retval == SUCCESS) failure = 1;
3465+ retval = zend_hash_del_key_or_index(svars, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), HASH_HTTP_RAW_POST_DATA, HASH_DEL_INDEX);
3466+ if (retval == SUCCESS) failure = 1;
3467+
3468+ if (failure) {
3469+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3470+ }
3471+}
3472+
3473+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3474+{
3475+ int retval = SAPI_HEADER_ADD, i;
3476+ char *tmp;
3477+
3478+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3479+
3480+ tmp = sapi_header->header;
3481+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3482+ if (tmp[0] == 0) {
3483+ char *fname = get_active_function_name(TSRMLS_C);
3484+
3485+ if (!fname) {
3486+ fname = "unknown";
3487+ }
3488+
3489+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3490+ sapi_header->header_len = i;
3491+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3492+ char *fname = get_active_function_name(TSRMLS_C);
3493+
3494+ if (!fname) {
3495+ fname = "unknown";
3496+ }
3497+
3498+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3499+ sapi_header->header_len = i;
3500+ tmp[0] = 0;
3501+ }
3502+ }
3503+ }
3504+
3505+ if (orig_header_handler) {
3506+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3507+ }
3508+
3509+ return retval;
3510+}
3511+
3512+/* {{{ PHP_MINIT_FUNCTION
3513+ */
3514+PHP_MINIT_FUNCTION(varfilter)
3515+{
3516+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3517+ REGISTER_INI_ENTRIES();
3518+
3519+ if (!hooked) {
3520+ void *temp;
3521+ hooked = 1;
3522+
3523+ temp = (void *)sapi_module.register_server_variables;
3524+ if (temp != varfilter_register_server_variables) {
3525+ orig_register_server_variables = temp;
3526+ }
3527+ temp = (void *)sapi_module.header_handler;
3528+ if (temp != varfilter_header_handler) {
3529+ orig_header_handler = temp;
3530+ }
3531+ }
3532+
3533+ sapi_register_input_filter(varfilter_input_filter);
3534+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3535+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3536+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3537+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3538+
3539+ sapi_module.header_handler = varfilter_header_handler;
3540+ sapi_module.register_server_variables = varfilter_register_server_variables;
3541+
3542+
3543+ return SUCCESS;
3544+}
3545+/* }}} */
3546+
3547+/* {{{ PHP_MSHUTDOWN_FUNCTION
3548+ */
3549+PHP_MSHUTDOWN_FUNCTION(varfilter)
3550+{
3551+ UNREGISTER_INI_ENTRIES();
3552+
3553+ return SUCCESS;
3554+}
3555+/* }}} */
3556+
3557+/* Remove if there's nothing to do at request start */
3558+/* {{{ PHP_RINIT_FUNCTION
3559+ */
3560+PHP_RINIT_FUNCTION(varfilter)
3561+{
3562+ VARFILTER_G(cur_request_variables) = 0;
3563+ VARFILTER_G(cur_get_vars) = 0;
3564+ VARFILTER_G(cur_post_vars) = 0;
3565+ VARFILTER_G(cur_cookie_vars) = 0;
3566+
3567+ VARFILTER_G(cur_uploads) = 0;
3568+
3569+ VARFILTER_G(no_more_variables) = 0;
3570+ VARFILTER_G(no_more_get_variables) = 0;
3571+ VARFILTER_G(no_more_post_variables) = 0;
3572+ VARFILTER_G(no_more_cookie_variables) = 0;
3573+ VARFILTER_G(no_more_uploads) = 0;
3574+
3575+ return SUCCESS;
3576+}
3577+/* }}} */
3578+
3579+/* Remove if there's nothing to do at request end */
3580+/* {{{ PHP_RSHUTDOWN_FUNCTION
3581+ */
3582+PHP_RSHUTDOWN_FUNCTION(varfilter)
3583+{
3584+ return SUCCESS;
3585+}
3586+/* }}} */
3587+
3588+/* {{{ PHP_MINFO_FUNCTION
3589+ */
3590+PHP_MINFO_FUNCTION(varfilter)
3591+{
3592+ php_info_print_table_start();
3593+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3594+ php_info_print_table_end();
3595+
3596+ DISPLAY_INI_ENTRIES();
3597+}
3598+/* }}} */
3599+
3600+/* {{{ normalize_varname
3601+ */
3602+static void normalize_varname(char *varname)
3603+{
3604+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3605+
3606+ /* overjump leading space */
3607+ while (*s == ' ') {
3608+ s++;
3609+ }
3610+
3611+ /* and remove it */
3612+ if (s != varname) {
3613+ memmove(varname, s, strlen(s)+1);
3614+ }
3615+
3616+ for (p=varname; *p && *p != '['; p++) {
3617+ switch(*p) {
3618+ case ' ':
3619+ case '.':
3620+ *p='_';
3621+ break;
3622+ }
3623+ }
3624+
3625+ /* find index */
3626+ index = strchr(varname, '[');
3627+ if (index) {
3628+ index++;
3629+ s=index;
3630+ } else {
3631+ return;
3632+ }
3633+
3634+ /* done? */
3635+ while (index) {
3636+
3637+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3638+ index++;
3639+ }
3640+ indexend = strchr(index, ']');
3641+ indexend = indexend ? indexend + 1 : index + strlen(index);
3642+
3643+ if (s != index) {
3644+ memmove(s, index, strlen(index)+1);
3645+ s += indexend-index;
3646+ } else {
3647+ s = indexend;
3648+ }
3649+
3650+ if (*s == '[') {
3651+ s++;
3652+ index = s;
3653+ } else {
3654+ index = NULL;
3655+ }
3656+ }
3657+ *s++='\0';
3658+}
3659+/* }}} */
3660+
3661+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3662+ */
3663+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3664+{
3665+ char *index, *prev_index = NULL, *var;
3666+ unsigned int var_len, total_len, depth = 0;
3667+
3668+ var = estrdup(varname);
3669+
3670+ /* Normalize the variable name */
3671+ normalize_varname(var);
3672+
3673+ /* Find length of variable name */
3674+ index = strchr(var, '[');
3675+ total_len = strlen(var);
3676+ var_len = index ? index-var : total_len;
3677+
3678+ /* Drop this variable if it exceeds the varname/total length limit */
3679+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3680+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3681+ goto return_failure;
3682+ }
3683+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3684+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3685+ goto return_failure;
3686+ }
3687+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3688+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3689+
3690+ goto return_failure;
3691+ }
3692+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3693+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3694+ goto return_failure;
3695+ }
3696+
3697+ /* Find out array depth */
3698+ while (index) {
3699+ unsigned int index_length;
3700+
3701+ depth++;
3702+ index = strchr(index+1, '[');
3703+
3704+ if (prev_index) {
3705+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3706+
3707+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3708+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3709+ goto return_failure;
3710+ }
3711+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3712+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3713+ goto return_failure;
3714+ }
3715+ prev_index = index;
3716+ }
3717+
3718+ }
3719+
3720+ /* Drop this variable if it exceeds the array depth limit */
3721+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3722+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3723+ goto return_failure;
3724+ }
3725+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3726+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3727+ goto return_failure;
3728+ }
3729+
3730+
3731+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3732+ /* This is to protect several silly scripts that do globalizing themself */
3733+
3734+ switch (var_len) {
3735+ case 18:
3736+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3737+ break;
3738+ case 17:
3739+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3740+ break;
3741+ case 16:
3742+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3743+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3744+ break;
3745+ case 15:
3746+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3747+ break;
3748+ case 14:
3749+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3750+ break;
3751+ case 13:
3752+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3753+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3754+ break;
3755+ case 8:
3756+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3757+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3758+ break;
3759+ case 7:
3760+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3761+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3762+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3763+ break;
3764+ case 6:
3765+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3766+ break;
3767+ case 5:
3768+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3769+ break;
3770+ case 4:
3771+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3772+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3773+ break;
3774+ }
3775+
3776+ efree(var);
3777+ return SUCCESS;
3778+protected_varname2:
3779+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3780+return_failure:
3781+ efree(var);
3782+ return FAILURE;
3783+}
3784+/* }}} */
3785+
3786+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3787+ */
3788+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3789+{
3790+ /* Drop if no more variables flag is set */
3791+ if (VARFILTER_G(no_more_uploads)) {
3792+ return FAILURE;
3793+ }
3794+ /* Drop this fileupload if the limit is reached */
3795+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3796+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3797+ VARFILTER_G(no_more_uploads) = 1;
3798+ return FAILURE;
3799+ }
3800+
3801+ return SUCCESS;
3802+}
3803+/* }}} */
3804+
3805+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3806+ */
3807+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3808+{
3809+
3810+ if (VARFILTER_G(disallow_elf_files)) {
3811+
3812+ if (offset == 0 && buffer_len > 10) {
3813+
3814+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3815+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3816+ return FAILURE;
3817+ }
3818+ }
3819+
3820+ }
3821+
3822+ return SUCCESS;
3823+}
3824+/* }}} */
3825+
3826+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3827+ */
3828+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3829+{
3830+ int retval = SUCCESS;
3831+
3832+ if (VARFILTER_G(verification_script)) {
3833+ char cmd[8192];
3834+ FILE *in;
3835+ int first=1;
3836+
3837+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3838+
3839+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3840+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3841+ return FAILURE;
3842+ }
3843+
3844+ retval = FAILURE;
3845+
3846+ /* read and forget the result */
3847+ while (1) {
3848+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3849+ if (readbytes<=0) {
3850+ break;
3851+ }
3852+ if (first) {
3853+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3854+ first = 0;
3855+ }
3856+ }
3857+ pclose(in);
3858+ }
3859+
3860+ if (retval != SUCCESS) {
3861+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3862+ return FAILURE;
3863+ }
3864+
3865+ VARFILTER_G(cur_uploads)++;
3866+ return SUCCESS;
3867+}
3868+/* }}} */
3869+
3870+/* {{{ SAPI_INPUT_FILTER_FUNC
3871+ */
3872+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3873+{
3874+ char *index, *prev_index = NULL;
3875+ unsigned int var_len, total_len, depth = 0;
3876+
3877+ /* Drop this variable if the limit was reached */
3878+ switch (arg) {
3879+ case PARSE_GET:
3880+ if (VARFILTER_G(no_more_get_variables)) {
3881+ return 0;
3882+ }
3883+ break;
3884+ case PARSE_POST:
3885+ if (VARFILTER_G(no_more_post_variables)) {
3886+ return 0;
3887+ }
3888+ break;
3889+ case PARSE_COOKIE:
3890+ if (VARFILTER_G(no_more_cookie_variables)) {
3891+ return 0;
3892+ }
3893+ break;
3894+ default: /* we do not want to protect parse_str() and friends */
3895+ if (new_val_len) {
3896+ *new_val_len = val_len;
3897+ }
3898+ return 1;
3899+ }
3900+ if (VARFILTER_G(no_more_variables)) {
3901+ return 0;
3902+ }
3903+
3904+ /* Drop this variable if the limit is now reached */
3905+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3906+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3907+ VARFILTER_G(no_more_variables) = 1;
3908+ return 0;
3909+ }
3910+ switch (arg) {
3911+ case PARSE_GET:
3912+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3913+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3914+ VARFILTER_G(no_more_get_variables) = 1;
3915+ return 0;
3916+ }
3917+ break;
3918+ case PARSE_COOKIE:
3919+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3920+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3921+ VARFILTER_G(no_more_cookie_variables) = 1;
3922+ return 0;
3923+ }
3924+ break;
3925+ case PARSE_POST:
3926+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3927+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3928+ VARFILTER_G(no_more_post_variables) = 1;
3929+ return 0;
3930+ }
3931+ break;
3932+ }
3933+
3934+
3935+ /* Drop this variable if it exceeds the value length limit */
3936+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3937+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3938+ return 0;
3939+ }
3940+ switch (arg) {
3941+ case PARSE_GET:
3942+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3943+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3944+ return 0;
3945+ }
3946+ break;
3947+ case PARSE_COOKIE:
3948+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3949+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3950+ return 0;
3951+ }
3952+ break;
3953+ case PARSE_POST:
3954+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3955+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3956+ return 0;
3957+ }
3958+ break;
3959+ }
3960+
3961+ /* Normalize the variable name */
3962+ normalize_varname(var);
3963+
3964+ /* Find length of variable name */
3965+ index = strchr(var, '[');
3966+ total_len = strlen(var);
3967+ var_len = index ? index-var : total_len;
3968+
3969+ /* Drop this variable if it exceeds the varname/total length limit */
3970+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3971+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3972+ return 0;
3973+ }
3974+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3975+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3976+ return 0;
3977+ }
3978+ switch (arg) {
3979+ case PARSE_GET:
3980+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3981+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3982+ return 0;
3983+ }
3984+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3985+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3986+ return 0;
3987+ }
3988+ break;
3989+ case PARSE_COOKIE:
3990+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3991+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3992+ return 0;
3993+ }
3994+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3995+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3996+ return 0;
3997+ }
3998+ break;
3999+ case PARSE_POST:
4000+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
4001+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
4002+ return 0;
4003+ }
4004+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
4005+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
4006+ return 0;
4007+ }
4008+ break;
4009+ }
4010+
4011+ /* Find out array depth */
4012+ while (index) {
4013+ unsigned int index_length;
4014+
4015+ depth++;
4016+ index = strchr(index+1, '[');
4017+
4018+ if (prev_index) {
4019+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
4020+
4021+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
4022+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
4023+ return 0;
4024+ }
4025+ switch (arg) {
4026+ case PARSE_GET:
4027+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
4028+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
4029+ return 0;
4030+ }
4031+ break;
4032+ case PARSE_COOKIE:
4033+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
4034+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
4035+ return 0;
4036+ }
4037+ break;
4038+ case PARSE_POST:
4039+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
4040+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
4041+ return 0;
4042+ }
4043+ break;
4044+ }
4045+ prev_index = index;
4046+ }
4047+
4048+ }
4049+
4050+ /* Drop this variable if it exceeds the array depth limit */
4051+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
4052+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
4053+ return 0;
4054+ }
4055+ switch (arg) {
4056+ case PARSE_GET:
4057+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
4058+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
4059+ return 0;
4060+ }
4061+ break;
4062+ case PARSE_COOKIE:
4063+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
4064+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
4065+ return 0;
4066+ }
4067+ break;
4068+ case PARSE_POST:
4069+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
4070+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
4071+ return 0;
4072+ }
4073+ break;
4074+ }
4075+
4076+ /* Check if variable value is truncated by a \0 */
4077+
4078+ if (val && *val && val_len != strlen(*val)) {
4079+
4080+ if (VARFILTER_G(disallow_nul)) {
4081+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
4082+ return 0;
4083+ }
4084+ switch (arg) {
4085+ case PARSE_GET:
4086+ if (VARFILTER_G(disallow_get_nul)) {
4087+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
4088+ return 0;
4089+ }
4090+ break;
4091+ case PARSE_COOKIE:
4092+ if (VARFILTER_G(disallow_cookie_nul)) {
4093+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
4094+ return 0;
4095+ }
4096+ break;
4097+ case PARSE_POST:
4098+ if (VARFILTER_G(disallow_post_nul)) {
4099+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
4100+ return 0;
4101+ }
4102+ break;
4103+ }
4104+ }
4105+
4106+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
4107+ /* This is to protect several silly scripts that do globalizing themself */
4108+
4109+ switch (var_len) {
4110+ case 18:
4111+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
4112+ break;
4113+ case 17:
4114+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
4115+ break;
4116+ case 16:
4117+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
4118+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
4119+ break;
4120+ case 15:
4121+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
4122+ break;
4123+ case 14:
4124+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
4125+ break;
4126+ case 13:
4127+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
4128+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
4129+ break;
4130+ case 8:
4131+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
4132+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
4133+ break;
4134+ case 7:
4135+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
4136+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
4137+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
4138+ break;
4139+ case 6:
4140+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
4141+ break;
4142+ case 5:
4143+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
4144+ break;
4145+ case 4:
4146+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
4147+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
4148+ break;
4149+ }
4150+
4151+ /* Okay let PHP register this variable */
4152+ VARFILTER_G(cur_request_variables)++;
4153+ switch (arg) {
4154+ case PARSE_GET:
4155+ VARFILTER_G(cur_get_vars)++;
4156+ break;
4157+ case PARSE_COOKIE:
4158+ VARFILTER_G(cur_cookie_vars)++;
4159+ break;
4160+ case PARSE_POST:
4161+ VARFILTER_G(cur_post_vars)++;
4162+ break;
4163+ }
4164+
4165+ if (new_val_len) {
4166+ *new_val_len = val_len;
4167+ }
4168+
4169+ return 1;
4170+protected_varname:
4171+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
4172+ return 0;
4173+}
4174+/* }}} */
4175+
4176+/*
4177+ * Local variables:
4178+ * tab-width: 4
4179+ * c-basic-offset: 4
4180+ * End:
4181+ * vim600: noet sw=4 ts=4 fdm=marker
4182+ * vim<600: noet sw=4 ts=4
4183+ */
4184+
4185+
4186diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.9/main/fopen_wrappers.c
4187--- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100
4188+++ hardening-patch-4.4.2-0.4.9/main/fopen_wrappers.c 2006-05-02 17:00:53.000000000 +0200
4189@@ -124,6 +124,12 @@
4190 }
4191 }
4192
4193+ if (resolved_name_len == resolved_basedir_len - 1) {
4194+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4195+ resolved_basedir_len--;
4196+ }
4197+ }
4198+
4199 /* Check the path */
4200 #ifdef PHP_WIN32
4201 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4202@@ -156,6 +162,21 @@
4203 char *pathbuf;
4204 char *ptr;
4205 char *end;
4206+ char path_copy[MAXPATHLEN];
4207+ int path_len;
4208+
4209+ /* Special case path ends with a trailing slash */
4210+ path_len = strlen(path);
4211+ if (path_len >= MAXPATHLEN) {
4212+ errno = EPERM; /* we deny permission to open it */
4213+ return -1;
4214+ }
4215+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4216+ memcpy(path_copy, path, path_len+1);
4217+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4218+ path_copy[path_len] = '\0';
4219+ path = (const char *)&path_copy;
4220+ }
4221
4222 pathbuf = estrdup(PG(open_basedir));
4223
4224diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.9/main/hardened_globals.h
4225--- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4226+++ hardening-patch-4.4.2-0.4.9/main/hardened_globals.h 2006-05-02 16:46:34.000000000 +0200
4227@@ -0,0 +1,62 @@
4228+/*
4229+ +----------------------------------------------------------------------+
4230+ | Hardening-Patch for PHP |
4231+ +----------------------------------------------------------------------+
4232+ | Copyright (c) 2004-2005 Stefan Esser |
4233+ +----------------------------------------------------------------------+
4234+ | This source file is subject to version 2.02 of the PHP license, |
4235+ | that is bundled with this package in the file LICENSE, and is |
4236+ | available at through the world-wide-web at |
4237+ | http://www.php.net/license/2_02.txt. |
4238+ | If you did not receive a copy of the PHP license and are unable to |
4239+ | obtain it through the world-wide-web, please send a note to |
4240+ | license@php.net so we can mail you a copy immediately. |
4241+ +----------------------------------------------------------------------+
4242+ | Author: Stefan Esser <sesser@hardened-php.net> |
4243+ +----------------------------------------------------------------------+
4244+ */
4245+
4246+#ifndef HARDENED_GLOBALS_H
4247+#define HARDENED_GLOBALS_H
4248+
4249+typedef struct _hardened_globals hardened_globals_struct;
4250+
4251+#ifdef ZTS
4252+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4253+extern int hardened_globals_id;
4254+#else
4255+# define HG(v) (hardened_globals.v)
4256+extern struct _hardened_globals hardened_globals;
4257+#endif
4258+
4259+
4260+struct _hardened_globals {
4261+#if HARDENING_PATCH_MM_PROTECT
4262+ unsigned int canary_1;
4263+ unsigned int canary_2;
4264+#endif
4265+#if HARDENING_PATCH_LL_PROTECT
4266+ unsigned int canary_3;
4267+ unsigned int canary_4;
4268+ unsigned int ll_canary_inited;
4269+#endif
4270+ zend_bool hphp_sql_bailout_on_error;
4271+ zend_bool hphp_multiheader;
4272+ HashTable *eval_whitelist;
4273+ HashTable *eval_blacklist;
4274+ HashTable *func_whitelist;
4275+ HashTable *func_blacklist;
4276+ HashTable *include_whitelist;
4277+ HashTable *include_blacklist;
4278+ unsigned int dummy;
4279+};
4280+
4281+
4282+#endif /* HARDENED_GLOBALS_H */
4283+
4284+/*
4285+ * Local variables:
4286+ * tab-width: 4
4287+ * c-basic-offset: 4
4288+ * End:
4289+ */
4290diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.9/main/hardening_patch.c
4291--- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4292+++ hardening-patch-4.4.2-0.4.9/main/hardening_patch.c 2006-05-02 16:46:34.000000000 +0200
4293@@ -0,0 +1,430 @@
4294+/*
4295+ +----------------------------------------------------------------------+
4296+ | Hardening Patch for PHP |
4297+ +----------------------------------------------------------------------+
4298+ | Copyright (c) 2004-2005 Stefan Esser |
4299+ +----------------------------------------------------------------------+
4300+ | This source file is subject to version 2.02 of the PHP license, |
4301+ | that is bundled with this package in the file LICENSE, and is |
4302+ | available at through the world-wide-web at |
4303+ | http://www.php.net/license/2_02.txt. |
4304+ | If you did not receive a copy of the PHP license and are unable to |
4305+ | obtain it through the world-wide-web, please send a note to |
4306+ | license@php.net so we can mail you a copy immediately. |
4307+ +----------------------------------------------------------------------+
4308+ | Author: Stefan Esser <sesser@hardened-php.net> |
4309+ +----------------------------------------------------------------------+
4310+ */
4311+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4312+
4313+#include "php.h"
4314+
4315+#include <stdio.h>
4316+#include <stdlib.h>
4317+
4318+#if HAVE_UNISTD_H
4319+#include <unistd.h>
4320+#endif
4321+#include "SAPI.h"
4322+#include "php_globals.h"
4323+
4324+#if HARDENING_PATCH
4325+
4326+#ifdef HAVE_SYS_SOCKET_H
4327+#include <sys/socket.h>
4328+#endif
4329+
4330+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4331+#undef AF_UNIX
4332+#endif
4333+
4334+#if defined(AF_UNIX)
4335+#include <sys/un.h>
4336+#endif
4337+
4338+#define SYSLOG_PATH "/dev/log"
4339+
4340+#include "snprintf.h"
4341+
4342+#include "hardening_patch.h"
4343+
4344+#ifdef ZTS
4345+#include "hardened_globals.h"
4346+int hardened_globals_id;
4347+#else
4348+struct _hardened_globals hardened_globals;
4349+#endif
4350+
4351+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4352+{
4353+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4354+}
4355+
4356+
4357+PHPAPI void hardened_startup()
4358+{
4359+#ifdef ZTS
4360+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4361+#else
4362+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4363+#endif
4364+}
4365+
4366+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4367+{
4368+ HG(canary_1) = php_canary();
4369+ HG(canary_2) = php_canary();
4370+}
4371+
4372+char *loglevel2string(int loglevel)
4373+{
4374+ switch (loglevel) {
4375+ case S_FILES:
4376+ return "FILES";
4377+ case S_INCLUDE:
4378+ return "INCLUDE";
4379+ case S_MEMORY:
4380+ return "MEMORY";
4381+ case S_MISC:
4382+ return "MISC";
4383+ case S_SQL:
4384+ return "SQL";
4385+ case S_EXECUTOR:
4386+ return "EXECUTOR";
4387+ case S_VARS:
4388+ return "VARS";
4389+ default:
4390+ return "UNKNOWN";
4391+ }
4392+}
4393+
4394+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4395+{
4396+#if defined(AF_UNIX)
4397+ int s, r, i=0;
4398+ struct sockaddr_un saun;
4399+ char buf[4096+64];
4400+ char error[4096+100];
4401+ char *ip_address;
4402+ char *fname;
4403+ int lineno;
4404+ va_list ap;
4405+ TSRMLS_FETCH();
4406+
4407+ if (EG(hphp_log_use_x_forwarded_for)) {
4408+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4409+ if (ip_address == NULL) {
4410+ ip_address = "X-FORWARDED-FOR not set";
4411+ }
4412+ } else {
4413+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4414+ if (ip_address == NULL) {
4415+ ip_address = "REMOTE_ADDR not set";
4416+ }
4417+ }
4418+
4419+
4420+ va_start(ap, fmt);
4421+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4422+ va_end(ap);
4423+ while (error[i]) {
4424+ if (error[i] < 32) error[i] = '.';
4425+ i++;
4426+ }
4427+
4428+ if (zend_is_executing(TSRMLS_C)) {
4429+ lineno = zend_get_executed_lineno(TSRMLS_C);
4430+ fname = zend_get_executed_filename(TSRMLS_C);
4431+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4432+ } else {
4433+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4434+ if (fname==NULL) {
4435+ fname = "unknown";
4436+ }
4437+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4438+ }
4439+
4440+ /* Syslog-Logging disabled? */
4441+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4442+ goto log_sapi;
4443+ }
4444+
4445+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4446+
4447+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4448+ if (s == -1) {
4449+ goto log_sapi;
4450+ }
4451+
4452+ memset(&saun, 0, sizeof(saun));
4453+ saun.sun_family = AF_UNIX;
4454+ strcpy(saun.sun_path, SYSLOG_PATH);
4455+ /*saun.sun_len = sizeof(saun);*/
4456+
4457+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4458+ if (r) {
4459+ close(s);
4460+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4461+ if (s == -1) {
4462+ goto log_sapi;
4463+ }
4464+
4465+ memset(&saun, 0, sizeof(saun));
4466+ saun.sun_family = AF_UNIX;
4467+ strcpy(saun.sun_path, SYSLOG_PATH);
4468+ /*saun.sun_len = sizeof(saun);*/
4469+
4470+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4471+ if (r) {
4472+ close(s);
4473+ goto log_sapi;
4474+ }
4475+ }
4476+ send(s, error, strlen(error), 0);
4477+
4478+ close(s);
4479+
4480+log_sapi:
4481+ /* SAPI Logging activated? */
4482+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4483+ sapi_module.log_message(buf);
4484+ }
4485+
4486+log_script:
4487+ /* script logging activaed? */
4488+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4489+ char cmd[8192], *cmdpos, *bufpos;
4490+ FILE *in;
4491+ int space;
4492+
4493+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4494+ space = sizeof(cmd) - strlen(cmd);
4495+ cmdpos = cmd + strlen(cmd);
4496+ bufpos = buf;
4497+ if (space <= 1) return;
4498+ while (space > 2 && *bufpos) {
4499+ if (*bufpos == '\'') {
4500+ if (space<=5) break;
4501+ *cmdpos++ = '\'';
4502+ *cmdpos++ = '\\';
4503+ *cmdpos++ = '\'';
4504+ *cmdpos++ = '\'';
4505+ bufpos++;
4506+ space-=4;
4507+ } else {
4508+ *cmdpos++ = *bufpos++;
4509+ space--;
4510+ }
4511+ }
4512+ *cmdpos++ = '\'';
4513+ *cmdpos = 0;
4514+
4515+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4516+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4517+ return;
4518+ }
4519+ /* read and forget the result */
4520+ while (1) {
4521+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4522+ if (readbytes<=0) {
4523+ break;
4524+ }
4525+ }
4526+ pclose(in);
4527+ }
4528+
4529+#endif
4530+}
4531+#endif
4532+
4533+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4534+
4535+/* will be replaced later with more compatible method */
4536+PHPAPI unsigned int php_canary()
4537+{
4538+ time_t t;
4539+ unsigned int canary;
4540+ int fd;
4541+
4542+ fd = open("/dev/urandom", 0);
4543+ if (fd != -1) {
4544+ int r = read(fd, &canary, sizeof(canary));
4545+ close(fd);
4546+ if (r == sizeof(canary)) {
4547+ return (canary);
4548+ }
4549+ }
4550+ /* not good but we never want to do this */
4551+ time(&t);
4552+ canary = *(unsigned int *)&t + getpid() << 16;
4553+ return (canary);
4554+}
4555+#endif
4556+
4557+#if HARDENING_PATCH_INC_PROTECT
4558+
4559+PHPAPI int php_is_valid_include(zval *z)
4560+{
4561+ char *filename;
4562+ int len, i;
4563+ TSRMLS_FETCH();
4564+
4565+ /* must be of type string */
4566+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4567+ return (0);
4568+ }
4569+
4570+ /* short cut */
4571+ filename = z->value.str.val;
4572+ len = z->value.str.len;
4573+
4574+ /* 1. must be shorter than MAXPATHLEN */
4575+ if (len > MAXPATHLEN) {
4576+ char *fname = estrndup(filename, len);
4577+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4578+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4579+ efree(fname);
4580+ return (0);
4581+ }
4582+
4583+ /* 2. must not be cutted */
4584+ if (len != strlen(filename)) {
4585+ char *fname = estrndup(filename, len);
4586+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4587+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4588+ efree(fname);
4589+ return (0);
4590+ }
4591+
4592+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4593+ if (strstr(filename, "://")) {
4594+ char *fname = estrndup(filename, len);
4595+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4596+
4597+ /* no black or whitelist then disallow all */
4598+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4599+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4600+ efree(fname);
4601+ return (0);
4602+ }
4603+
4604+ /* whitelist is stronger than blacklist */
4605+ if (HG(include_whitelist)) {
4606+ char *s, *t, *h, *index;
4607+ uint indexlen;
4608+ ulong numindex;
4609+
4610+ s = filename;
4611+
4612+ do {
4613+ zend_bool isOk = 0;
4614+ int tlen;
4615+
4616+ t = h = strstr(s, "://");
4617+ if (h == NULL) break;
4618+
4619+
4620+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4621+ t--;
4622+ }
4623+
4624+ tlen = strlen(t);
4625+
4626+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4627+ do {
4628+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4629+
4630+ if (r==HASH_KEY_NON_EXISTANT) {
4631+ break;
4632+ }
4633+ if (r==HASH_KEY_IS_STRING) {
4634+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4635+ if (strncmp(t, index, indexlen-1)==0) {
4636+ isOk = 1;
4637+ break;
4638+ }
4639+ }
4640+ }
4641+
4642+ zend_hash_move_forward(HG(include_whitelist));
4643+ } while (1);
4644+
4645+ /* not found in whitelist */
4646+ if (!isOk) {
4647+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4648+ efree(fname);
4649+ return 0;
4650+ }
4651+
4652+ s = h + 3;
4653+ } while (1);
4654+ } else {
4655+ /* okay then handle the blacklist */
4656+ char *s, *t, *h, *index;
4657+ uint indexlen;
4658+ ulong numindex;
4659+
4660+ s = filename;
4661+
4662+ do {
4663+ int tlen;
4664+
4665+ t = h = strstr(s, "://");
4666+ if (h == NULL) break;
4667+
4668+
4669+ while (t > s) {
4670+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4671+ }
4672+
4673+ tlen = strlen(t);
4674+
4675+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4676+ do {
4677+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4678+
4679+ if (r==HASH_KEY_NON_EXISTANT) {
4680+ break;
4681+ }
4682+ if (r==HASH_KEY_IS_STRING) {
4683+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4684+ if (strncmp(t, index, indexlen-1)==0) {
4685+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4686+ efree(fname);
4687+ return 0;
4688+ }
4689+ }
4690+ }
4691+
4692+ zend_hash_move_forward(HG(include_blacklist));
4693+ } while (1);
4694+
4695+ s = h + 3;
4696+ } while (1);
4697+ }
4698+
4699+ efree(fname);
4700+ }
4701+
4702+ /* 4. must not be an uploaded file */
4703+ if (SG(rfc1867_uploaded_files)) {
4704+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4705+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4706+ return (0);
4707+ }
4708+ }
4709+
4710+ /* passed all tests */
4711+ return (1);
4712+}
4713+
4714+#endif
4715+
4716+/*
4717+ * Local variables:
4718+ * tab-width: 4
4719+ * c-basic-offset: 4
4720+ * End:
4721+ * vim600: sw=4 ts=4 fdm=marker
4722+ * vim<600: sw=4 ts=4
4723+ */
4724diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.9/main/hardening_patch.h
4725--- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4726+++ hardening-patch-4.4.2-0.4.9/main/hardening_patch.h 2006-05-02 16:54:23.000000000 +0200
4727@@ -0,0 +1,46 @@
4728+/*
4729+ +----------------------------------------------------------------------+
4730+ | Hardening Patch for PHP |
4731+ +----------------------------------------------------------------------+
4732+ | Copyright (c) 2004-2005 Stefan Esser |
4733+ +----------------------------------------------------------------------+
4734+ | This source file is subject to version 2.02 of the PHP license, |
4735+ | that is bundled with this package in the file LICENSE, and is |
4736+ | available at through the world-wide-web at |
4737+ | http://www.php.net/license/2_02.txt. |
4738+ | If you did not receive a copy of the PHP license and are unable to |
4739+ | obtain it through the world-wide-web, please send a note to |
4740+ | license@php.net so we can mail you a copy immediately. |
4741+ +----------------------------------------------------------------------+
4742+ | Author: Stefan Esser <sesser@hardened-php.net> |
4743+ +----------------------------------------------------------------------+
4744+ */
4745+
4746+#ifndef HARDENING_PATCH_H
4747+#define HARDENING_PATCH_H
4748+
4749+#include "zend.h"
4750+
4751+#if HARDENING_PATCH
4752+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4753+PHPAPI void hardened_startup();
4754+#define HARDENING_PATCH_VERSION "0.4.9"
4755+
4756+#endif
4757+
4758+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4759+PHPAPI unsigned int php_canary();
4760+#endif
4761+
4762+#if HARDENING_PATCH_INC_PROTECT
4763+PHPAPI int php_is_valid_include(zval *z);
4764+#endif
4765+
4766+#endif /* HARDENING_PATCH_H */
4767+
4768+/*
4769+ * Local variables:
4770+ * tab-width: 4
4771+ * c-basic-offset: 4
4772+ * End:
4773+ */
4774diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.9/main/hardening_patch.m4
4775--- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4776+++ hardening-patch-4.4.2-0.4.9/main/hardening_patch.m4 2006-05-02 16:46:34.000000000 +0200
4777@@ -0,0 +1,95 @@
4778+dnl
4779+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4780+dnl
4781+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4782+dnl
4783+
4784+AC_ARG_ENABLE(hardening-patch-mm-protect,
4785+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4786+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4787+],[
4788+ DO_HARDENING_PATCH_MM_PROTECT=yes
4789+])
4790+
4791+AC_ARG_ENABLE(hardening-patch-ll-protect,
4792+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4793+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4794+],[
4795+ DO_HARDENING_PATCH_LL_PROTECT=yes
4796+])
4797+
4798+AC_ARG_ENABLE(hardening-patch-inc-protect,
4799+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4800+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4801+],[
4802+ DO_HARDENING_PATCH_INC_PROTECT=yes
4803+])
4804+
4805+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4806+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4807+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4808+],[
4809+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4810+])
4811+
4812+AC_ARG_ENABLE(hardening-patch-hash-protect,
4813+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4814+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4815+],[
4816+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4817+])
4818+
4819+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4820+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4821+
4822+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4823+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4824+
4825+AC_MSG_CHECKING(whether to protect include/require statements)
4826+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4827+
4828+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4829+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4830+
4831+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4832+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4833+
4834+
4835+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4836+
4837+
4838+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4839+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4840+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4841+else
4842+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4843+fi
4844+
4845+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4846+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4847+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4848+else
4849+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4850+fi
4851+
4852+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4853+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4854+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4855+else
4856+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4857+fi
4858+
4859+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4860+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4861+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4862+else
4863+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4864+fi
4865+
4866+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4867+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4868+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4869+else
4870+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4871+fi
4872+
4873diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.9/main/main.c
4874--- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100
4875+++ hardening-patch-4.4.2-0.4.9/main/main.c 2006-05-02 16:46:34.000000000 +0200
4876@@ -92,6 +92,10 @@
4877 PHPAPI int core_globals_id;
4878 #endif
4879
4880+#if HARDENING_PATCH
4881+#include "hardened_globals.h"
4882+#endif
4883+
4884 #define ERROR_BUF_LEN 1024
4885
4886 typedef struct {
4887@@ -142,10 +146,33 @@
4888 */
4889 static PHP_INI_MH(OnChangeMemoryLimit)
4890 {
4891+#if HARDENING_PATCH
4892+ long orig_memory_limit;
4893+
4894+ if (entry->modified) {
4895+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4896+ } else {
4897+ orig_memory_limit = 1<<30;
4898+ }
4899+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4900+ orig_memory_limit = 1<<30;
4901+ }
4902+#endif
4903 if (new_value) {
4904 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4905+#if HARDENING_PATCH
4906+ if (PG(memory_limit) > orig_memory_limit) {
4907+ PG(memory_limit) = orig_memory_limit;
4908+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4909+ return FAILURE;
4910+ }
4911+#endif
4912 } else {
4913+#if HARDENING_PATCH
4914+ PG(memory_limit) = orig_memory_limit;
4915+#else
4916 PG(memory_limit) = 1<<30; /* effectively, no limit */
4917+#endif
4918 }
4919 return zend_set_memory_limit(PG(memory_limit));
4920 }
4921@@ -1008,6 +1035,9 @@
4922
4923 zend_try {
4924 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4925+#if HARDENING_PATCH
4926+ hardened_clear_mm_canaries(TSRMLS_C);
4927+#endif
4928 } zend_end_try();
4929
4930 zend_try {
4931@@ -1098,6 +1128,10 @@
4932 tsrm_ls = ts_resource(0);
4933 #endif
4934
4935+#if HARDENING_PATCH
4936+ hardened_startup();
4937+#endif
4938+
4939 sapi_initialize_empty_request(TSRMLS_C);
4940 sapi_activate(TSRMLS_C);
4941
4942@@ -1110,6 +1144,12 @@
4943 php_output_startup();
4944 php_output_activate(TSRMLS_C);
4945
4946+#if HARDENING_PATCH_INC_PROTECT
4947+ zuf.is_valid_include = php_is_valid_include;
4948+#endif
4949+#if HARDENING_PATCH
4950+ zuf.security_log_function = php_security_log;
4951+#endif
4952 zuf.error_function = php_error_cb;
4953 zuf.printf_function = php_printf;
4954 zuf.write_function = php_body_write_wrapper;
4955@@ -1211,6 +1251,10 @@
4956 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4957 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);
4958 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4959+#if HARDENING_PATCH
4960+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4961+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4962+#endif
4963 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4964 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4965 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4966@@ -1318,7 +1362,7 @@
4967 */
4968 static inline void php_register_server_variables(TSRMLS_D)
4969 {
4970- zval *array_ptr=NULL;
4971+ zval *array_ptr=NULL, *vptr;
4972
4973 ALLOC_ZVAL(array_ptr);
4974 array_init(array_ptr);
4975diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.9/main/php_config.h.in
4976--- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100
4977+++ hardening-patch-4.4.2-0.4.9/main/php_config.h.in 2006-05-02 16:46:34.000000000 +0200
4978@@ -865,6 +865,39 @@
4979 /* Enabling BIND8 compatibility for Panther */
4980 #undef BIND_8_COMPAT
4981
4982+/* Hardening-Patch */
4983+#undef HARDENING_PATCH
4984+
4985+/* Memory Manager Protection */
4986+#undef HARDENING_PATCH_MM_PROTECT
4987+
4988+/* Memory Manager Protection */
4989+#undef HARDENING_PATCH_MM_PROTECT
4990+
4991+/* Linked List Protection */
4992+#undef HARDENING_PATCH_LL_PROTECT
4993+
4994+/* Linked List Protection */
4995+#undef HARDENING_PATCH_LL_PROTECT
4996+
4997+/* Include/Require Protection */
4998+#undef HARDENING_PATCH_INC_PROTECT
4999+
5000+/* Include/Require Protection */
5001+#undef HARDENING_PATCH_INC_PROTECT
5002+
5003+/* Fmt String Protection */
5004+#undef HARDENING_PATCH_FMT_PROTECT
5005+
5006+/* Fmt String Protection */
5007+#undef HARDENING_PATCH_FMT_PROTECT
5008+
5009+/* HashTable DTOR Protection */
5010+#undef HARDENING_PATCH_HASH_PROTECT
5011+
5012+/* HashTable DTOR Protection */
5013+#undef HARDENING_PATCH_HASH_PROTECT
5014+
5015 /* Whether you have AOLserver */
5016 #undef HAVE_AOLSERVER
5017
5018@@ -1148,6 +1181,12 @@
5019 /* Define if you have the getaddrinfo function */
5020 #undef HAVE_GETADDRINFO
5021
5022+/* Whether realpath is broken */
5023+#undef PHP_BROKEN_REALPATH
5024+
5025+/* Whether realpath is broken */
5026+#undef PHP_BROKEN_REALPATH
5027+
5028 /* Whether system headers declare timezone */
5029 #undef HAVE_DECLARED_TIMEZONE
5030
5031diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.9/main/php_content_types.c
5032--- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100
5033+++ hardening-patch-4.4.2-0.4.9/main/php_content_types.c 2006-05-02 16:46:34.000000000 +0200
5034@@ -77,6 +77,7 @@
5035 sapi_register_post_entries(php_post_entries);
5036 sapi_register_default_post_reader(php_default_post_reader);
5037 sapi_register_treat_data(php_default_treat_data);
5038+ sapi_register_input_filter(php_default_input_filter);
5039 return SUCCESS;
5040 }
5041 /* }}} */
5042diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.9/main/php.h
5043--- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100
5044+++ hardening-patch-4.4.2-0.4.9/main/php.h 2006-05-02 16:46:34.000000000 +0200
5045@@ -35,11 +35,19 @@
5046 #include "zend_qsort.h"
5047 #include "php_compat.h"
5048
5049+
5050 #include "zend_API.h"
5051
5052 #undef sprintf
5053 #define sprintf php_sprintf
5054
5055+#if HARDENING_PATCH
5056+#if HAVE_REALPATH
5057+#undef realpath
5058+#define realpath php_realpath
5059+#endif
5060+#endif
5061+
5062 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
5063 #undef PHP_DEBUG
5064 #define PHP_DEBUG ZEND_DEBUG
5065@@ -409,6 +417,10 @@
5066 #endif
5067 #endif /* !XtOffsetOf */
5068
5069+#if HARDENING_PATCH
5070+#include "hardening_patch.h"
5071+#endif
5072+
5073 #endif
5074
5075 /*
5076diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.9/main/php_variables.c
5077--- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100
5078+++ hardening-patch-4.4.2-0.4.9/main/php_variables.c 2006-05-02 16:46:34.000000000 +0200
5079@@ -236,17 +236,28 @@
5080 while (var) {
5081 val = strchr(var, '=');
5082 if (val) { /* have a value */
5083- int val_len;
5084+ unsigned int val_len, new_val_len;
5085
5086 *val++ = '\0';
5087 php_url_decode(var, strlen(var));
5088 val_len = php_url_decode(val, strlen(val));
5089- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5090+ val = estrndup(val, val_len);
5091+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5092+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5093+ }
5094+ efree(val);
5095 }
5096 var = php_strtok_r(NULL, "&", &strtok_buf);
5097 }
5098 }
5099
5100+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
5101+{
5102+ /* TODO: check .ini setting here and apply user-defined input filter */
5103+ *new_val_len = val_len;
5104+ return 1;
5105+}
5106+
5107 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
5108 {
5109 char *res = NULL, *var, *val, *separator=NULL;
5110@@ -324,15 +335,26 @@
5111 while (var) {
5112 val = strchr(var, '=');
5113 if (val) { /* have a value */
5114- int val_len;
5115+ unsigned int val_len, new_val_len;
5116
5117 *val++ = '\0';
5118 php_url_decode(var, strlen(var));
5119 val_len = php_url_decode(val, strlen(val));
5120- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5121+ val = estrndup(val, val_len);
5122+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5123+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5124+ }
5125+ efree(val);
5126 } else {
5127+ unsigned int val_len, new_val_len;
5128+
5129 php_url_decode(var, strlen(var));
5130- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
5131+ val_len = 0;
5132+ val = estrndup("", 0);
5133+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5134+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5135+ }
5136+ efree(val);
5137 }
5138 var = php_strtok_r(NULL, separator, &strtok_buf);
5139 }
5140diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.9/main/rfc1867.c
5141--- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100
5142+++ hardening-patch-4.4.2-0.4.9/main/rfc1867.c 2006-05-02 16:46:34.000000000 +0200
5143@@ -128,6 +128,8 @@
5144 #define UPLOAD_ERROR_D 4 /* No file uploaded */
5145 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
5146 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
5147+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
5148+
5149
5150 void php_rfc1867_register_constants(TSRMLS_D)
5151 {
5152@@ -138,6 +140,7 @@
5153 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
5154 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
5155 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
5156+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
5157 }
5158
5159 static void normalize_protected_variable(char *varname TSRMLS_DC)
5160@@ -849,6 +852,7 @@
5161 char buff[FILLUNIT];
5162 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
5163 int blen=0, wlen=0;
5164+ unsigned long offset;
5165
5166 zend_llist_clean(&header);
5167
5168@@ -897,21 +901,24 @@
5169 if (!filename && param) {
5170
5171 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
5172+ unsigned int new_val_len; /* Dummy variable */
5173
5174 if (!value) {
5175 value = estrdup("");
5176 }
5177
5178+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
5179 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
5180- if (php_mb_encoding_translation(TSRMLS_C)) {
5181- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5182- &num_vars, &num_vars_max TSRMLS_CC);
5183- } else {
5184- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5185- }
5186+ if (php_mb_encoding_translation(TSRMLS_C)) {
5187+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5188+ &num_vars, &num_vars_max TSRMLS_CC);
5189+ } else {
5190+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5191+ }
5192 #else
5193- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5194+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5195 #endif
5196+ }
5197 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
5198 max_file_size = atol(value);
5199 }
5200@@ -963,7 +970,11 @@
5201 tmp++;
5202 }
5203 }
5204-
5205+
5206+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
5207+ skip_upload = 1;
5208+ }
5209+
5210 total_bytes = cancel_upload = 0;
5211
5212 if (!skip_upload) {
5213@@ -987,6 +998,11 @@
5214 cancel_upload = UPLOAD_ERROR_D;
5215 }
5216
5217+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
5218+ cancel_upload = UPLOAD_ERROR_X;
5219+ }
5220+
5221+ offset = 0;
5222 end = 0;
5223 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
5224 {
5225@@ -997,6 +1013,11 @@
5226 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
5227 cancel_upload = UPLOAD_ERROR_B;
5228 } else if (blen > 0) {
5229+
5230+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
5231+ cancel_upload = UPLOAD_ERROR_X;
5232+ }
5233+
5234 wlen = write(fd, buff, blen);
5235
5236 if (wlen < blen) {
5237@@ -1004,6 +1025,7 @@
5238 cancel_upload = UPLOAD_ERROR_F;
5239 } else {
5240 total_bytes += wlen;
5241+ offset += wlen;
5242 }
5243 }
5244 }
5245@@ -1025,6 +1047,10 @@
5246 }
5247 #endif
5248
5249+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5250+ cancel_upload = UPLOAD_ERROR_X;
5251+ }
5252+
5253 if (cancel_upload) {
5254 if (temp_filename) {
5255 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5256diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.9/main/SAPI.c
5257--- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100
5258+++ hardening-patch-4.4.2-0.4.9/main/SAPI.c 2006-05-02 16:46:34.000000000 +0200
5259@@ -854,6 +854,37 @@
5260 return SUCCESS;
5261 }
5262
5263+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))
5264+{
5265+ sapi_module.input_filter = input_filter;
5266+ return SUCCESS;
5267+}
5268+
5269+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5270+{
5271+ sapi_module.upload_varname_filter = upload_varname_filter;
5272+ return SUCCESS;
5273+}
5274+
5275+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5276+{
5277+ sapi_module.pre_upload_filter = pre_upload_filter;
5278+ return SUCCESS;
5279+}
5280+
5281+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC))
5282+{
5283+ sapi_module.upload_content_filter = upload_content_filter;
5284+ return SUCCESS;
5285+}
5286+
5287+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5288+{
5289+ sapi_module.post_upload_filter = post_upload_filter;
5290+ return SUCCESS;
5291+}
5292+
5293+
5294
5295 SAPI_API int sapi_flush(TSRMLS_D)
5296 {
5297diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.9/main/SAPI.h
5298--- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100
5299+++ hardening-patch-4.4.2-0.4.9/main/SAPI.h 2006-05-02 16:46:34.000000000 +0200
5300@@ -101,9 +101,10 @@
5301 char *current_user;
5302 int current_user_length;
5303
5304- /* this is necessary for CLI module */
5305- int argc;
5306- char **argv;
5307+ /* this is necessary for CLI module */
5308+ int argc;
5309+ char **argv;
5310+
5311 } sapi_request_info;
5312
5313
5314@@ -177,6 +178,10 @@
5315 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5316 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5317 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5318+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));
5319+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5320+SAPI_API int sapi_register_upload_content_filter(unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC));
5321+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5322
5323 SAPI_API int sapi_flush(TSRMLS_D);
5324 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5325@@ -238,8 +243,16 @@
5326 int (*get_target_uid)(uid_t * TSRMLS_DC);
5327 int (*get_target_gid)(gid_t * TSRMLS_DC);
5328
5329+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5330+
5331+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5332+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5333+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5334+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5335+
5336 void (*ini_defaults)(HashTable *configuration_hash);
5337 int phpinfo_as_text;
5338+
5339 };
5340
5341
5342@@ -262,16 +275,27 @@
5343
5344 #define SAPI_DEFAULT_MIMETYPE "text/html"
5345 #define SAPI_DEFAULT_CHARSET ""
5346+
5347+#if HARDENING_PATCH
5348+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5349+#else
5350 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5351+#endif
5352
5353 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5354 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5355
5356 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5357+#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)
5358+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5359+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5360+#define SAPI_UPLOAD_CONTENT_FILTER_FUNC(upload_content_filter) unsigned int upload_content_filter(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC)
5361+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5362
5363 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5364 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5365 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5366+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5367
5368 #define STANDARD_SAPI_MODULE_PROPERTIES
5369
5370diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.9/main/snprintf.c
5371--- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100
5372+++ hardening-patch-4.4.2-0.4.9/main/snprintf.c 2006-05-02 16:46:34.000000000 +0200
5373@@ -1014,7 +1014,11 @@
5374
5375
5376 case 'n':
5377+#if HARDENING_PATCH_FMT_PROTECT
5378+ php_security_log(S_MISC, "'n' specifier within format string");
5379+#else
5380 *(va_arg(ap, int *)) = cc;
5381+#endif
5382 break;
5383
5384 /*
5385diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.9/main/spprintf.c
5386--- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100
5387+++ hardening-patch-4.4.2-0.4.9/main/spprintf.c 2006-05-02 16:46:34.000000000 +0200
5388@@ -630,7 +630,11 @@
5389
5390
5391 case 'n':
5392+#if HARDENING_PATCH_FMT_PROTECT
5393+ php_security_log(S_MISC, "'n' specifier within format string");
5394+#else
5395 *(va_arg(ap, int *)) = xbuf->len;
5396+#endif
5397 break;
5398
5399 /*
5400diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.9/php.ini-dist
5401--- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100
5402+++ hardening-patch-4.4.2-0.4.9/php.ini-dist 2006-05-02 16:46:34.000000000 +0200
5403@@ -1114,6 +1114,209 @@
5404 ;exif.decode_jis_motorola = JIS
5405 ;exif.decode_jis_intel = JIS
5406
5407+[hardening-patch]
5408+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5409+; Hardening-Patch's logging ;
5410+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5411+
5412+;
5413+; hphp.log.syslog - Configures level for alerts reported through syslog
5414+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5415+; hphp.log.script - Configures level for alerts reported through external script
5416+;
5417+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5418+; Or each number up to get desired Hardening-Patch's reporting level
5419+;
5420+; S_ALL - All alerts
5421+; S_MEMORY - All canary violations and the safe unlink protection use this class
5422+; S_VARS - All variable filters trigger this class
5423+; S_FILES - All violation of uploaded files filter use this class
5424+; S_INCLUDE - The protection against malicious include filenames use this class
5425+; S_SQL - Failed SQL queries in MySQL are logged with this class
5426+; S_EXECUTOR - The execution depth protection uses this logging class
5427+; S_MISC - All other log messages (f.e. format string protection) use this class
5428+;
5429+; Example:
5430+;
5431+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5432+; memory alerts through syslog and SQL+Include alerts fo the script
5433+;
5434+;hphp.log.syslog = S_MEMORY
5435+;hphp.log.sapi = S_ALL & ~S_MEMORY
5436+;hphp.log.script = S_INCLUDE | S_SQL
5437+;
5438+; Syslog logging:
5439+;
5440+; - Facility configuration: one of the following facilities
5441+;
5442+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5443+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5444+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5445+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5446+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5447+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5448+; LOG_PERROR
5449+;
5450+; - Priority configuration: one of the followinf priorities
5451+;
5452+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5453+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5454+;
5455+hphp.log.syslog.priority = LOG_ALERT
5456+hphp.log.syslog.facility = LOG_USER
5457+;
5458+; Script logging:
5459+;
5460+;hphp.log.script.name = /home/hphp/log_script
5461+;
5462+; Alert configuration:
5463+;
5464+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5465+;
5466+;hphp.log.use-x-forwarded-for = On
5467+;
5468+
5469+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5470+; Hardening-Patch's Executor options ;
5471+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5472+
5473+; Execution depth limit
5474+;hphp.executor.max_depth = 8000
5475+
5476+; White-/blacklist for function calls during normal execution
5477+;hphp.executor.func.whitelist = ord,chr
5478+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5479+
5480+; White-/blacklist for function calls during eval() execution
5481+;hphp.executor.eval.whitelist = ord,chr
5482+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5483+
5484+; White-/blacklist for URLs allowes in include filenames
5485+;
5486+; - When both options are not set all URLs are forbidden
5487+;
5488+; - When both options are set whitelist is taken and blacklist ignored
5489+;
5490+; - An entry in the lists is either a URL sheme like: http, https
5491+; or the beginning of an URL like: php://input
5492+;
5493+;hphp.executor.include.whitelist = cookietest
5494+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5495+
5496+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5497+; Hardening-Patch's REQUEST variable filters ;
5498+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5499+
5500+; Limits the number of REQUEST variables
5501+hphp.request.max_vars = 200
5502+
5503+; Limits the length of variable names (without indices)
5504+hphp.request.max_varname_length = 64
5505+
5506+; Limits the length of complete variable names (with indices)
5507+hphp.request.max_totalname_length = 256
5508+
5509+; Limits the length of array indices
5510+hphp.request.max_array_index_length = 64
5511+
5512+; Limits the depth of arrays
5513+hphp.request.max_array_depth = 100
5514+
5515+; Limits the length of variable values
5516+hphp.request.max_value_length = 65000
5517+
5518+; Disallow ASCII-NUL characters in input
5519+hphp.request.disallow_nul = 1
5520+
5521+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5522+; Hardening-Patch's COOKIE variable filters ;
5523+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5524+
5525+; Limits the number of COOKIE variables
5526+hphp.cookie.max_vars = 100
5527+
5528+; Limits the length of variable names (without indices)
5529+hphp.cookie.max_name_length = 64
5530+
5531+; Limits the length of complete variable names (with indices)
5532+hphp.cookie.max_totalname_length = 256
5533+
5534+; Limits the length of array indices
5535+hphp.cookie.max_array_index_length = 64
5536+
5537+; Limits the depth of arrays
5538+hphp.cookie.max_array_depth = 100
5539+
5540+; Limits the length of variable values
5541+hphp.cookie.max_value_length = 10000
5542+
5543+; Disallow ASCII-NUL characters in input
5544+hphp.cookie.disallow_nul = 1
5545+
5546+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5547+; Hardening-Patch's GET variable filters ;
5548+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5549+
5550+; Limits the number of COOKIE variables
5551+hphp.get.max_vars = 100
5552+
5553+; Limits the length of variable names (without indices)
5554+hphp.get.max_name_length = 64
5555+
5556+; Limits the length of complete variable names (with indices)
5557+hphp.get.max_totalname_length = 256
5558+
5559+; Limits the length of array indices
5560+hphp.get.max_array_index_length = 64
5561+
5562+; Limits the depth of arrays
5563+hphp.get.max_array_depth = 50
5564+
5565+; Limits the length of variable values
5566+hphp.get.max_value_length = 512
5567+
5568+; Disallow ASCII-NUL characters in input
5569+hphp.get.disallow_nul = 1
5570+
5571+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5572+; Hardening-Patch's POST variable filters ;
5573+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5574+
5575+; Limits the number of POST variables
5576+hphp.post.max_vars = 200
5577+
5578+; Limits the length of variable names (without indices)
5579+hphp.post.max_name_length = 64
5580+
5581+; Limits the length of complete variable names (with indices)
5582+hphp.post.max_totalname_length = 256
5583+
5584+; Limits the length of array indices
5585+hphp.post.max_array_index_length = 64
5586+
5587+; Limits the depth of arrays
5588+hphp.post.max_array_depth = 100
5589+
5590+; Limits the length of variable values
5591+hphp.post.max_value_length = 65000
5592+
5593+; Disallow ASCII-NUL characters in input
5594+hphp.post.disallow_nul = 1
5595+
5596+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5597+; Hardening-Patch's fileupload variable filters ;
5598+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5599+
5600+; Limits the number of uploadable files
5601+hphp.upload.max_uploads = 25
5602+
5603+; Filter out the upload of ELF executables
5604+hphp.upload.disallow_elf_files = On
5605+
5606+; External filterscript for upload verification
5607+;hphp.upload.verification_script = /home/hphp/verify_script
5608+
5609+
5610 ; Local Variables:
5611 ; tab-width: 4
5612 ; End:
5613diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.9/php.ini-recommended
5614--- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100
5615+++ hardening-patch-4.4.2-0.4.9/php.ini-recommended 2006-05-02 16:46:34.000000000 +0200
5616@@ -1112,6 +1112,209 @@
5617 ;exif.decode_jis_motorola = JIS
5618 ;exif.decode_jis_intel = JIS
5619
5620+[hardening-patch]
5621+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5622+; Hardening-Patch's logging ;
5623+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5624+
5625+;
5626+; hphp.log.syslog - Configures level for alerts reported through syslog
5627+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5628+; hphp.log.script - Configures level for alerts reported through external script
5629+;
5630+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5631+; Or each number up to get desired Hardening-Patch's reporting level
5632+;
5633+; S_ALL - All alerts
5634+; S_MEMORY - All canary violations and the safe unlink protection use this class
5635+; S_VARS - All variable filters trigger this class
5636+; S_FILES - All violation of uploaded files filter use this class
5637+; S_INCLUDE - The protection against malicious include filenames use this class
5638+; S_SQL - Failed SQL queries in MySQL are logged with this class
5639+; S_EXECUTOR - The execution depth protection uses this logging class
5640+; S_MISC - All other log messages (f.e. format string protection) use this class
5641+;
5642+; Example:
5643+;
5644+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5645+; memory alerts through syslog and SQL+Include alerts fo the script
5646+;
5647+;hphp.log.syslog = S_MEMORY
5648+;hphp.log.sapi = S_ALL & ~S_MEMORY
5649+;hphp.log.script = S_INCLUDE | S_SQL
5650+;
5651+; Syslog logging:
5652+;
5653+; - Facility configuration: one of the following facilities
5654+;
5655+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5656+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5657+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5658+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5659+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5660+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5661+; LOG_PERROR
5662+;
5663+; - Priority configuration: one of the followinf priorities
5664+;
5665+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5666+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5667+;
5668+hphp.log.syslog.priority = LOG_ALERT
5669+hphp.log.syslog.facility = LOG_USER
5670+;
5671+; Script logging:
5672+;
5673+;hphp.log.script.name = /home/hphp/log_script
5674+;
5675+; Alert configuration:
5676+;
5677+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5678+;
5679+;hphp.log.use-x-forwarded-for = On
5680+;
5681+
5682+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5683+; Hardening-Patch's Executor options ;
5684+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5685+
5686+; Execution depth limit
5687+;hphp.executor.max_depth = 8000
5688+
5689+; White-/blacklist for function calls during normal execution
5690+;hphp.executor.func.whitelist = ord,chr
5691+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5692+
5693+; White-/blacklist for function calls during eval() execution
5694+;hphp.executor.eval.whitelist = ord,chr
5695+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5696+
5697+; White-/blacklist for URLs allowes in include filenames
5698+;
5699+; - When both options are not set all URLs are forbidden
5700+;
5701+; - When both options are set whitelist is taken and blacklist ignored
5702+;
5703+; - An entry in the lists is either a URL sheme like: http, https
5704+; or the beginning of an URL like: php://input
5705+;
5706+;hphp.executor.include.whitelist = cookietest
5707+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5708+
5709+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5710+; Hardening-Patch's REQUEST variable filters ;
5711+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5712+
5713+; Limits the number of REQUEST variables
5714+hphp.request.max_vars = 200
5715+
5716+; Limits the length of variable names (without indices)
5717+hphp.request.max_varname_length = 64
5718+
5719+; Limits the length of complete variable names (with indices)
5720+hphp.request.max_totalname_length = 256
5721+
5722+; Limits the length of array indices
5723+hphp.request.max_array_index_length = 64
5724+
5725+; Limits the depth of arrays
5726+hphp.request.max_array_depth = 100
5727+
5728+; Limits the length of variable values
5729+hphp.request.max_value_length = 65000
5730+
5731+; Disallow ASCII-NUL characters in input
5732+hphp.request.disallow_nul = 1
5733+
5734+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5735+; Hardening-Patch's COOKIE variable filters ;
5736+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5737+
5738+; Limits the number of COOKIE variables
5739+hphp.cookie.max_vars = 100
5740+
5741+; Limits the length of variable names (without indices)
5742+hphp.cookie.max_name_length = 64
5743+
5744+; Limits the length of complete variable names (with indices)
5745+hphp.cookie.max_totalname_length = 256
5746+
5747+; Limits the length of array indices
5748+hphp.cookie.max_array_index_length = 64
5749+
5750+; Limits the depth of arrays
5751+hphp.cookie.max_array_depth = 100
5752+
5753+; Limits the length of variable values
5754+hphp.cookie.max_value_length = 10000
5755+
5756+; Disallow ASCII-NUL characters in input
5757+hphp.cookie.disallow_nul = 1
5758+
5759+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5760+; Hardening-Patch's GET variable filters ;
5761+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5762+
5763+; Limits the number of COOKIE variables
5764+hphp.get.max_vars = 100
5765+
5766+; Limits the length of variable names (without indices)
5767+hphp.get.max_name_length = 64
5768+
5769+; Limits the length of complete variable names (with indices)
5770+hphp.get.max_totalname_length = 256
5771+
5772+; Limits the length of array indices
5773+hphp.get.max_array_index_length = 64
5774+
5775+; Limits the depth of arrays
5776+hphp.get.max_array_depth = 50
5777+
5778+; Limits the length of variable values
5779+hphp.get.max_value_length = 512
5780+
5781+; Disallow ASCII-NUL characters in input
5782+hphp.get.disallow_nul = 1
5783+
5784+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5785+; Hardening-Patch's POST variable filters ;
5786+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5787+
5788+; Limits the number of POST variables
5789+hphp.post.max_vars = 200
5790+
5791+; Limits the length of variable names (without indices)
5792+hphp.post.max_name_length = 64
5793+
5794+; Limits the length of complete variable names (with indices)
5795+hphp.post.max_totalname_length = 256
5796+
5797+; Limits the length of array indices
5798+hphp.post.max_array_index_length = 64
5799+
5800+; Limits the depth of arrays
5801+hphp.post.max_array_depth = 100
5802+
5803+; Limits the length of variable values
5804+hphp.post.max_value_length = 65000
5805+
5806+; Disallow ASCII-NUL characters in input
5807+hphp.post.disallow_nul = 1
5808+
5809+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5810+; Hardening-Patch's fileupload variable filters ;
5811+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5812+
5813+; Limits the number of uploadable files
5814+hphp.upload.max_uploads = 25
5815+
5816+; Filter out the upload of ELF executables
5817+hphp.upload.disallow_elf_files = On
5818+
5819+; External filterscript for upload verification
5820+;hphp.upload.verification_script = /home/hphp/verify_script
5821+
5822+
5823 ; Local Variables:
5824 ; tab-width: 4
5825 ; End:
5826diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.9/README.input_filter
5827--- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5828+++ hardening-patch-4.4.2-0.4.9/README.input_filter 2006-05-02 16:46:34.000000000 +0200
5829@@ -0,0 +1,193 @@
5830+Input Filter Support ported from PHP 5
5831+--------------------------------------
5832+
5833+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5834+and can be quite difficult to prevent. Whenever you accept user data
5835+and somehow display this data back to users, you are likely vulnerable
5836+to XSS hacks.
5837+
5838+The Input Filter support in PHP 5 is aimed at providing the framework
5839+through which a company-wide or site-wide security policy can be
5840+enforced. It is implemented as a SAPI hook and is called from the
5841+treat_data and post handler functions. To implement your own security
5842+policy you will need to write a standard PHP extension.
5843+
5844+A simple implementation might look like the following. This stores the
5845+original raw user data and adds a my_get_raw() function while the normal
5846+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5847+data. In this simple example all I am doing is calling strip_tags() on
5848+the data. If register_globals is turned on, the default globals that
5849+are created will be stripped ($foo) while a $RAW_foo is created with the
5850+original user input.
5851+
5852+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5853+ zval *post_array;
5854+ zval *get_array;
5855+ zval *cookie_array;
5856+ZEND_END_MODULE_GLOBALS(my_input_filter)
5857+
5858+#ifdef ZTS
5859+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5860+#else
5861+#define IF_G(v) (my_input_filter_globals.v)
5862+#endif
5863+
5864+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5865+
5866+function_entry my_input_filter_functions[] = {
5867+ PHP_FE(my_get_raw, NULL)
5868+ {NULL, NULL, NULL}
5869+};
5870+
5871+zend_module_entry my_input_filter_module_entry = {
5872+ STANDARD_MODULE_HEADER,
5873+ "my_input_filter",
5874+ my_input_filter_functions,
5875+ PHP_MINIT(my_input_filter),
5876+ PHP_MSHUTDOWN(my_input_filter),
5877+ NULL,
5878+ PHP_RSHUTDOWN(my_input_filter),
5879+ PHP_MINFO(my_input_filter),
5880+ "0.1",
5881+ STANDARD_MODULE_PROPERTIES
5882+};
5883+
5884+PHP_MINIT_FUNCTION(my_input_filter)
5885+{
5886+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5887+
5888+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5889+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5890+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5891+
5892+ sapi_register_input_filter(my_sapi_input_filter);
5893+ return SUCCESS;
5894+}
5895+
5896+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5897+{
5898+ if(IF_G(get_array)) {
5899+ zval_ptr_dtor(&IF_G(get_array));
5900+ IF_G(get_array) = NULL;
5901+ }
5902+ if(IF_G(post_array)) {
5903+ zval_ptr_dtor(&IF_G(post_array));
5904+ IF_G(post_array) = NULL;
5905+ }
5906+ if(IF_G(cookie_array)) {
5907+ zval_ptr_dtor(&IF_G(cookie_array));
5908+ IF_G(cookie_array) = NULL;
5909+ }
5910+ return SUCCESS;
5911+}
5912+
5913+PHP_MINFO_FUNCTION(my_input_filter)
5914+{
5915+ php_info_print_table_start();
5916+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5917+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5918+ php_info_print_table_end();
5919+}
5920+
5921+/* The filter handler. If you return 1 from it, then PHP also registers the
5922+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5923+ * you can use this if your filter already registers the variable under a
5924+ * different name, or if you just don't want the variable registered at all. */
5925+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5926+{
5927+ zval new_var;
5928+ zval *array_ptr = NULL;
5929+ char *raw_var;
5930+ int var_len;
5931+
5932+ assert(*val != NULL);
5933+
5934+ switch(arg) {
5935+ case PARSE_GET:
5936+ if(!IF_G(get_array)) {
5937+ ALLOC_ZVAL(array_ptr);
5938+ array_init(array_ptr);
5939+ INIT_PZVAL(array_ptr);
5940+ }
5941+ IF_G(get_array) = array_ptr;
5942+ break;
5943+ case PARSE_POST:
5944+ if(!IF_G(post_array)) {
5945+ ALLOC_ZVAL(array_ptr);
5946+ array_init(array_ptr);
5947+ INIT_PZVAL(array_ptr);
5948+ }
5949+ IF_G(post_array) = array_ptr;
5950+ break;
5951+ case PARSE_COOKIE:
5952+ if(!IF_G(cookie_array)) {
5953+ ALLOC_ZVAL(array_ptr);
5954+ array_init(array_ptr);
5955+ INIT_PZVAL(array_ptr);
5956+ }
5957+ IF_G(cookie_array) = array_ptr;
5958+ break;
5959+ }
5960+ Z_STRLEN(new_var) = val_len;
5961+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5962+ Z_TYPE(new_var) = IS_STRING;
5963+
5964+ var_len = strlen(var);
5965+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5966+ strcpy(raw_var, "RAW_");
5967+ strlcat(raw_var,var,var_len+5);
5968+
5969+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5970+
5971+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5972+
5973+ *new_val_len = strlen(*val);
5974+ return 1;
5975+}
5976+
5977+PHP_FUNCTION(my_get_raw)
5978+{
5979+ long arg;
5980+ char *var;
5981+ int var_len;
5982+ zval **tmp;
5983+ zval *array_ptr = NULL;
5984+ HashTable *hash_ptr;
5985+ char *raw_var;
5986+
5987+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
5988+ return;
5989+ }
5990+
5991+ switch(arg) {
5992+ case PARSE_GET:
5993+ array_ptr = IF_G(get_array);
5994+ break;
5995+ case PARSE_POST:
5996+ array_ptr = IF_G(post_array);
5997+ break;
5998+ case PARSE_COOKIE:
5999+ array_ptr = IF_G(post_array);
6000+ break;
6001+ }
6002+
6003+ if(!array_ptr) RETURN_FALSE;
6004+
6005+ /*
6006+ * I'm changing the variable name here because when running with register_globals on,
6007+ * the variable will end up in the global symbol table
6008+ */
6009+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
6010+ strcpy(raw_var, "RAW_");
6011+ strlcat(raw_var,var,var_len+5);
6012+ hash_ptr = HASH_OF(array_ptr);
6013+
6014+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
6015+ *return_value = **tmp;
6016+ zval_copy_ctor(return_value);
6017+ } else {
6018+ RETVAL_FALSE;
6019+ }
6020+ efree(raw_var);
6021+}
6022+
6023diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.9/run-tests.php
6024--- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100
6025+++ hardening-patch-4.4.2-0.4.9/run-tests.php 2006-05-02 16:46:34.000000000 +0200
6026@@ -152,6 +152,10 @@
6027 'error_reporting=2047',
6028 'display_errors=1',
6029 'log_errors=0',
6030+ 'hphp.executor.include.whitelist=cookietest',
6031+ 'hphp.log.syslog=0',
6032+ 'hphp.log.sapi=0',
6033+ 'hphp.log.script=0',
6034 'html_errors=0',
6035 'track_errors=1',
6036 'report_memleaks=1',
6037diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.9/sapi/apache/mod_php4.c
6038--- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100
6039+++ hardening-patch-4.4.2-0.4.9/sapi/apache/mod_php4.c 2006-05-02 16:46:34.000000000 +0200
6040@@ -452,7 +452,7 @@
6041 sapi_apache_get_fd,
6042 sapi_apache_force_http_10,
6043 sapi_apache_get_target_uid,
6044- sapi_apache_get_target_gid
6045+ sapi_apache_get_target_gid,
6046 };
6047 /* }}} */
6048
6049@@ -898,7 +898,11 @@
6050 {
6051 TSRMLS_FETCH();
6052 if (PG(expose_php)) {
6053+#if HARDENING_PATCH
6054+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
6055+#else
6056 ap_add_version_component("PHP/" PHP_VERSION);
6057+#endif
6058 }
6059 }
6060 #endif
6061diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.9/sapi/apache2filter/sapi_apache2.c
6062--- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6063+++ hardening-patch-4.4.2-0.4.9/sapi/apache2filter/sapi_apache2.c 2006-05-02 16:46:34.000000000 +0200
6064@@ -562,7 +562,11 @@
6065 {
6066 TSRMLS_FETCH();
6067 if (PG(expose_php)) {
6068+#if HARDENING_PATCH
6069+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6070+#else
6071 ap_add_version_component(p, "PHP/" PHP_VERSION);
6072+#endif
6073 }
6074 }
6075
6076diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.9/sapi/apache2handler/sapi_apache2.c
6077--- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6078+++ hardening-patch-4.4.2-0.4.9/sapi/apache2handler/sapi_apache2.c 2006-05-02 16:46:34.000000000 +0200
6079@@ -340,7 +340,11 @@
6080 {
6081 TSRMLS_FETCH();
6082 if (PG(expose_php)) {
6083+#if HARDENING_PATCH
6084+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6085+#else
6086 ap_add_version_component(p, "PHP/" PHP_VERSION);
6087+#endif
6088 }
6089 }
6090
6091diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.9/sapi/cgi/cgi_main.c
6092--- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100
6093+++ hardening-patch-4.4.2-0.4.9/sapi/cgi/cgi_main.c 2006-05-02 16:46:34.000000000 +0200
6094@@ -1432,11 +1432,19 @@
6095 SG(headers_sent) = 1;
6096 SG(request_info).no_headers = 1;
6097 }
6098+#if HARDENING_PATCH
6099+#if ZEND_DEBUG
6100+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6101+#else
6102+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6103+#endif
6104+#else
6105 #if ZEND_DEBUG
6106 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6107 #else
6108 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6109 #endif
6110+#endif
6111 php_end_ob_buffers(1 TSRMLS_CC);
6112 exit(0);
6113 break;
6114diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.9/sapi/cli/php_cli.c
6115--- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100
6116+++ hardening-patch-4.4.2-0.4.9/sapi/cli/php_cli.c 2006-05-02 16:46:34.000000000 +0200
6117@@ -654,11 +654,19 @@
6118 if (php_request_startup(TSRMLS_C)==FAILURE) {
6119 goto err;
6120 }
6121+#if HARDENING_PATCH
6122+#if ZEND_DEBUG
6123+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6124+#else
6125+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, HARDENING_PATCH_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6126+#endif
6127+#else
6128 #if ZEND_DEBUG
6129 php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6130 #else
6131 php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2006 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
6132 #endif
6133+#endif
6134 php_end_ob_buffers(1 TSRMLS_CC);
6135 exit_status=0;
6136 goto out;
6137diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.9/TSRM/TSRM.h
6138--- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
6139+++ hardening-patch-4.4.2-0.4.9/TSRM/TSRM.h 2006-05-02 16:46:34.000000000 +0200
6140@@ -33,6 +33,13 @@
6141 # define TSRM_API
6142 #endif
6143
6144+#if HARDENING_PATCH
6145+# if HAVE_REALPATH
6146+# undef realpath
6147+# define realpath php_realpath
6148+# endif
6149+#endif
6150+
6151 /* Only compile multi-threading functions if we're in ZTS mode */
6152 #ifdef ZTS
6153
6154@@ -84,6 +91,7 @@
6155
6156 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
6157
6158+
6159 #ifdef __cplusplus
6160 extern "C" {
6161 #endif
6162diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.9/TSRM/tsrm_virtual_cwd.c
6163--- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100
6164+++ hardening-patch-4.4.2-0.4.9/TSRM/tsrm_virtual_cwd.c 2006-05-02 16:46:34.000000000 +0200
6165@@ -179,6 +179,165 @@
6166 return p;
6167 }
6168
6169+#if HARDENING_PATCH
6170+CWD_API char *php_realpath(const char *path, char *resolved)
6171+{
6172+ struct stat sb;
6173+ char *p, *q, *s;
6174+ size_t left_len, resolved_len;
6175+ unsigned symlinks;
6176+ int serrno, slen;
6177+ int is_dir = 1;
6178+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
6179+
6180+ serrno = errno;
6181+ symlinks = 0;
6182+ if (path[0] == '/') {
6183+ resolved[0] = '/';
6184+ resolved[1] = '\0';
6185+ if (path[1] == '\0')
6186+ return (resolved);
6187+ resolved_len = 1;
6188+ left_len = strlcpy(left, path + 1, sizeof(left));
6189+ } else {
6190+ if (getcwd(resolved, PATH_MAX) == NULL) {
6191+ strlcpy(resolved, ".", PATH_MAX);
6192+ return (NULL);
6193+ }
6194+ resolved_len = strlen(resolved);
6195+ left_len = strlcpy(left, path, sizeof(left));
6196+ }
6197+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
6198+ errno = ENAMETOOLONG;
6199+ return (NULL);
6200+ }
6201+
6202+ /*
6203+ * Iterate over path components in `left'.
6204+ */
6205+ while (left_len != 0) {
6206+ /*
6207+ * Extract the next path component and adjust `left'
6208+ * and its length.
6209+ */
6210+ p = strchr(left, '/');
6211+ s = p ? p : left + left_len;
6212+ if (s - left >= sizeof(next_token)) {
6213+ errno = ENAMETOOLONG;
6214+ return (NULL);
6215+ }
6216+ memcpy(next_token, left, s - left);
6217+ next_token[s - left] = '\0';
6218+ left_len -= s - left;
6219+ if (p != NULL)
6220+ memmove(left, s + 1, left_len + 1);
6221+ if (resolved[resolved_len - 1] != '/') {
6222+ if (resolved_len + 1 >= PATH_MAX) {
6223+ errno = ENAMETOOLONG;
6224+ return (NULL);
6225+ }
6226+ resolved[resolved_len++] = '/';
6227+ resolved[resolved_len] = '\0';
6228+ }
6229+ if (next_token[0] == '\0')
6230+ continue;
6231+ else if (strcmp(next_token, ".") == 0)
6232+ continue;
6233+ else if (strcmp(next_token, "..") == 0) {
6234+ /*
6235+ * Strip the last path component except when we have
6236+ * single "/"
6237+ */
6238+ if (!is_dir) {
6239+ errno = ENOENT;
6240+ return (NULL);
6241+ }
6242+ if (resolved_len > 1) {
6243+ resolved[resolved_len - 1] = '\0';
6244+ q = strrchr(resolved, '/');
6245+ *q = '\0';
6246+ resolved_len = q - resolved;
6247+ }
6248+ continue;
6249+ }
6250+
6251+ /*
6252+ * Append the next path component and lstat() it. If
6253+ * lstat() fails we still can return successfully if
6254+ * there are no more path components left.
6255+ */
6256+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6257+ if (resolved_len >= PATH_MAX) {
6258+ errno = ENAMETOOLONG;
6259+ return (NULL);
6260+ }
6261+ if (lstat(resolved, &sb) != 0) {
6262+ if (errno == ENOENT && p == NULL) {
6263+ errno = serrno;
6264+ return (resolved);
6265+ }
6266+ return (NULL);
6267+ }
6268+ if (S_ISLNK(sb.st_mode)) {
6269+ if (symlinks++ > MAXSYMLINKS) {
6270+ errno = ELOOP;
6271+ return (NULL);
6272+ }
6273+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6274+ if (slen < 0)
6275+ return (NULL);
6276+ symlink[slen] = '\0';
6277+ if (symlink[0] == '/') {
6278+ resolved[1] = 0;
6279+ resolved_len = 1;
6280+ } else if (resolved_len > 1) {
6281+ /* Strip the last path component. */
6282+ resolved[resolved_len - 1] = '\0';
6283+ q = strrchr(resolved, '/');
6284+ *q = '\0';
6285+ resolved_len = q - resolved;
6286+ }
6287+
6288+ /*
6289+ * If there are any path components left, then
6290+ * append them to symlink. The result is placed
6291+ * in `left'.
6292+ */
6293+ if (p != NULL) {
6294+ if (symlink[slen - 1] != '/') {
6295+ if (slen + 1 >= sizeof(symlink)) {
6296+ errno = ENAMETOOLONG;
6297+ return (NULL);
6298+ }
6299+ symlink[slen] = '/';
6300+ symlink[slen + 1] = 0;
6301+ }
6302+ left_len = strlcat(symlink, left, sizeof(left));
6303+ if (left_len >= sizeof(left)) {
6304+ errno = ENAMETOOLONG;
6305+ return (NULL);
6306+ }
6307+ }
6308+ left_len = strlcpy(left, symlink, sizeof(left));
6309+ } else {
6310+ if (S_ISDIR(sb.st_mode)) {
6311+ is_dir = 1;
6312+ } else {
6313+ is_dir = 0;
6314+ }
6315+ }
6316+ }
6317+
6318+ /*
6319+ * Remove trailing slash except when the resolved pathname
6320+ * is a single "/".
6321+ */
6322+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6323+ resolved[resolved_len - 1] = '\0';
6324+ return (resolved);
6325+}
6326+#endif
6327+
6328 CWD_API void virtual_cwd_startup(void)
6329 {
6330 char cwd[MAXPATHLEN];
6331@@ -300,8 +459,11 @@
6332
6333 if (path_length == 0)
6334 return (0);
6335- if (path_length >= MAXPATHLEN)
6336+ if (path_length >= MAXPATHLEN) {
6337+ state->cwd[0] = 0;
6338+ state->cwd_length = 0;
6339 return (1);
6340+ }
6341
6342 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6343 /* cwd_length can be 0 when getcwd() fails.
6344@@ -313,8 +475,9 @@
6345 path = resolved_path;
6346 path_length = strlen(path);
6347 } else {
6348- /* disable for now
6349- return 1; */
6350+ state->cwd[0] = 0;
6351+ state->cwd_length = 0;
6352+ return 1;
6353 }
6354 }
6355 } else { /* Concat current directory with relative path and then run realpath() on it */
6356@@ -323,6 +486,8 @@
6357
6358 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6359 if (!tmp) {
6360+ state->cwd[0] = 0;
6361+ state->cwd_length = 0;
6362 return 1;
6363 }
6364 memcpy(ptr, state->cwd, state->cwd_length);
6365@@ -332,6 +497,8 @@
6366 ptr += path_length;
6367 *ptr = '\0';
6368 if (strlen(tmp) >= MAXPATHLEN) {
6369+ state->cwd[0] = 0;
6370+ state->cwd_length = 0;
6371 free(tmp);
6372 return 1;
6373 }
6374@@ -340,9 +507,10 @@
6375 path = resolved_path;
6376 path_length = strlen(path);
6377 } else {
6378- /* disable for now
6379+ state->cwd[0] = 0;
6380+ state->cwd_length = 0;
6381 free(tmp);
6382- return 1; */
6383+ return 1;
6384 }
6385 }
6386 free(tmp);
6387diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.9/TSRM/tsrm_virtual_cwd.h
6388--- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100
6389+++ hardening-patch-4.4.2-0.4.9/TSRM/tsrm_virtual_cwd.h 2006-05-02 16:46:34.000000000 +0200
6390@@ -128,6 +128,22 @@
6391
6392 typedef int (*verify_path_func)(const cwd_state *);
6393
6394+#ifndef HAVE_STRLCPY
6395+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6396+#undef strlcpy
6397+#define strlcpy php_strlcpy
6398+#endif
6399+
6400+#ifndef HAVE_STRLCAT
6401+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6402+#undef strlcat
6403+#define strlcat php_strlcat
6404+#endif
6405+
6406+
6407+#if HARDENING_PATCH
6408+CWD_API char *php_realpath(const char *path, char *resolved);
6409+#endif
6410 CWD_API void virtual_cwd_startup(void);
6411 CWD_API void virtual_cwd_shutdown(void);
6412 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6413diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.9/Zend/zend_alloc.c
6414--- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100
6415+++ hardening-patch-4.4.2-0.4.9/Zend/zend_alloc.c 2006-05-02 16:46:34.000000000 +0200
6416@@ -56,6 +56,11 @@
6417 # define END_MAGIC_SIZE 0
6418 #endif
6419
6420+#if HARDENING_PATCH_MM_PROTECT
6421+# define CANARY_SIZE sizeof(unsigned int)
6422+#else
6423+# define CANARY_SIZE 0
6424+#endif
6425
6426 # if MEMORY_LIMIT
6427 # if ZEND_DEBUG
6428@@ -96,9 +101,17 @@
6429 if (p==AG(head)) { \
6430 AG(head) = p->pNext; \
6431 } else { \
6432+ if (p != p->pLast->pNext) { \
6433+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6434+ exit(1); \
6435+ } \
6436 p->pLast->pNext = p->pNext; \
6437 } \
6438 if (p->pNext) { \
6439+ if (p != p->pNext->pLast) { \
6440+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6441+ exit(1); \
6442+ } \
6443 p->pNext->pLast = p->pLast; \
6444 }
6445
6446@@ -130,6 +143,12 @@
6447 DECLARE_CACHE_VARS();
6448 TSRMLS_FETCH();
6449
6450+#if HARDENING_PATCH_MM_PROTECT
6451+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6452+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6453+ exit(1);
6454+ }
6455+#endif
6456 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6457
6458 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6459@@ -147,6 +166,10 @@
6460 AG(cache_stats)[CACHE_INDEX][1]++;
6461 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6462 #endif
6463+#if HARDENING_PATCH_MM_PROTECT
6464+ p->canary = HG(canary_1);
6465+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6466+#endif
6467 p->cached = 0;
6468 p->size = size;
6469 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6470@@ -162,7 +185,7 @@
6471 AG(allocated_memory_peak) = AG(allocated_memory);
6472 }
6473 #endif
6474- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6475+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6476 }
6477
6478 HANDLE_BLOCK_INTERRUPTIONS();
6479@@ -192,7 +215,10 @@
6480 # endif
6481 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6482 #endif
6483-
6484+#if HARDENING_PATCH_MM_PROTECT
6485+ p->canary = HG(canary_1);
6486+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6487+#endif
6488 HANDLE_UNBLOCK_INTERRUPTIONS();
6489 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6490 }
6491@@ -219,17 +245,36 @@
6492 return emalloc_rel(lval + offset);
6493 }
6494 }
6495-
6496+
6497+#if HARDENING_PATCH
6498+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6499+#endif
6500 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6501 return 0;
6502 }
6503
6504 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6505 {
6506+#if HARDENING_PATCH_MM_PROTECT
6507+ unsigned int canary_2;
6508+#endif
6509 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6510 DECLARE_CACHE_VARS();
6511 TSRMLS_FETCH();
6512
6513+#if HARDENING_PATCH_MM_PROTECT
6514+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6515+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6516+ if (canary_2 != HG(canary_2)) {
6517+efree_canary_mismatch:
6518+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6519+ exit(1);
6520+ }
6521+ /* to catch double efree()s */
6522+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6523+ p->canary = 0;
6524+#endif
6525+
6526 #if defined(ZTS) && TSRM_DEBUG
6527 if (p->thread_id != tsrm_thread_id()) {
6528 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6529@@ -274,6 +319,9 @@
6530 size_t _size = nmemb * size;
6531
6532 if (nmemb && (_size/nmemb!=size)) {
6533+#if HARDENING_PATCH
6534+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6535+#endif
6536 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6537 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6538 kill(getpid(), SIGSEGV);
6539@@ -293,6 +341,9 @@
6540
6541 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6542 {
6543+#if HARDENING_PATCH_MM_PROTECT
6544+ unsigned int canary_2;
6545+#endif
6546 zend_mem_header *p;
6547 zend_mem_header *orig;
6548 DECLARE_CACHE_VARS();
6549@@ -304,6 +355,16 @@
6550
6551 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6552
6553+#if HARDENING_PATCH_MM_PROTECT
6554+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6555+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6556+ if (canary_2 != HG(canary_2)) {
6557+erealloc_canary_mismatch:
6558+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6559+ exit(1);
6560+ }
6561+#endif
6562+
6563 #if defined(ZTS) && TSRM_DEBUG
6564 if (p->thread_id != tsrm_thread_id()) {
6565 void *new_p;
6566@@ -327,7 +388,7 @@
6567 }
6568 #endif
6569 REMOVE_POINTER_FROM_LIST(p);
6570- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6571+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6572 if (!p) {
6573 if (!allow_failure) {
6574 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6575@@ -349,6 +410,9 @@
6576 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6577 #endif
6578
6579+#if HARDENING_PATCH_MM_PROTECT
6580+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6581+#endif
6582 p->size = size;
6583
6584 HANDLE_UNBLOCK_INTERRUPTIONS();
6585@@ -423,6 +487,10 @@
6586 {
6587 AG(head) = NULL;
6588
6589+#if HARDENING_PATCH_MM_PROTECT
6590+ HG(canary_1) = zend_canary();
6591+ HG(canary_2) = zend_canary();
6592+#endif
6593 #if MEMORY_LIMIT
6594 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6595 AG(allocated_memory) = 0;
6596diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.9/Zend/zend_alloc.h
6597--- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100
6598+++ hardening-patch-4.4.2-0.4.9/Zend/zend_alloc.h 2006-05-02 16:46:34.000000000 +0200
6599@@ -32,6 +32,9 @@
6600 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6601
6602 typedef struct _zend_mem_header {
6603+#if HARDENING_PATCH_MM_PROTECT
6604+ unsigned int canary;
6605+#endif
6606 #if ZEND_DEBUG
6607 long magic;
6608 char *filename;
6609diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.9/Zend/zend_builtin_functions.c
6610--- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100
6611+++ hardening-patch-4.4.2-0.4.9/Zend/zend_builtin_functions.c 2006-05-02 16:46:34.000000000 +0200
6612@@ -49,6 +49,9 @@
6613 static ZEND_FUNCTION(crash);
6614 #endif
6615 #endif
6616+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6617+static ZEND_FUNCTION(heap_overflow);
6618+#endif
6619 static ZEND_FUNCTION(get_included_files);
6620 static ZEND_FUNCTION(is_subclass_of);
6621 static ZEND_FUNCTION(is_a);
6622@@ -101,6 +104,9 @@
6623 ZEND_FE(crash, NULL)
6624 #endif
6625 #endif
6626+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6627+ ZEND_FE(heap_overflow, NULL)
6628+#endif
6629 ZEND_FE(get_included_files, NULL)
6630 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6631 ZEND_FE(is_subclass_of, NULL)
6632@@ -805,6 +811,19 @@
6633
6634 #endif /* ZEND_DEBUG */
6635
6636+
6637+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6638+ZEND_FUNCTION(heap_overflow)
6639+{
6640+ char *nowhere = emalloc(10);
6641+
6642+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6643+
6644+ efree(nowhere);
6645+}
6646+#endif
6647+
6648+
6649 /* {{{ proto array get_included_files(void)
6650 Returns an array with the file names that were include_once()'d */
6651 ZEND_FUNCTION(get_included_files)
6652diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.9/Zend/zend.c
6653--- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100
6654+++ hardening-patch-4.4.2-0.4.9/Zend/zend.c 2006-05-02 16:46:34.000000000 +0200
6655@@ -53,6 +53,12 @@
6656 ZEND_API void (*zend_unblock_interruptions)(void);
6657 ZEND_API void (*zend_ticks_function)(int ticks);
6658 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6659+#if HARDENING_PATCH
6660+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6661+#endif
6662+#if HARDENING_PATCH_INC_PROTECT
6663+ZEND_API int (*zend_is_valid_include)(zval *z);
6664+#endif
6665
6666 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6667
6668@@ -70,9 +76,390 @@
6669 return SUCCESS;
6670 }
6671
6672+#if HARDENING_PATCH
6673+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6674+{
6675+ if (!new_value) {
6676+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6677+ } else {
6678+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6679+ }
6680+ return SUCCESS;
6681+}
6682+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6683+{
6684+ if (!new_value) {
6685+ EG(hphp_log_syslog_facility) = LOG_USER;
6686+ } else {
6687+ EG(hphp_log_syslog_facility) = atoi(new_value);
6688+ }
6689+ return SUCCESS;
6690+}
6691+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6692+{
6693+ if (!new_value) {
6694+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6695+ } else {
6696+ EG(hphp_log_syslog_priority) = atoi(new_value);
6697+ }
6698+ return SUCCESS;
6699+}
6700+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6701+{
6702+ if (!new_value) {
6703+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6704+ } else {
6705+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6706+ }
6707+ return SUCCESS;
6708+}
6709+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6710+{
6711+ if (!new_value) {
6712+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6713+ } else {
6714+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6715+ }
6716+ return SUCCESS;
6717+}
6718+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6719+{
6720+ if (EG(hphp_log_scriptname)) {
6721+ pefree(EG(hphp_log_scriptname),1);
6722+ }
6723+ EG(hphp_log_scriptname) = NULL;
6724+ if (new_value) {
6725+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6726+ }
6727+ return SUCCESS;
6728+}
6729+
6730+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6731+{
6732+ char *s = NULL, *e, *val;
6733+ unsigned long dummy = 1;
6734+
6735+ if (!new_value) {
6736+include_whitelist_destroy:
6737+ if (HG(include_whitelist)) {
6738+ zend_hash_destroy(HG(include_whitelist));
6739+ pefree(HG(include_whitelist),1);
6740+ }
6741+ HG(include_whitelist) = NULL;
6742+ return SUCCESS;
6743+ }
6744+ if (!(*new_value)) {
6745+ goto include_whitelist_destroy;
6746+ }
6747+
6748+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6749+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6750+
6751+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6752+ e = val;
6753+
6754+ while (*e) {
6755+ switch (*e) {
6756+ case ' ':
6757+ case ',':
6758+ if (s) {
6759+ *e = '\0';
6760+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6761+ s = NULL;
6762+ }
6763+ break;
6764+ default:
6765+ if (!s) {
6766+ s = e;
6767+ }
6768+ break;
6769+ }
6770+ e++;
6771+ }
6772+ if (s) {
6773+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6774+ }
6775+ efree(val);
6776+
6777+ return SUCCESS;
6778+}
6779+
6780+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6781+{
6782+ char *s = NULL, *e, *val;
6783+ unsigned long dummy = 1;
6784+
6785+ if (!new_value) {
6786+include_blacklist_destroy:
6787+ if (HG(include_blacklist)) {
6788+ zend_hash_destroy(HG(include_blacklist));
6789+ pefree(HG(include_blacklist),1);
6790+ }
6791+ HG(include_blacklist) = NULL;
6792+ return SUCCESS;
6793+ }
6794+ if (!(*new_value)) {
6795+ goto include_blacklist_destroy;
6796+ }
6797+
6798+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6799+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6800+
6801+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6802+ e = val;
6803+
6804+ while (*e) {
6805+ switch (*e) {
6806+ case ' ':
6807+ case ',':
6808+ if (s) {
6809+ *e = '\0';
6810+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6811+ s = NULL;
6812+ }
6813+ break;
6814+ default:
6815+ if (!s) {
6816+ s = e;
6817+ }
6818+ break;
6819+ }
6820+ e++;
6821+ }
6822+ if (s) {
6823+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6824+ }
6825+ efree(val);
6826+
6827+ return SUCCESS;
6828+}
6829+
6830+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6831+{
6832+ char *s = NULL, *e, *val;
6833+ unsigned long dummy = 1;
6834+
6835+ if (!new_value) {
6836+eval_whitelist_destroy:
6837+ if (HG(eval_whitelist)) {
6838+ zend_hash_destroy(HG(eval_whitelist));
6839+ pefree(HG(eval_whitelist),1);
6840+ }
6841+ HG(eval_whitelist) = NULL;
6842+ return SUCCESS;
6843+ }
6844+ if (!(*new_value)) {
6845+ goto eval_whitelist_destroy;
6846+ }
6847+
6848+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6849+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6850+
6851+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6852+ e = val;
6853+
6854+ while (*e) {
6855+ switch (*e) {
6856+ case ' ':
6857+ case ',':
6858+ if (s) {
6859+ *e = '\0';
6860+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6861+ s = NULL;
6862+ }
6863+ break;
6864+ default:
6865+ if (!s) {
6866+ s = e;
6867+ }
6868+ break;
6869+ }
6870+ e++;
6871+ }
6872+ if (s) {
6873+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6874+ }
6875+ efree(val);
6876+
6877+ return SUCCESS;
6878+}
6879+
6880+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6881+{
6882+ char *s = NULL, *e, *val;
6883+ unsigned long dummy = 1;
6884+
6885+ if (!new_value) {
6886+eval_blacklist_destroy:
6887+ if (HG(eval_blacklist)) {
6888+ zend_hash_destroy(HG(eval_blacklist));
6889+ pefree(HG(eval_blacklist), 1);
6890+ }
6891+ HG(eval_blacklist) = NULL;
6892+ return SUCCESS;
6893+ }
6894+ if (!(*new_value)) {
6895+ goto eval_blacklist_destroy;
6896+ }
6897+
6898+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6899+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6900+
6901+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6902+ e = val;
6903+
6904+ while (*e) {
6905+ switch (*e) {
6906+ case ' ':
6907+ case ',':
6908+ if (s) {
6909+ *e = '\0';
6910+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6911+ s = NULL;
6912+ }
6913+ break;
6914+ default:
6915+ if (!s) {
6916+ s = e;
6917+ }
6918+ break;
6919+ }
6920+ e++;
6921+ }
6922+ if (s) {
6923+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6924+ }
6925+ efree(val);
6926+
6927+
6928+ return SUCCESS;
6929+}
6930+
6931+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6932+{
6933+ char *s = NULL, *e, *val;
6934+ unsigned long dummy = 1;
6935+
6936+ if (!new_value) {
6937+func_whitelist_destroy:
6938+ if (HG(func_whitelist)) {
6939+ zend_hash_destroy(HG(func_whitelist));
6940+ pefree(HG(func_whitelist),1);
6941+ }
6942+ HG(func_whitelist) = NULL;
6943+ return SUCCESS;
6944+ }
6945+ if (!(*new_value)) {
6946+ goto func_whitelist_destroy;
6947+ }
6948+
6949+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6950+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6951+
6952+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6953+ e = val;
6954+
6955+ while (*e) {
6956+ switch (*e) {
6957+ case ' ':
6958+ case ',':
6959+ if (s) {
6960+ *e = '\0';
6961+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6962+ s = NULL;
6963+ }
6964+ break;
6965+ default:
6966+ if (!s) {
6967+ s = e;
6968+ }
6969+ break;
6970+ }
6971+ e++;
6972+ }
6973+ if (s) {
6974+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6975+ }
6976+ efree(val);
6977+
6978+ return SUCCESS;
6979+}
6980+
6981+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6982+{
6983+ char *s = NULL, *e, *val;
6984+ unsigned long dummy = 1;
6985+
6986+ if (!new_value) {
6987+func_blacklist_destroy:
6988+ if (HG(func_blacklist)) {
6989+ zend_hash_destroy(HG(func_blacklist));
6990+ pefree(HG(func_blacklist),1);
6991+ }
6992+ HG(func_blacklist) = NULL;
6993+ return SUCCESS;
6994+ }
6995+ if (!(*new_value)) {
6996+ goto func_blacklist_destroy;
6997+ }
6998+
6999+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
7000+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
7001+
7002+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7003+ e = val;
7004+
7005+ while (*e) {
7006+ switch (*e) {
7007+ case ' ':
7008+ case ',':
7009+ if (s) {
7010+ *e = '\0';
7011+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7012+ s = NULL;
7013+ }
7014+ break;
7015+ default:
7016+ if (!s) {
7017+ s = e;
7018+ }
7019+ break;
7020+ }
7021+ e++;
7022+ }
7023+ if (s) {
7024+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7025+ }
7026+ efree(val);
7027+
7028+
7029+ return SUCCESS;
7030+}
7031+
7032+#endif
7033
7034 ZEND_INI_BEGIN()
7035 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
7036+#if HARDENING_PATCH
7037+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
7038+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
7039+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
7040+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
7041+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
7042+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
7043+ STD_ZEND_INI_BOOLEAN("hphp.log.use-x-forwarded-for", "0", ZEND_INI_SYSTEM, OnUpdateBool, hphp_log_use_x_forwarded_for, zend_executor_globals, executor_globals)
7044+
7045+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
7046+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
7047+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
7048+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
7049+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
7050+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
7051+
7052+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
7053+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
7054+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
7055+#endif
7056 ZEND_INI_END()
7057
7058
7059@@ -354,8 +741,12 @@
7060 zend_init_rsrc_plist(TSRMLS_C);
7061 EG(lambda_count)=0;
7062 EG(user_error_handler) = NULL;
7063+ EG(in_code_type) = 0;
7064 EG(in_execution) = 0;
7065 EG(current_execute_data) = NULL;
7066+#if HARDENING_PATCH
7067+ EG(hphp_log_scriptname) = NULL;
7068+#endif
7069 }
7070
7071
7072@@ -420,6 +811,14 @@
7073 extern zend_scanner_globals language_scanner_globals;
7074 #endif
7075
7076+ /* Set up Hardening-Patch utility functions first */
7077+#if HARDENING_PATCH
7078+ zend_security_log = utility_functions->security_log_function;
7079+#endif
7080+#if HARDENING_PATCH_INC_PROTECT
7081+ zend_is_valid_include = utility_functions->is_valid_include;
7082+#endif
7083+
7084 #ifdef ZTS
7085 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
7086 #else
7087@@ -619,6 +1018,7 @@
7088 }
7089 CG(unclean_shutdown) = 1;
7090 CG(in_compilation) = EG(in_execution) = 0;
7091+ EG(in_code_type) = 0;
7092 EG(current_execute_data) = NULL;
7093 longjmp(EG(bailout), FAILURE);
7094 }
7095diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.9/Zend/zend_canary.c
7096--- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
7097+++ hardening-patch-4.4.2-0.4.9/Zend/zend_canary.c 2006-05-02 16:46:34.000000000 +0200
7098@@ -0,0 +1,58 @@
7099+/*
7100+ +----------------------------------------------------------------------+
7101+ | Hardening-Patch for PHP |
7102+ +----------------------------------------------------------------------+
7103+ | Copyright (c) 2004-2005 Stefan Esser |
7104+ +----------------------------------------------------------------------+
7105+ | This source file is subject to version 2.02 of the PHP license, |
7106+ | that is bundled with this package in the file LICENSE, and is |
7107+ | available at through the world-wide-web at |
7108+ | http://www.php.net/license/2_02.txt. |
7109+ | If you did not receive a copy of the PHP license and are unable to |
7110+ | obtain it through the world-wide-web, please send a note to |
7111+ | license@php.net so we can mail you a copy immediately. |
7112+ +----------------------------------------------------------------------+
7113+ | Author: Stefan Esser <sesser@hardened-php.net> |
7114+ +----------------------------------------------------------------------+
7115+ */
7116+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
7117+
7118+#include "zend.h"
7119+
7120+#include <stdio.h>
7121+#include <stdlib.h>
7122+
7123+
7124+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7125+
7126+/* will be replaced later with more compatible method */
7127+ZEND_API unsigned int zend_canary()
7128+{
7129+ time_t t;
7130+ unsigned int canary;
7131+ int fd;
7132+
7133+ fd = open("/dev/urandom", 0);
7134+ if (fd != -1) {
7135+ int r = read(fd, &canary, sizeof(canary));
7136+ close(fd);
7137+ if (r == sizeof(canary)) {
7138+ return (canary);
7139+ }
7140+ }
7141+ /* not good but we never want to do this */
7142+ time(&t);
7143+ canary = *(unsigned int *)&t + getpid() << 16;
7144+ return (canary);
7145+}
7146+#endif
7147+
7148+
7149+/*
7150+ * Local variables:
7151+ * tab-width: 4
7152+ * c-basic-offset: 4
7153+ * End:
7154+ * vim600: sw=4 ts=4 fdm=marker
7155+ * vim<600: sw=4 ts=4
7156+ */
7157diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.9/Zend/zend_compile.c
7158--- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100
7159+++ hardening-patch-4.4.2-0.4.9/Zend/zend_compile.c 2006-05-02 16:46:34.000000000 +0200
7160@@ -768,6 +768,13 @@
7161 op_array.function_name = name;
7162 op_array.arg_types = NULL;
7163 op_array.return_reference = return_reference;
7164+#if HARDENING_PATCH
7165+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7166+ op_array.created_by_eval = 1;
7167+ } else {
7168+ op_array.created_by_eval = 0;
7169+ }
7170+#endif
7171
7172 if (is_method) {
7173 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
7174diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.9/Zend/zend_compile.h
7175--- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100
7176+++ hardening-patch-4.4.2-0.4.9/Zend/zend_compile.h 2006-05-02 16:46:34.000000000 +0200
7177@@ -106,6 +106,9 @@
7178 char *filename;
7179
7180 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
7181+#if HARDENING_PATCH
7182+ zend_bool created_by_eval;
7183+#endif
7184 };
7185
7186
7187@@ -549,6 +552,7 @@
7188 #define ZEND_USER_FUNCTION 2
7189 #define ZEND_OVERLOADED_FUNCTION 3
7190 #define ZEND_EVAL_CODE 4
7191+#define ZEND_SANDBOX_CODE 6
7192
7193 #define ZEND_INTERNAL_CLASS 1
7194 #define ZEND_USER_CLASS 2
7195diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.9/Zend/zend_constants.c
7196--- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100
7197+++ hardening-patch-4.4.2-0.4.9/Zend/zend_constants.c 2006-05-02 16:46:34.000000000 +0200
7198@@ -111,6 +111,73 @@
7199 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
7200
7201 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
7202+#if HARDENING_PATCH
7203+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
7204+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
7205+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
7206+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
7207+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
7208+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
7209+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
7210+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
7211+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
7212+
7213+ /* error levels */
7214+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
7215+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
7216+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
7217+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
7218+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
7219+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
7220+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
7221+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
7222+ /* facility: type of program logging the message */
7223+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
7224+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
7225+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
7226+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
7227+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
7228+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
7229+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
7230+#ifdef LOG_NEWS
7231+ /* No LOG_NEWS on HP-UX */
7232+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
7233+#endif
7234+#ifdef LOG_UUCP
7235+ /* No LOG_UUCP on HP-UX */
7236+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
7237+#endif
7238+#ifdef LOG_CRON
7239+ /* apparently some systems don't have this one */
7240+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
7241+#endif
7242+#ifdef LOG_AUTHPRIV
7243+ /* AIX doesn't have LOG_AUTHPRIV */
7244+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7245+#endif
7246+#if !defined(PHP_WIN32) && !defined(NETWARE)
7247+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7248+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7249+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7250+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7251+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7252+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7253+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7254+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7255+#endif
7256+ /* options */
7257+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7258+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7259+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7260+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7261+#ifdef LOG_NOWAIT
7262+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7263+#endif
7264+#ifdef LOG_PERROR
7265+ /* AIX doesn't have LOG_PERROR */
7266+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7267+#endif
7268+#endif
7269
7270 /* true/false constants */
7271 {
7272diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.9/Zend/zend_errors.h
7273--- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100
7274+++ hardening-patch-4.4.2-0.4.9/Zend/zend_errors.h 2006-05-02 16:46:34.000000000 +0200
7275@@ -36,5 +36,17 @@
7276 #define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE)
7277 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7278
7279+#if HARDENING_PATCH
7280+#define S_MEMORY (1<<0L)
7281+#define S_VARS (1<<1L)
7282+#define S_FILES (1<<2L)
7283+#define S_INCLUDE (1<<3L)
7284+#define S_SQL (1<<4L)
7285+#define S_EXECUTOR (1<<5L)
7286+#define S_MISC (1<<30L)
7287+#define S_INTERNAL (1<<29L)
7288+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
7289+#endif
7290+
7291 #endif /* ZEND_ERRORS_H */
7292
7293diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.9/Zend/zend_execute_API.c
7294--- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100
7295+++ hardening-patch-4.4.2-0.4.9/Zend/zend_execute_API.c 2006-05-02 16:46:34.000000000 +0200
7296@@ -142,6 +142,7 @@
7297 EG(class_table) = CG(class_table);
7298
7299 EG(in_execution) = 0;
7300+ EG(in_code_type) = 0;
7301
7302 zend_ptr_stack_init(&EG(argument_stack));
7303
7304@@ -431,12 +432,14 @@
7305 zend_execute_data execute_data;
7306
7307 /* Initialize execute_data */
7308+ memset(&execute_data, 0, sizeof(execute_data));
7309 EX(fbc) = NULL;
7310 EX(object).ptr = NULL;
7311 EX(ce) = NULL;
7312 EX(Ts) = NULL;
7313 EX(op_array) = NULL;
7314 EX(opline) = NULL;
7315+ EX(execute_depth) = 0;
7316
7317 *retval_ptr_ptr = NULL;
7318
7319@@ -494,6 +497,39 @@
7320 zval_dtor(&function_name_copy);
7321 return FAILURE;
7322 }
7323+#if HARDENING_PATCH
7324+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7325+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7326+ if (HG(eval_whitelist) != NULL) {
7327+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7328+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7329+ zval_dtor(&function_name_copy);
7330+ zend_bailout();
7331+ }
7332+ } else if (HG(eval_blacklist) != NULL) {
7333+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7334+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7335+ zval_dtor(&function_name_copy);
7336+ zend_bailout();
7337+ }
7338+ }
7339+ }
7340+
7341+ if (HG(func_whitelist) != NULL) {
7342+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7343+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7344+ zval_dtor(&function_name_copy);
7345+ zend_bailout();
7346+ }
7347+ } else if (HG(func_blacklist) != NULL) {
7348+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7349+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7350+ zval_dtor(&function_name_copy);
7351+ zend_bailout();
7352+ }
7353+ }
7354+ }
7355+#endif
7356 zval_dtor(&function_name_copy);
7357
7358 for (i=0; i<param_count; i++) {
7359@@ -606,8 +642,7 @@
7360 return SUCCESS;
7361 }
7362
7363-
7364-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7365+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7366 {
7367 zval pv;
7368 zend_op_array *new_op_array;
7369@@ -640,6 +675,7 @@
7370 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7371 zend_op **original_opline_ptr = EG(opline_ptr);
7372
7373+ new_op_array->type = type;
7374 EG(return_value_ptr_ptr) = &local_retval_ptr;
7375 EG(active_op_array) = new_op_array;
7376 EG(no_extensions)=1;
7377@@ -673,6 +709,10 @@
7378 return retval;
7379 }
7380
7381+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7382+{
7383+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7384+}
7385
7386 void execute_new_code(TSRMLS_D)
7387 {
7388diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.9/Zend/zend_execute.c
7389--- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100
7390+++ hardening-patch-4.4.2-0.4.9/Zend/zend_execute.c 2006-05-02 16:46:34.000000000 +0200
7391@@ -1042,6 +1042,7 @@
7392 zend_execute_data execute_data;
7393
7394 /* Initialize execute_data */
7395+ memset(&execute_data, 0, sizeof(execute_data));
7396 EX(fbc) = NULL;
7397 EX(ce) = NULL;
7398 EX(object).ptr = NULL;
7399@@ -1053,9 +1054,21 @@
7400 }
7401 EX(prev_execute_data) = EG(current_execute_data);
7402 EX(original_in_execution)=EG(in_execution);
7403+ EX(original_in_code_type)=EG(in_code_type);
7404
7405 EG(current_execute_data) = &execute_data;
7406
7407+#if HARDENING_PATCH
7408+ EX(execute_depth) = 0;
7409+
7410+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7411+ EG(in_code_type) = ZEND_EVAL_CODE;
7412+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7413+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7414+ op_array->type = ZEND_EVAL_CODE;
7415+ }
7416+#endif
7417+
7418 EG(in_execution) = 1;
7419 if (op_array->start_op) {
7420 EX(opline) = op_array->start_op;
7421@@ -1087,6 +1100,19 @@
7422 }
7423 }
7424
7425+#if HARDENING_PATCH
7426+ if (EX(prev_execute_data) == NULL) {
7427+ EX(execute_depth) = 0;
7428+ } else {
7429+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7430+ }
7431+
7432+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7433+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7434+ zend_bailout();
7435+ }
7436+#endif
7437+
7438 while (1) {
7439 #ifdef ZEND_WIN32
7440 if (EG(timed_out)) {
7441@@ -1634,6 +1660,36 @@
7442 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7443 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7444 }
7445+#if HARDENING_PATCH
7446+ if (active_function_table == EG(function_table)) {
7447+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7448+ if (HG(eval_whitelist) != NULL) {
7449+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7450+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7451+ zend_bailout();
7452+ }
7453+ } else if (HG(eval_blacklist) != NULL) {
7454+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7455+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7456+ zend_bailout();
7457+ }
7458+ }
7459+ }
7460+
7461+ if (HG(func_whitelist) != NULL) {
7462+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7463+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7464+ zend_bailout();
7465+ }
7466+ } else if (HG(func_blacklist) != NULL) {
7467+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7468+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7469+ zend_bailout();
7470+ }
7471+ }
7472+ }
7473+#endif
7474+
7475 zval_dtor(&tmp);
7476 EX(fbc) = function;
7477 overloaded_function_call_cont:
7478@@ -1649,6 +1705,35 @@
7479 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7480 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7481 }
7482+#if HARDENING_PATCH
7483+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7484+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7485+ if (HG(eval_whitelist) != NULL) {
7486+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7487+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7488+ zend_bailout();
7489+ }
7490+ } else if (HG(eval_blacklist) != NULL) {
7491+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7492+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7493+ zend_bailout();
7494+ }
7495+ }
7496+ }
7497+
7498+ if (HG(func_whitelist) != NULL) {
7499+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7500+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7501+ zend_bailout();
7502+ }
7503+ } else if (HG(func_blacklist) != NULL) {
7504+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7505+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7506+ zend_bailout();
7507+ }
7508+ }
7509+ }
7510+#endif
7511 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7512 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7513 EX(object).ptr = NULL;
7514@@ -1821,6 +1906,7 @@
7515 efree(EX(Ts));
7516 }
7517 EG(in_execution) = EX(original_in_execution);
7518+ EG(in_code_type) = EX(original_in_code_type);
7519 EG(current_execute_data) = EX(prev_execute_data);
7520 return;
7521 }
7522@@ -2210,7 +2296,12 @@
7523 int dummy = 1;
7524 zend_file_handle file_handle = {0};
7525
7526+#if HARDENING_PATCH_INC_PROTECT
7527+ if (zend_is_valid_include(inc_filename)
7528+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7529+#else
7530 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7531+#endif
7532 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7533
7534 file_handle.filename = inc_filename->value.str.val;
7535@@ -2239,6 +2330,11 @@
7536 break;
7537 case ZEND_INCLUDE:
7538 case ZEND_REQUIRE:
7539+#if HARDENING_PATCH_INC_PROTECT
7540+ if (!zend_is_valid_include(inc_filename)) {
7541+ break;
7542+ }
7543+#endif
7544 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7545 break;
7546 case ZEND_EVAL: {
7547diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.9/Zend/zend_execute_globals.h
7548--- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100
7549+++ hardening-patch-4.4.2-0.4.9/Zend/zend_execute_globals.h 2006-05-02 16:46:34.000000000 +0200
7550@@ -60,6 +60,8 @@
7551 object_info object;
7552 temp_variable *Ts;
7553 zend_bool original_in_execution;
7554+ zend_uint original_in_code_type;
7555+ zend_uint execute_depth;
7556 zend_op_array *op_array;
7557 struct _zend_execute_data *prev_execute_data;
7558 } zend_execute_data;
7559diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.9/Zend/zend_extensions.c
7560--- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100
7561+++ hardening-patch-4.4.2-0.4.9/Zend/zend_extensions.c 2006-05-02 16:46:34.000000000 +0200
7562@@ -54,23 +54,44 @@
7563 return FAILURE;
7564 }
7565
7566+ /* check if module is compiled against Hardening-Patch */
7567+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7568+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7569+ "The Hardening-Patch version %d is installed.\n\n",
7570+ new_extension->name,
7571+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7572+ DL_UNLOAD(handle);
7573+ return FAILURE;
7574+ }
7575+
7576+
7577+ /* check if module is compiled against correct Hardening-Patch version */
7578+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7579+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7580+ "The Hardening-Patch version %d is installed.\n\n",
7581+ new_extension->name,
7582+ extension_version_info->zend_extension_api_no,
7583+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7584+ DL_UNLOAD(handle);
7585+ return FAILURE;
7586+ }
7587
7588 /* allow extension to proclaim compatibility with any Zend version */
7589- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7590- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7591+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
7592+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7593 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7594 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7595 new_extension->name,
7596- extension_version_info->zend_extension_api_no,
7597+ extension_version_info->real_zend_extension_api_no,
7598 ZEND_EXTENSION_API_NO);
7599 DL_UNLOAD(handle);
7600 return FAILURE;
7601- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7602+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7603 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7604 "The Zend Engine API version %d which is installed, is newer.\n"
7605 "Contact %s at %s for a later version of %s.\n\n",
7606 new_extension->name,
7607- extension_version_info->zend_extension_api_no,
7608+ extension_version_info->real_zend_extension_api_no,
7609 ZEND_EXTENSION_API_NO,
7610 new_extension->author,
7611 new_extension->URL,
7612diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.9/Zend/zend_extensions.h
7613--- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100
7614+++ hardening-patch-4.4.2-0.4.9/Zend/zend_extensions.h 2006-05-02 16:46:34.000000000 +0200
7615@@ -23,6 +23,9 @@
7616
7617 #include "zend_compile.h"
7618
7619+/* Create own API version number for Hardening-Patch */
7620+
7621+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7622 #define ZEND_EXTENSION_API_NO 20050606
7623
7624 typedef struct _zend_extension_version_info {
7625@@ -30,6 +33,7 @@
7626 char *required_zend_version;
7627 unsigned char thread_safe;
7628 unsigned char debug;
7629+ int real_zend_extension_api_no;
7630 } zend_extension_version_info;
7631
7632
7633@@ -96,7 +100,7 @@
7634
7635
7636 #define ZEND_EXTENSION() \
7637- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7638+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
7639
7640 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7641 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7642diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.9/Zend/zend_globals.h
7643--- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100
7644+++ hardening-patch-4.4.2-0.4.9/Zend/zend_globals.h 2006-05-02 16:46:34.000000000 +0200
7645@@ -163,6 +163,16 @@
7646
7647 int error_reporting;
7648 int orig_error_reporting;
7649+#if HARDENING_PATCH
7650+ int hphp_log_syslog;
7651+ int hphp_log_syslog_facility;
7652+ int hphp_log_syslog_priority;
7653+ int hphp_log_sapi;
7654+ int hphp_log_script;
7655+ char *hphp_log_scriptname;
7656+ zend_bool hphp_log_use_x_forwarded_for;
7657+ long hphp_executor_max_depth;
7658+#endif
7659 int exit_status;
7660
7661 zend_op_array *active_op_array;
7662@@ -176,6 +186,7 @@
7663 int ticks_count;
7664
7665 zend_bool in_execution;
7666+ zend_uint in_code_type;
7667 zend_bool bailout_set;
7668 zend_bool full_tables_cleanup;
7669
7670diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.9/Zend/zend.h
7671--- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100
7672+++ hardening-patch-4.4.2-0.4.9/Zend/zend.h 2006-05-02 16:46:34.000000000 +0200
7673@@ -274,9 +274,10 @@
7674 struct _zval_struct {
7675 /* Variable information */
7676 zvalue_value value; /* value */
7677+ zend_uint refcount;
7678+ zend_ushort flags;
7679 zend_uchar type; /* active type */
7680 zend_uchar is_ref;
7681- zend_ushort refcount;
7682 };
7683
7684
7685@@ -337,6 +338,12 @@
7686 void (*ticks_function)(int ticks);
7687 void (*on_timeout)(int seconds TSRMLS_DC);
7688 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7689+#if HARDENING_PATCH
7690+ void (*security_log_function)(int loglevel, char *fmt, ...);
7691+#endif
7692+#if HARDENING_PATCH_INC_PROTECT
7693+ int (*is_valid_include)(zval *z);
7694+#endif
7695 } zend_utility_functions;
7696
7697
7698@@ -468,7 +475,16 @@
7699 extern ZEND_API void (*zend_ticks_function)(int ticks);
7700 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);
7701 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7702+#if HARDENING_PATCH
7703+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7704+#endif
7705+#if HARDENING_PATCH_INC_PROTECT
7706+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7707+#endif
7708
7709+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7710+ZEND_API unsigned int zend_canary(void);
7711+#endif
7712
7713 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7714
7715@@ -575,6 +591,11 @@
7716
7717 #define ZEND_MAX_RESERVED_RESOURCES 4
7718
7719+#if HARDENING_PATCH
7720+#include "hardened_globals.h"
7721+#include "php_syslog.h"
7722+#endif
7723+
7724 #endif /* ZEND_H */
7725
7726 /*
7727diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.9/Zend/zend_hash.c
7728--- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100
7729+++ hardening-patch-4.4.2-0.4.9/Zend/zend_hash.c 2006-05-02 16:47:25.000000000 +0200
7730@@ -26,6 +26,17 @@
7731 # include <stdlib.h>
7732 #endif
7733
7734+#if HARDENING_PATCH_HASH_PROTECT
7735+ unsigned int zend_hash_canary = 0x1234567;
7736+ zend_bool zend_hash_canary_inited = 0;
7737+#endif
7738+
7739+#define CHECK_HASH_CANARY(hash) \
7740+ if (zend_hash_canary != (hash)->canary) { \
7741+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7742+ exit(1); \
7743+ }
7744+
7745 #define HANDLE_NUMERIC(key, length, func) { \
7746 register char *tmp=key; \
7747 \
7748@@ -175,6 +186,9 @@
7749 {
7750 uint i = 3;
7751 Bucket **tmp;
7752+#if HARDENING_PATCH_HASH_PROTECT
7753+ TSRMLS_FETCH();
7754+#endif
7755
7756 SET_INCONSISTENT(HT_OK);
7757
7758@@ -184,6 +198,13 @@
7759
7760 ht->nTableSize = 1 << i;
7761 ht->nTableMask = ht->nTableSize - 1;
7762+#if HARDENING_PATCH_HASH_PROTECT
7763+ if (zend_hash_canary_inited==0) {
7764+ zend_hash_canary = zend_canary();
7765+ zend_hash_canary_inited = 1;
7766+ }
7767+ ht->canary = zend_hash_canary;
7768+#endif
7769 ht->pDestructor = pDestructor;
7770 ht->pListHead = NULL;
7771 ht->pListTail = NULL;
7772@@ -259,6 +280,9 @@
7773 }
7774 #endif
7775 if (ht->pDestructor) {
7776+#if HARDENING_PATCH_HASH_PROTECT
7777+ CHECK_HASH_CANARY(ht);
7778+#endif
7779 ht->pDestructor(p->pData);
7780 }
7781 UPDATE_DATA(ht, p, pData, nDataSize);
7782@@ -327,6 +351,9 @@
7783 }
7784 #endif
7785 if (ht->pDestructor) {
7786+#if HARDENING_PATCH_HASH_PROTECT
7787+ CHECK_HASH_CANARY(ht);
7788+#endif
7789 ht->pDestructor(p->pData);
7790 }
7791 UPDATE_DATA(ht, p, pData, nDataSize);
7792@@ -402,6 +429,9 @@
7793 }
7794 #endif
7795 if (ht->pDestructor) {
7796+#if HARDENING_PATCH_HASH_PROTECT
7797+ CHECK_HASH_CANARY(ht);
7798+#endif
7799 ht->pDestructor(p->pData);
7800 }
7801 UPDATE_DATA(ht, p, pData, nDataSize);
7802@@ -450,7 +480,7 @@
7803 IS_CONSISTENT(ht);
7804
7805 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7806- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7807+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7808 if (t) {
7809 HANDLE_BLOCK_INTERRUPTIONS();
7810 ht->arBuckets = t;
7811@@ -460,6 +490,7 @@
7812 HANDLE_UNBLOCK_INTERRUPTIONS();
7813 return SUCCESS;
7814 }
7815+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7816 return FAILURE;
7817 }
7818 return SUCCESS;
7819@@ -491,15 +522,17 @@
7820 IS_CONSISTENT(ht);
7821
7822 if (flag == HASH_DEL_KEY) {
7823- HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX));
7824+ HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, NULL, 0, idx, HASH_DEL_INDEX));
7825 h = zend_inline_hash_func(arKey, nKeyLength);
7826 }
7827 nIndex = h & ht->nTableMask;
7828
7829 p = ht->arBuckets[nIndex];
7830 while (p != NULL) {
7831- if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric index */
7832- ((p->nKeyLength == nKeyLength) && (!memcmp(p->arKey, arKey, nKeyLength))))) {
7833+ if ((p->h == h)
7834+ && (p->nKeyLength == nKeyLength)
7835+ && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */
7836+ || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */
7837 HANDLE_BLOCK_INTERRUPTIONS();
7838 if (p == ht->arBuckets[nIndex]) {
7839 ht->arBuckets[nIndex] = p->pNext;
7840@@ -524,6 +557,9 @@
7841 ht->pInternalPointer = p->pListNext;
7842 }
7843 if (ht->pDestructor) {
7844+#if HARDENING_PATCH_HASH_PROTECT
7845+ CHECK_HASH_CANARY(ht);
7846+#endif
7847 ht->pDestructor(p->pData);
7848 }
7849 if (!p->pDataPtr) {
7850@@ -553,6 +589,9 @@
7851 q = p;
7852 p = p->pListNext;
7853 if (ht->pDestructor) {
7854+#if HARDENING_PATCH_HASH_PROTECT
7855+ CHECK_HASH_CANARY(ht);
7856+#endif
7857 ht->pDestructor(q->pData);
7858 }
7859 if (!q->pDataPtr && q->pData) {
7860@@ -579,6 +618,9 @@
7861 q = p;
7862 p = p->pListNext;
7863 if (ht->pDestructor) {
7864+#if HARDENING_PATCH_HASH_PROTECT
7865+ CHECK_HASH_CANARY(ht);
7866+#endif
7867 ht->pDestructor(q->pData);
7868 }
7869 if (!q->pDataPtr && q->pData) {
7870@@ -608,6 +650,9 @@
7871 HANDLE_BLOCK_INTERRUPTIONS();
7872
7873 if (ht->pDestructor) {
7874+#if HARDENING_PATCH_HASH_PROTECT
7875+ CHECK_HASH_CANARY(ht);
7876+#endif
7877 ht->pDestructor(p->pData);
7878 }
7879 if (!p->pDataPtr) {
7880diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.9/Zend/zend_hash.h
7881--- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100
7882+++ hardening-patch-4.4.2-0.4.9/Zend/zend_hash.h 2006-05-02 16:46:34.000000000 +0200
7883@@ -54,6 +54,9 @@
7884 } Bucket;
7885
7886 typedef struct _hashtable {
7887+#if HARDENING_PATCH_HASH_PROTECT
7888+ unsigned int canary;
7889+#endif
7890 uint nTableSize;
7891 uint nTableMask;
7892 uint nNumOfElements;
7893diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.9/Zend/zend_ini.h
7894--- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7895+++ hardening-patch-4.4.2-0.4.9/Zend/zend_ini.h 2006-05-02 16:46:34.000000000 +0200
7896@@ -174,6 +174,7 @@
7897 /* Standard message handlers */
7898 BEGIN_EXTERN_C()
7899 ZEND_API ZEND_INI_MH(OnUpdateBool);
7900+#define OnUpdateLong OnUpdateInt
7901 ZEND_API ZEND_INI_MH(OnUpdateInt);
7902 ZEND_API ZEND_INI_MH(OnUpdateReal);
7903 ZEND_API ZEND_INI_MH(OnUpdateString);
7904diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.9/Zend/zend_language_scanner.l
7905--- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100
7906+++ hardening-patch-4.4.2-0.4.9/Zend/zend_language_scanner.l 2006-05-02 16:46:34.000000000 +0200
7907@@ -393,6 +393,13 @@
7908 compilation_successful=0;
7909 } else {
7910 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7911+#if HARDENING_PATCH
7912+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7913+ op_array->created_by_eval = 1;
7914+ } else {
7915+ op_array->created_by_eval = 0;
7916+ }
7917+#endif
7918 CG(in_compilation) = 1;
7919 CG(active_op_array) = op_array;
7920 compiler_result = zendparse(TSRMLS_C);
7921diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.9/Zend/zend_language_scanner.c
7922--- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100
7923+++ hardening-patch-4.4.2-0.4.9/Zend/zend_language_scanner.c 2006-05-02 16:46:34.000000000 +0200
7924@@ -3036,6 +3036,13 @@
7925 compilation_successful=0;
7926 } else {
7927 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7928+#if HARDENING_PATCH
7929+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7930+ op_array->created_by_eval = 1;
7931+ } else {
7932+ op_array->created_by_eval = 0;
7933+ }
7934+#endif
7935 CG(in_compilation) = 1;
7936 CG(active_op_array) = op_array;
7937 compiler_result = zendparse(TSRMLS_C);
7938diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.9/Zend/zend_llist.c
7939--- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100
7940+++ hardening-patch-4.4.2-0.4.9/Zend/zend_llist.c 2006-05-02 16:46:34.000000000 +0200
7941@@ -21,9 +21,49 @@
7942 #include "zend.h"
7943 #include "zend_llist.h"
7944 #include "zend_qsort.h"
7945+#include "zend_globals.h"
7946+
7947+#if HARDENING_PATCH_LL_PROTECT
7948+ unsigned int zend_llist_canary_1 = 0x1234567;
7949+ unsigned int zend_llist_canary_2 = 0x1553425;
7950+ zend_bool zend_llist_canary_inited = 0;
7951+#endif
7952+
7953+#define CHECK_LIST_CANARY(list) \
7954+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7955+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7956+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7957+ exit(1); \
7958+ }
7959+
7960+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7961+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7962+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7963+ exit(1); \
7964+ }
7965+
7966
7967 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7968 {
7969+#if HARDENING_PATCH_LL_PROTECT
7970+ TSRMLS_FETCH();
7971+
7972+ if (persistent) {
7973+ if (!zend_llist_canary_inited) {
7974+ /* do not change order to ensure thread safety */
7975+ zend_llist_canary_1 = zend_canary();
7976+ zend_llist_canary_2 = zend_canary();
7977+ zend_llist_canary_inited = 1;
7978+ }
7979+ } else
7980+ if (!HG(ll_canary_inited)) {
7981+ HG(canary_3) = zend_canary();
7982+ HG(canary_4) = zend_canary();
7983+ HG(ll_canary_inited) = 1;
7984+ }
7985+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7986+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7987+#endif
7988 l->head = NULL;
7989 l->tail = NULL;
7990 l->count = 0;
7991@@ -37,6 +77,11 @@
7992 {
7993 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7994
7995+#if HARDENING_PATCH_LL_PROTECT
7996+ TSRMLS_FETCH();
7997+ CHECK_LIST_CANARY(l)
7998+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7999+#endif
8000 tmp->prev = l->tail;
8001 tmp->next = NULL;
8002 if (l->tail) {
8003@@ -55,6 +100,11 @@
8004 {
8005 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8006
8007+#if HARDENING_PATCH_LL_PROTECT
8008+ TSRMLS_FETCH();
8009+ CHECK_LIST_CANARY(l)
8010+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8011+#endif
8012 tmp->next = l->head;
8013 tmp->prev = NULL;
8014 if (l->head) {
8015@@ -91,10 +141,20 @@
8016 zend_llist_element *current=l->head;
8017 zend_llist_element *next;
8018
8019+#if HARDENING_PATCH_LL_PROTECT
8020+ TSRMLS_FETCH();
8021+ CHECK_LIST_CANARY(l)
8022+#endif
8023 while (current) {
8024+#if HARDENING_PATCH_LL_PROTECT
8025+ CHECK_LISTELEMENT_CANARY(current, l)
8026+#endif
8027 next = current->next;
8028 if (compare(current->data, element)) {
8029 DEL_LLIST_ELEMENT(current, l);
8030+#if HARDENING_PATCH_LL_PROTECT
8031+ current->canary = 0;
8032+#endif
8033 break;
8034 }
8035 current = next;
8036@@ -106,7 +166,14 @@
8037 {
8038 zend_llist_element *current=l->head, *next;
8039
8040+#if HARDENING_PATCH_LL_PROTECT
8041+ TSRMLS_FETCH();
8042+ CHECK_LIST_CANARY(l)
8043+#endif
8044 while (current) {
8045+#if HARDENING_PATCH_LL_PROTECT
8046+ CHECK_LISTELEMENT_CANARY(current, l)
8047+#endif
8048 next = current->next;
8049 if (l->dtor) {
8050 l->dtor(current->data);
8051@@ -131,7 +198,14 @@
8052 zend_llist_element *old_tail;
8053 void *data;
8054
8055+#if HARDENING_PATCH_LL_PROTECT
8056+ TSRMLS_FETCH();
8057+ CHECK_LIST_CANARY(l)
8058+#endif
8059 if ((old_tail = l->tail)) {
8060+#if HARDENING_PATCH_LL_PROTECT
8061+ CHECK_LISTELEMENT_CANARY(old_tail, l)
8062+#endif
8063 if (l->tail->prev) {
8064 l->tail->prev->next = NULL;
8065 }
8066@@ -157,9 +231,16 @@
8067 {
8068 zend_llist_element *ptr;
8069
8070+#if HARDENING_PATCH_LL_PROTECT
8071+ TSRMLS_FETCH();
8072+ CHECK_LIST_CANARY(src)
8073+#endif
8074 zend_llist_init(dst, src->size, src->dtor, src->persistent);
8075 ptr = src->head;
8076 while (ptr) {
8077+#if HARDENING_PATCH_LL_PROTECT
8078+ CHECK_LISTELEMENT_CANARY(ptr, src)
8079+#endif
8080 zend_llist_add_element(dst, ptr->data);
8081 ptr = ptr->next;
8082 }
8083@@ -170,11 +251,21 @@
8084 {
8085 zend_llist_element *element, *next;
8086
8087+#if HARDENING_PATCH_LL_PROTECT
8088+ TSRMLS_FETCH();
8089+ CHECK_LIST_CANARY(l)
8090+#endif
8091 element=l->head;
8092 while (element) {
8093+#if HARDENING_PATCH_LL_PROTECT
8094+ CHECK_LISTELEMENT_CANARY(element, l)
8095+#endif
8096 next = element->next;
8097 if (func(element->data)) {
8098 DEL_LLIST_ELEMENT(element, l);
8099+#if HARDENING_PATCH_LL_PROTECT
8100+ element->canary = 0;
8101+#endif
8102 }
8103 element = next;
8104 }
8105@@ -185,7 +276,13 @@
8106 {
8107 zend_llist_element *element;
8108
8109+#if HARDENING_PATCH_LL_PROTECT
8110+ CHECK_LIST_CANARY(l)
8111+#endif
8112 for (element=l->head; element; element=element->next) {
8113+#if HARDENING_PATCH_LL_PROTECT
8114+ CHECK_LISTELEMENT_CANARY(element, l)
8115+#endif
8116 func(element->data TSRMLS_CC);
8117 }
8118 }
8119@@ -197,6 +294,9 @@
8120 zend_llist_element **elements;
8121 zend_llist_element *element, **ptr;
8122
8123+#if HARDENING_PATCH_LL_PROTECT
8124+ CHECK_LIST_CANARY(l)
8125+#endif
8126 if (l->count <= 0) {
8127 return;
8128 }
8129@@ -206,6 +306,9 @@
8130 ptr = &elements[0];
8131
8132 for (element=l->head; element; element=element->next) {
8133+#if HARDENING_PATCH_LL_PROTECT
8134+ CHECK_LISTELEMENT_CANARY(element, l)
8135+#endif
8136 *ptr++ = element;
8137 }
8138
8139@@ -228,7 +331,13 @@
8140 {
8141 zend_llist_element *element;
8142
8143+#if HARDENING_PATCH_LL_PROTECT
8144+ CHECK_LIST_CANARY(l)
8145+#endif
8146 for (element=l->head; element; element=element->next) {
8147+#if HARDENING_PATCH_LL_PROTECT
8148+ CHECK_LISTELEMENT_CANARY(element, l)
8149+#endif
8150 func(element->data, arg TSRMLS_CC);
8151 }
8152 }
8153@@ -239,8 +348,14 @@
8154 zend_llist_element *element;
8155 va_list args;
8156
8157+#if HARDENING_PATCH_LL_PROTECT
8158+ CHECK_LIST_CANARY(l)
8159+#endif
8160 va_start(args, num_args);
8161 for (element=l->head; element; element=element->next) {
8162+#if HARDENING_PATCH_LL_PROTECT
8163+ CHECK_LISTELEMENT_CANARY(element, l)
8164+#endif
8165 func(element->data, num_args, args TSRMLS_CC);
8166 }
8167 va_end(args);
8168@@ -249,6 +364,10 @@
8169
8170 ZEND_API int zend_llist_count(zend_llist *l)
8171 {
8172+#if HARDENING_PATCH_LL_PROTECT
8173+ TSRMLS_FETCH();
8174+ CHECK_LIST_CANARY(l)
8175+#endif
8176 return l->count;
8177 }
8178
8179@@ -256,8 +375,15 @@
8180 {
8181 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8182
8183+#if HARDENING_PATCH_LL_PROTECT
8184+ TSRMLS_FETCH();
8185+ CHECK_LIST_CANARY(l)
8186+#endif
8187 *current = l->head;
8188 if (*current) {
8189+#if HARDENING_PATCH_LL_PROTECT
8190+ CHECK_LISTELEMENT_CANARY(*current, l)
8191+#endif
8192 return (*current)->data;
8193 } else {
8194 return NULL;
8195@@ -269,8 +395,15 @@
8196 {
8197 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8198
8199+#if HARDENING_PATCH_LL_PROTECT
8200+ TSRMLS_FETCH();
8201+ CHECK_LIST_CANARY(l)
8202+#endif
8203 *current = l->tail;
8204 if (*current) {
8205+#if HARDENING_PATCH_LL_PROTECT
8206+ CHECK_LISTELEMENT_CANARY(*current, l)
8207+#endif
8208 return (*current)->data;
8209 } else {
8210 return NULL;
8211@@ -282,9 +415,19 @@
8212 {
8213 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8214
8215+#if HARDENING_PATCH_LL_PROTECT
8216+ TSRMLS_FETCH();
8217+ CHECK_LIST_CANARY(l)
8218+#endif
8219 if (*current) {
8220+#if HARDENING_PATCH_LL_PROTECT
8221+ CHECK_LISTELEMENT_CANARY(*current, l)
8222+#endif
8223 *current = (*current)->next;
8224 if (*current) {
8225+#if HARDENING_PATCH_LL_PROTECT
8226+ CHECK_LISTELEMENT_CANARY(*current, l)
8227+#endif
8228 return (*current)->data;
8229 }
8230 }
8231@@ -296,9 +439,19 @@
8232 {
8233 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8234
8235+#if HARDENING_PATCH_LL_PROTECT
8236+ TSRMLS_FETCH();
8237+ CHECK_LIST_CANARY(l)
8238+#endif
8239 if (*current) {
8240+#if HARDENING_PATCH_LL_PROTECT
8241+ CHECK_LISTELEMENT_CANARY(*current, l)
8242+#endif
8243 *current = (*current)->prev;
8244 if (*current) {
8245+#if HARDENING_PATCH_LL_PROTECT
8246+ CHECK_LISTELEMENT_CANARY(*current, l)
8247+#endif
8248 return (*current)->data;
8249 }
8250 }
8251diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.9/Zend/zend_llist.h
8252--- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100
8253+++ hardening-patch-4.4.2-0.4.9/Zend/zend_llist.h 2006-05-02 16:46:34.000000000 +0200
8254@@ -24,6 +24,9 @@
8255 #include <stdlib.h>
8256
8257 typedef struct _zend_llist_element {
8258+#if HARDENING_PATCH_LL_PROTECT
8259+ unsigned int canary, padding;
8260+#endif
8261 struct _zend_llist_element *next;
8262 struct _zend_llist_element *prev;
8263 char data[1]; /* Needs to always be last in the struct */
8264@@ -36,6 +39,9 @@
8265 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
8266
8267 typedef struct _zend_llist {
8268+#if HARDENING_PATCH_LL_PROTECT
8269+ unsigned int canary_h; /* head */
8270+#endif
8271 zend_llist_element *head;
8272 zend_llist_element *tail;
8273 size_t size;
8274@@ -43,6 +49,9 @@
8275 llist_dtor_func_t dtor;
8276 unsigned char persistent;
8277 zend_llist_element *traverse_ptr;
8278+#if HARDENING_PATCH_LL_PROTECT
8279+ unsigned int canary_t; /* tail */
8280+#endif
8281 } zend_llist;
8282
8283 typedef zend_llist_element* zend_llist_position;
8284diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.9/Zend/zend_modules.h
8285--- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100
8286+++ hardening-patch-4.4.2-0.4.9/Zend/zend_modules.h 2006-05-02 16:46:34.000000000 +0200
8287@@ -34,6 +34,7 @@
8288 ZEND_API extern unsigned char second_arg_force_ref[];
8289 ZEND_API extern unsigned char third_arg_force_ref[];
8290
8291+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8292 #define ZEND_MODULE_API_NO 20020429
8293 #ifdef ZTS
8294 #define USING_ZTS 1
8295@@ -41,9 +42,9 @@
8296 #define USING_ZTS 0
8297 #endif
8298
8299-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8300+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8301
8302-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8303+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8304
8305 #define STANDARD_MODULE_PROPERTIES \
8306 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8307@@ -75,6 +76,7 @@
8308 unsigned char type;
8309 void *handle;
8310 int module_number;
8311+ unsigned int real_zend_api;
8312 };
8313
8314
8315diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.9/Zend/zend_opcode.c
8316--- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100
8317+++ hardening-patch-4.4.2-0.4.9/Zend/zend_opcode.c 2006-05-02 16:46:34.000000000 +0200
8318@@ -88,6 +88,9 @@
8319 op_array->done_pass_two = 0;
8320
8321 op_array->start_op = NULL;
8322+#if HARDENING_PATCH
8323+ op_array->created_by_eval = 0;
8324+#endif
8325
8326 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8327 }
8328diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.9/Zend/zend_operators.c
8329--- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100
8330+++ hardening-patch-4.4.2-0.4.9/Zend/zend_operators.c 2006-05-02 16:46:34.000000000 +0200
8331@@ -1604,6 +1604,20 @@
8332 return (op->value.lval ? 1 : 0);
8333 }
8334
8335+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8336+{
8337+ register unsigned char *str = (unsigned char*)source;
8338+ register unsigned char *result = (unsigned char*)dest;
8339+ register unsigned char *end = str + length;
8340+
8341+ while (str < end) {
8342+ *result++ = tolower((int)*str++);
8343+ }
8344+ *result = *end;
8345+
8346+ return dest;
8347+}
8348+
8349 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8350 {
8351 register char *p=str, *end=p+length;
8352diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.9/Zend/zend_operators.h
8353--- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100
8354+++ hardening-patch-4.4.2-0.4.9/Zend/zend_operators.h 2006-05-02 16:46:34.000000000 +0200
8355@@ -174,6 +174,14 @@
8356 #endif
8357
8358 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8359+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8360+
8361+static inline char *
8362+zend_str_tolower_dup(const char *source, unsigned int length)
8363+{
8364+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8365+}
8366+
8367 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8368 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8369 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);