summaryrefslogtreecommitdiff
path: root/hardening-patch-4.4.4-0.4.15.patch
diff options
context:
space:
mode:
authorjvoisin2018-09-11 10:30:39 +0200
committerjvoisin2018-09-11 10:30:39 +0200
commit5321e0fcf6ab6e6cc5d95b4cbd9bc0f7e44e01fe (patch)
tree25ce8c8ffe0880fe8c7aedde6df1c6d0a80c6d37 /hardening-patch-4.4.4-0.4.15.patch
first commit
Diffstat (limited to 'hardening-patch-4.4.4-0.4.15.patch')
-rw-r--r--hardening-patch-4.4.4-0.4.15.patch8300
1 files changed, 8300 insertions, 0 deletions
diff --git a/hardening-patch-4.4.4-0.4.15.patch b/hardening-patch-4.4.4-0.4.15.patch
new file mode 100644
index 0000000..c0208f6
--- /dev/null
+++ b/hardening-patch-4.4.4-0.4.15.patch
@@ -0,0 +1,8300 @@
1diff -Nura php-4.4.4/Changelog.hphp hardening-patch-4.4.4-0.4.15/Changelog.hphp
2--- php-4.4.4/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100
3+++ hardening-patch-4.4.4-0.4.15/Changelog.hphp 2006-09-07 19:32:38.000000000 +0200
4@@ -0,0 +1,61 @@
5+Changelog of the Hardening-Patch
6+--------------------------------
7+
8+0.4.15 - 07. September 2006
9+
10+ PHP4:
11+ [+] Fix for potential DOS in handling of include blacklists
12+
13+ PHP4+5:
14+ [+] Backported a fix for open_basedir problems with insanse PHP scripts
15+ [+] Added a fix for ini_restore() PHP security vulnerability
16+
17+0.4.14 - 11. August 2006
18+
19+ PHP4:
20+ [+] Remove unecessary call to AC_BROKEN_REALPATH
21+
22+ PHP5:
23+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant
24+
25+ PHP4+5:
26+ [+] Added a few PHP security fixes / see changelog.secfix for details
27+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits
28+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments
29+
30+0.4.13 - 07. August 2006
31+
32+ PHP4+5:
33+ [+] Added a fix for a compile problem on solaris due to missing strcasestr()
34+
35+0.4.12 - 19. July 2006
36+
37+ PHP4:
38+ [+] Added fixes from sf4 security patch / see changelog.secfix for details
39+
40+ PHP5:
41+ [+] Added fixes from sf5 security patch / see changelog.secfix for details
42+
43+ PHP4+5:
44+ [+] Added anti mail spam feature
45+ [+] Speedup of zend_hash canary (clear/destroy)
46+ [+] Added a fix for a DOS in the handling of URL blacklists
47+
48+0.4.11 - 13. May 2006
49+
50+ PHP5:
51+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache
52+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4
53+
54+ PHP4+5:
55+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories
56+
57+
58+0.4.10 - 11. May 2006
59+
60+ PHP4:
61+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
62+
63+ PHP4+5:
64+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
65+
66diff -Nura php-4.4.4/Changelog.secfix hardening-patch-4.4.4-0.4.15/Changelog.secfix
67--- php-4.4.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100
68+++ hardening-patch-4.4.4-0.4.15/Changelog.secfix 2006-09-05 20:30:51.000000000 +0200
69@@ -0,0 +1,17 @@
70+Changelog of PHP 4.4.3 Security Fixes
71+
72+Release 2 - 11. August 2006
73+
74+ [+] Added IMAP open_basedir/safe_mode check
75+ [+] Added a upstream fix for previous ext/session fixes
76+ [+] Added upstream fix to ext/socket
77+ [+] Added sscanf() security fix
78+ [+] Added fixes for handling of corrupt .gif files to gdlib
79+
80+Release 1 - 4. August 2006
81+
82+ [+] Added a fix to disable CURLOPT_FOLLOWLOCATION while in safe_mode()/open_basedir
83+ [+] Added a *working* wordwrap() fix
84+ [+] Added code to make memory_limit work on 64bit systems
85+ [+] Added a fix for an integer overflow in str_repeat()
86+
87diff -Nura php-4.4.4/configure hardening-patch-4.4.4-0.4.15/configure
88--- php-4.4.4/configure 2006-08-15 14:01:18.000000000 +0200
89+++ hardening-patch-4.4.4-0.4.15/configure 2006-09-05 20:30:51.000000000 +0200
90@@ -402,6 +402,16 @@
91 ac_default_prefix=/usr/local
92 # Any additions from configure.in:
93 ac_help="$ac_help
94+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
95+ac_help="$ac_help
96+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
97+ac_help="$ac_help
98+ --disable-hardening-patch-inc-protect Disable include/require protection."
99+ac_help="$ac_help
100+ --disable-hardening-patch-fmt-protect Disable format string protection."
101+ac_help="$ac_help
102+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
103+ac_help="$ac_help
104
105 SAPI modules:
106 "
107@@ -854,6 +864,8 @@
108 ac_help="$ac_help
109 --disable-tokenizer Disable tokenizer support"
110 ac_help="$ac_help
111+ --disable-varfilter Disable Hardening-Patch's variable filter"
112+ac_help="$ac_help
113 --enable-wddx Enable WDDX support."
114 ac_help="$ac_help
115 --disable-xml Disable XML support using bundled expat lib"
116@@ -2942,6 +2954,157 @@
117
118
119
120+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
121+if test "${enable_hardening_patch_mm_protect+set}" = set; then
122+ enableval="$enable_hardening_patch_mm_protect"
123+
124+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
125+
126+else
127+
128+ DO_HARDENING_PATCH_MM_PROTECT=yes
129+
130+fi
131+
132+
133+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
134+if test "${enable_hardening_patch_ll_protect+set}" = set; then
135+ enableval="$enable_hardening_patch_ll_protect"
136+
137+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
138+
139+else
140+
141+ DO_HARDENING_PATCH_LL_PROTECT=yes
142+
143+fi
144+
145+
146+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
147+if test "${enable_hardening_patch_inc_protect+set}" = set; then
148+ enableval="$enable_hardening_patch_inc_protect"
149+
150+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
151+
152+else
153+
154+ DO_HARDENING_PATCH_INC_PROTECT=yes
155+
156+fi
157+
158+
159+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
160+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
161+ enableval="$enable_hardening_patch_fmt_protect"
162+
163+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
164+
165+else
166+
167+ DO_HARDENING_PATCH_FMT_PROTECT=yes
168+
169+fi
170+
171+
172+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
173+if test "${enable_hardening_patch_hash_protect+set}" = set; then
174+ enableval="$enable_hardening_patch_hash_protect"
175+
176+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
177+
178+else
179+
180+ DO_HARDENING_PATCH_HASH_PROTECT=yes
181+
182+fi
183+
184+
185+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
186+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
187+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
188+
189+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
190+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
191+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
192+
193+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
194+echo "configure:2733: checking whether to protect include/require statements" >&5
195+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
196+
197+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
198+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
199+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
200+
201+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
202+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
203+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
204+
205+
206+cat >> confdefs.h <<\EOF
207+#define HARDENING_PATCH 1
208+EOF
209+
210+
211+
212+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
213+ cat >> confdefs.h <<\EOF
214+#define HARDENING_PATCH_MM_PROTECT 1
215+EOF
216+
217+else
218+ cat >> confdefs.h <<\EOF
219+#define HARDENING_PATCH_MM_PROTECT 0
220+EOF
221+
222+fi
223+
224+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
225+ cat >> confdefs.h <<\EOF
226+#define HARDENING_PATCH_LL_PROTECT 1
227+EOF
228+
229+else
230+ cat >> confdefs.h <<\EOF
231+#define HARDENING_PATCH_LL_PROTECT 0
232+EOF
233+
234+fi
235+
236+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
237+ cat >> confdefs.h <<\EOF
238+#define HARDENING_PATCH_INC_PROTECT 1
239+EOF
240+
241+else
242+ cat >> confdefs.h <<\EOF
243+#define HARDENING_PATCH_INC_PROTECT 0
244+EOF
245+
246+fi
247+
248+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
249+ cat >> confdefs.h <<\EOF
250+#define HARDENING_PATCH_FMT_PROTECT 1
251+EOF
252+
253+else
254+ cat >> confdefs.h <<\EOF
255+#define HARDENING_PATCH_FMT_PROTECT 0
256+EOF
257+
258+fi
259+
260+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
261+ cat >> confdefs.h <<\EOF
262+#define HARDENING_PATCH_HASH_PROTECT 1
263+EOF
264+
265+else
266+ cat >> confdefs.h <<\EOF
267+#define HARDENING_PATCH_HASH_PROTECT 0
268+EOF
269+
270+fi
271
272
273
274@@ -16017,6 +16180,62 @@
275 fi
276
277
278+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
279+echo "configure:14928: checking whether realpath is broken" >&5
280+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
281+ echo $ac_n "(cached) $ac_c" 1>&6
282+else
283+
284+ if test "$cross_compiling" = yes; then
285+
286+ ac_cv_broken_realpath=no
287+
288+else
289+ cat > conftest.$ac_ext <<EOF
290+#line 14939 "configure"
291+#include "confdefs.h"
292+
293+main() {
294+ char buf[4096+1];
295+ buf[0] = 0;
296+ realpath("/etc/hosts/../passwd", buf);
297+ exit(strcmp(buf, "/etc/passwd")==0);
298+}
299+
300+EOF
301+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
302+then
303+
304+ ac_cv_broken_realpath=no
305+
306+else
307+ echo "configure: failed program was:" >&5
308+ cat conftest.$ac_ext >&5
309+ rm -fr conftest*
310+
311+ ac_cv_broken_realpath=yes
312+
313+fi
314+rm -fr conftest*
315+fi
316+
317+
318+fi
319+
320+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
321+ if test "$ac_cv_broken_realpath" = "yes"; then
322+ cat >> confdefs.h <<\EOF
323+#define PHP_BROKEN_REALPATH 1
324+EOF
325+
326+ else
327+ cat >> confdefs.h <<\EOF
328+#define PHP_BROKEN_REALPATH 0
329+EOF
330+
331+ fi
332+
333+
334 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
335 echo "configure:16022: checking for declared timezone" >&5
336 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
337@@ -86718,7 +86937,7 @@
338 if test "$ac_cv_crypt_blowfish" = "yes"; then
339 ac_result=1
340 else
341- ac_result=0
342+ ac_result=1
343 fi
344 cat >> confdefs.h <<EOF
345 #define PHP_BLOWFISH_CRYPT $ac_result
346@@ -87420,7 +87639,7 @@
347 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
348 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
349 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
350- var_unserializer.c ftok.c aggregation.c sha1.c ; do
351+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
352
353 IFS=.
354 set $ac_src
355@@ -87475,7 +87694,7 @@
356 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
357 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
358 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
359- var_unserializer.c ftok.c aggregation.c sha1.c ; do
360+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
361
362 IFS=.
363 set $ac_src
364@@ -87601,7 +87820,7 @@
365 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
366 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
367 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
368- var_unserializer.c ftok.c aggregation.c sha1.c ; do
369+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
370
371 IFS=.
372 set $ac_src
373@@ -87653,7 +87872,7 @@
374 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
375 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
376 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
377- var_unserializer.c ftok.c aggregation.c sha1.c ; do
378+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
379
380 IFS=.
381 set $ac_src
382@@ -91124,6 +91343,265 @@
383 fi
384
385
386+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
387+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
388+# Check whether --enable-varfilter or --disable-varfilter was given.
389+if test "${enable_varfilter+set}" = set; then
390+ enableval="$enable_varfilter"
391+ PHP_VARFILTER=$enableval
392+else
393+
394+ PHP_VARFILTER=yes
395+
396+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
397+ PHP_VARFILTER=$PHP_ENABLE_ALL
398+ fi
399+
400+fi
401+
402+
403+
404+ext_output="yes, shared"
405+ext_shared=yes
406+case $PHP_VARFILTER in
407+shared,*)
408+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
409+ ;;
410+shared)
411+ PHP_VARFILTER=yes
412+ ;;
413+no)
414+ ext_output=no
415+ ext_shared=no
416+ ;;
417+*)
418+ ext_output=yes
419+ ext_shared=no
420+ ;;
421+esac
422+
423+
424+
425+echo "$ac_t""$ext_output" 1>&6
426+
427+
428+
429+
430+if test "$PHP_VARFILTER" != "no"; then
431+ cat >> confdefs.h <<\EOF
432+#define HAVE_VARFILTER 1
433+EOF
434+
435+
436+ ext_builddir=ext/varfilter
437+ ext_srcdir=$abs_srcdir/ext/varfilter
438+
439+ ac_extra=
440+
441+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
442+
443+
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=$php_c_pre
454+ b_cxx_pre=$php_cxx_pre
455+ b_c_meta=$php_c_meta
456+ b_cxx_meta=$php_cxx_meta
457+ b_c_post=$php_c_post
458+ b_cxx_post=$php_cxx_post
459+ b_lo=$php_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+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $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+ EXT_STATIC="$EXT_STATIC varfilter"
485+ if test "$ext_shared" != "nocli"; then
486+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
487+ fi
488+ else
489+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
490+
491+ case ext/varfilter in
492+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
493+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
494+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
495+ esac
496+
497+
498+
499+ b_c_pre=$shared_c_pre
500+ b_cxx_pre=$shared_cxx_pre
501+ b_c_meta=$shared_c_meta
502+ b_cxx_meta=$shared_cxx_meta
503+ b_c_post=$shared_c_post
504+ b_cxx_post=$shared_cxx_post
505+ b_lo=$shared_lo
506+
507+
508+ old_IFS=$IFS
509+ for ac_src in varfilter.c; do
510+
511+ IFS=.
512+ set $ac_src
513+ ac_obj=$1
514+ IFS=$old_IFS
515+
516+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
517+
518+ case $ac_src in
519+ *.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" ;;
520+ *.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" ;;
521+ esac
522+
523+ cat >>Makefile.objects<<EOF
524+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
525+ $ac_comp
526+EOF
527+ done
528+
529+
530+ install_modules="install-modules"
531+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
532+
533+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
534+
535+ cat >>Makefile.objects<<EOF
536+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
537+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
538+
539+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
540+ \$(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)
541+
542+EOF
543+
544+ cat >> confdefs.h <<EOF
545+#define COMPILE_DL_VARFILTER 1
546+EOF
547+
548+ fi
549+ fi
550+
551+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
552+ if test "$PHP_SAPI" = "cgi"; then
553+
554+
555+ case ext/varfilter in
556+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
557+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
558+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
559+ esac
560+
561+
562+
563+ b_c_pre=$php_c_pre
564+ b_cxx_pre=$php_cxx_pre
565+ b_c_meta=$php_c_meta
566+ b_cxx_meta=$php_cxx_meta
567+ b_c_post=$php_c_post
568+ b_cxx_post=$php_cxx_post
569+ b_lo=$php_lo
570+
571+
572+ old_IFS=$IFS
573+ for ac_src in varfilter.c; do
574+
575+ IFS=.
576+ set $ac_src
577+ ac_obj=$1
578+ IFS=$old_IFS
579+
580+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
581+
582+ case $ac_src in
583+ *.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" ;;
584+ *.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" ;;
585+ esac
586+
587+ cat >>Makefile.objects<<EOF
588+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
589+ $ac_comp
590+EOF
591+ done
592+
593+
594+ EXT_STATIC="$EXT_STATIC varfilter"
595+ else
596+
597+
598+ case ext/varfilter in
599+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
600+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
601+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
602+ esac
603+
604+
605+
606+ b_c_pre=$php_c_pre
607+ b_cxx_pre=$php_cxx_pre
608+ b_c_meta=$php_c_meta
609+ b_cxx_meta=$php_cxx_meta
610+ b_c_post=$php_c_post
611+ b_cxx_post=$php_cxx_post
612+ b_lo=$php_lo
613+
614+
615+ old_IFS=$IFS
616+ for ac_src in varfilter.c; do
617+
618+ IFS=.
619+ set $ac_src
620+ ac_obj=$1
621+ IFS=$old_IFS
622+
623+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
624+
625+ case $ac_src in
626+ *.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" ;;
627+ *.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" ;;
628+ esac
629+
630+ cat >>Makefile.objects<<EOF
631+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
632+ $ac_comp
633+EOF
634+ done
635+
636+
637+ fi
638+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
639+ fi
640+
641+ BUILD_DIR="$BUILD_DIR $ext_builddir"
642+
643+
644+fi
645
646
647 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
648@@ -104088,7 +104566,7 @@
649 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
650 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
651 streams.c network.c php_open_temporary_file.c php_logos.c \
652- output.c memory_streams.c user_streams.c; do
653+ output.c memory_streams.c user_streams.c hardening_patch.c; do
654
655 IFS=.
656 set $ac_src
657@@ -104273,7 +104751,7 @@
658 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
659 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
660 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
661- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
662+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
663
664 IFS=.
665 set $ac_src
666diff -Nura php-4.4.4/configure.in hardening-patch-4.4.4-0.4.15/configure.in
667--- php-4.4.4/configure.in 2006-08-15 14:22:14.000000000 +0200
668+++ hardening-patch-4.4.4-0.4.15/configure.in 2006-09-05 20:30:51.000000000 +0200
669@@ -247,7 +247,7 @@
670 sinclude(Zend/acinclude.m4)
671 sinclude(Zend/Zend.m4)
672 sinclude(TSRM/tsrm.m4)
673-
674+sinclude(main/hardening_patch.m4)
675
676
677 divert(2)
678@@ -621,6 +621,7 @@
679 AC_FUNC_ALLOCA
680 dnl PHP_AC_BROKEN_SPRINTF
681 dnl PHP_AC_BROKEN_SNPRINTF
682+dnl PHP_AC_BROKEN_REALPATH
683 PHP_DECLARED_TIMEZONE
684 PHP_TIME_R_TYPE
685 PHP_READDIR_R_TYPE
686@@ -1260,7 +1261,7 @@
687 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
688 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
689 streams.c network.c php_open_temporary_file.c php_logos.c \
690- output.c memory_streams.c user_streams.c)
691+ output.c memory_streams.c user_streams.c hardening_patch.c)
692 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
693 case $host_alias in
694 *netware*)
695@@ -1281,7 +1282,7 @@
696 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
697 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
698 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
699- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
700+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
701
702 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
703 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
704diff -Nura php-4.4.4/ext/fbsql/php_fbsql.c hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c
705--- php-4.4.4/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100
706+++ hardening-patch-4.4.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:30:51.000000000 +0200
707@@ -1797,8 +1797,24 @@
708 }
709 else if (fbcmdErrorsFound(md))
710 {
711+#if HARDENING_PATCH
712+ char* query_copy;
713+ int i;
714+#endif
715 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
716 char* emg = fbcemdAllErrorMessages(emd);
717+#if HARDENING_PATCH
718+ query_copy=estrdup(query_copy);
719+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
720+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
721+ efree(query_copy);
722+ if (HG(hphp_sql_bailout_on_error)) {
723+ free(emg);
724+ fbcemdRelease(emd);
725+ result = 0;
726+ zend_bailout();
727+ }
728+#endif
729 if (FB_SQL_G(generateWarnings))
730 {
731 if (emg)
732diff -Nura php-4.4.4/ext/imap/php_imap.c hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c
733--- php-4.4.4/ext/imap/php_imap.c 2006-08-11 17:07:00.000000000 +0200
734+++ hardening-patch-4.4.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:30:51.000000000 +0200
735@@ -738,6 +738,13 @@
736 RETURN_FALSE;
737 }
738
739+ /* local filename, need to perform open_basedir and safe_mode checks */
740+ if (Z_STRVAL_PP(mailbox)[0] != '{' &&
741+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) ||
742+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) {
743+ RETURN_FALSE;
744+ }
745+
746 IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user));
747 IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd));
748
749diff -Nura php-4.4.4/ext/mbstring/mbstring.c hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c
750--- php-4.4.4/ext/mbstring/mbstring.c 2006-04-03 15:04:13.000000000 +0200
751+++ hardening-patch-4.4.4-0.4.15/ext/mbstring/mbstring.c 2006-09-05 20:30:51.000000000 +0200
752@@ -1500,6 +1500,7 @@
753 char *strtok_buf = NULL, **val_list;
754 zval *array_ptr = (zval *) arg;
755 int n, num, val_len, *len_list;
756+ unsigned int new_val_len;
757 enum mbfl_no_encoding from_encoding;
758 mbfl_string string, resvar, resval;
759 mbfl_encoding_detector *identd = NULL;
760@@ -1622,8 +1623,14 @@
761 val_len = len_list[n];
762 }
763 n++;
764- /* add variable to symbol table */
765- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
766+ /* we need val to be emalloc()ed */
767+ val = estrndup(val, val_len);
768+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
769+ /* add variable to symbol table */
770+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
771+ }
772+ efree(val);
773+
774 if (convd != NULL){
775 mbfl_string_clear(&resvar);
776 mbfl_string_clear(&resval);
777diff -Nura php-4.4.4/ext/mysql/php_mysql.c hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c
778--- php-4.4.4/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100
779+++ hardening-patch-4.4.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:30:51.000000000 +0200
780@@ -1218,6 +1218,8 @@
781 {
782 php_mysql_conn *mysql;
783 MYSQL_RES *mysql_result;
784+ char *copy_query;
785+ int i;
786
787 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
788
789@@ -1268,6 +1270,13 @@
790 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
791 }
792 }
793+ copy_query = estrdup(Z_STRVAL_PP(query));
794+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
795+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
796+ efree(copy_query);
797+ if (HG(hphp_sql_bailout_on_error)) {
798+ zend_bailout();
799+ }
800 RETURN_FALSE;
801 }
802 #else
803@@ -1275,12 +1284,20 @@
804 /* check possible error */
805 if (MySG(trace_mode)){
806 if (mysql_errno(&mysql->conn)){
807- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
808+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
809 }
810 }
811+ copy_query = estrdup(Z_STRVAL_PP(query));
812+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
813+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
814+ efree(copy_query);
815+ if (HG(hphp_sql_bailout_on_error)) {
816+ zend_bailout();
817+ }
818 RETURN_FALSE;
819 }
820 #endif
821+
822 if(use_store == MYSQL_USE_RESULT) {
823 mysql_result=mysql_use_result(&mysql->conn);
824 } else {
825diff -Nura php-4.4.4/ext/pgsql/pgsql.c hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c
826--- php-4.4.4/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100
827+++ hardening-patch-4.4.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:30:51.000000000 +0200
828@@ -1001,10 +1001,28 @@
829 case PGRES_EMPTY_QUERY:
830 case PGRES_BAD_RESPONSE:
831 case PGRES_NONFATAL_ERROR:
832- case PGRES_FATAL_ERROR:
833- PHP_PQ_ERROR("Query failed: %s", pgsql);
834- PQclear(pgsql_result);
835- RETURN_FALSE;
836+ case PGRES_FATAL_ERROR:
837+ {
838+#if HARDENING_PATCH
839+ int i;
840+ char *query_copy;
841+#endif
842+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
843+ PQclear(pgsql_result);
844+#if HARDENING_PATCH
845+ query_copy = estrdup(Z_STRVAL_PP(query));
846+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
847+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
848+ efree(query_copy);
849+ if (HG(hphp_sql_bailout_on_error)) {
850+ efree(msgbuf);
851+ zend_bailout();
852+ }
853+#endif
854+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
855+ efree(msgbuf);
856+ RETURN_FALSE;
857+ }
858 break;
859 case PGRES_COMMAND_OK: /* successful command that did not return rows */
860 default:
861diff -Nura php-4.4.4/ext/session/mod_files.c hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c
862--- php-4.4.4/ext/session/mod_files.c 2006-08-11 17:04:28.000000000 +0200
863+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:30:51.000000000 +0200
864@@ -397,6 +397,34 @@
865 return SUCCESS;
866 }
867
868+PS_VALIDATE_SID_FUNC(files)
869+{
870+ char buf[MAXPATHLEN];
871+ int fd;
872+ PS_FILES_DATA;
873+
874+ if (!ps_files_valid_key(key)) {
875+ return FAILURE;
876+ }
877+
878+ if (!PS(use_strict_mode)) {
879+ return SUCCESS;
880+ }
881+
882+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
883+ return FAILURE;
884+ }
885+
886+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
887+
888+ if (fd != -1) {
889+ close(fd);
890+ return SUCCESS;
891+ }
892+
893+ return FAILURE;
894+}
895+
896 /*
897 * Local variables:
898 * tab-width: 4
899diff -Nura php-4.4.4/ext/session/mod_mm.c hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c
900--- php-4.4.4/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100
901+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:30:51.000000000 +0200
902@@ -425,6 +425,42 @@
903 return SUCCESS;
904 }
905
906+PS_VALIDATE_SID_FUNC(mm)
907+{
908+ PS_MM_DATA;
909+ ps_sd *sd;
910+ const char *p;
911+ char c;
912+ int ret = SUCCESS;
913+
914+ for (p = key; (c = *p); p++) {
915+ /* valid characters are a..z,A..Z,0..9 */
916+ if (!((c >= 'a' && c <= 'z')
917+ || (c >= 'A' && c <= 'Z')
918+ || (c >= '0' && c <= '9')
919+ || c == ','
920+ || c == '-')) {
921+ return FAILURE;
922+ }
923+ }
924+
925+ if (!PS(use_strict_mode)) {
926+ return SUCCESS;
927+ }
928+
929+ mm_lock(data->mm, MM_LOCK_RD);
930+
931+ sd = ps_sd_lookup(data, key, 0);
932+ if (sd) {
933+ mm_unlock(data->mm);
934+ return SUCCESS;
935+ }
936+
937+ mm_unlock(data->mm);
938+
939+ return FAILURE;
940+}
941+
942 #endif
943
944 /*
945diff -Nura php-4.4.4/ext/session/mod_user.c hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c
946--- php-4.4.4/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100
947+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:30:51.000000000 +0200
948@@ -23,7 +23,7 @@
949 #include "mod_user.h"
950
951 ps_module ps_mod_user = {
952- PS_MOD(user)
953+ PS_MOD_SID(user)
954 };
955
956 #define SESS_ZVAL_LONG(val, a) \
957@@ -174,6 +174,83 @@
958 FINISH;
959 }
960
961+PS_CREATE_SID_FUNC(user)
962+{
963+ int i;
964+ char *val = NULL;
965+ zval *retval;
966+ ps_user *mdata = PS_GET_MOD_DATA();
967+
968+ if (!mdata)
969+ return estrndup("", 0);
970+
971+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
972+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
973+ }
974+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
975+
976+ if (retval) {
977+ if (Z_TYPE_P(retval) == IS_STRING) {
978+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
979+ } else {
980+ val = estrndup("", 0);
981+ }
982+ zval_ptr_dtor(&retval);
983+ } else {
984+ val = estrndup("", 0);
985+ }
986+
987+ return val;
988+}
989+
990+static int ps_user_valid_key(const char *key TSRMLS_DC)
991+{
992+ size_t len;
993+ const char *p;
994+ char c;
995+ int ret = SUCCESS;
996+
997+ for (p = key; (c = *p); p++) {
998+ /* valid characters are a..z,A..Z,0..9 */
999+ if (!((c >= 'a' && c <= 'z')
1000+ || (c >= 'A' && c <= 'Z')
1001+ || (c >= '0' && c <= '9')
1002+ || c == ','
1003+ || c == '-')) {
1004+ ret = FAILURE;
1005+ break;
1006+ }
1007+ }
1008+
1009+ len = p - key;
1010+
1011+ if (len == 0)
1012+ ret = FAILURE;
1013+
1014+ return ret;
1015+}
1016+
1017+PS_VALIDATE_SID_FUNC(user)
1018+{
1019+ zval *args[1];
1020+ STDVARS;
1021+
1022+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
1023+ return ps_user_valid_key(key TSRMLS_CC);
1024+ }
1025+ SESS_ZVAL_STRING(key, args[0]);
1026+
1027+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1028+
1029+ if (retval) {
1030+ convert_to_long(retval);
1031+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1032+ zval_ptr_dtor(&retval);
1033+ }
1034+
1035+ return ret;
1036+}
1037+
1038 /*
1039 * Local variables:
1040 * tab-width: 4
1041diff -Nura php-4.4.4/ext/session/mod_user.h hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h
1042--- php-4.4.4/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100
1043+++ hardening-patch-4.4.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:30:51.000000000 +0200
1044@@ -22,7 +22,7 @@
1045 #define MOD_USER_H
1046
1047 typedef union {
1048- zval *names[6];
1049+ zval *names[8];
1050 struct {
1051 zval *ps_open;
1052 zval *ps_close;
1053@@ -30,6 +30,8 @@
1054 zval *ps_write;
1055 zval *ps_destroy;
1056 zval *ps_gc;
1057+ zval *ps_create;
1058+ zval *ps_validate;
1059 } name;
1060 } ps_user;
1061
1062diff -Nura php-4.4.4/ext/session/php_session.h hardening-patch-4.4.4-0.4.15/ext/session/php_session.h
1063--- php-4.4.4/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100
1064+++ hardening-patch-4.4.4-0.4.15/ext/session/php_session.h 2006-09-05 20:30:51.000000000 +0200
1065@@ -23,7 +23,7 @@
1066
1067 #include "ext/standard/php_var.h"
1068
1069-#define PHP_SESSION_API 20020330
1070+#define PHP_SESSION_API 20051121
1071
1072 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1073 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1074@@ -32,6 +32,7 @@
1075 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1076 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1077 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1078+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1079
1080 /* default create id function */
1081 char *php_session_create_id(PS_CREATE_SID_ARGS);
1082@@ -45,6 +46,7 @@
1083 int (*s_destroy)(PS_DESTROY_ARGS);
1084 int (*s_gc)(PS_GC_ARGS);
1085 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1086+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1087 } ps_module;
1088
1089 #define PS_GET_MOD_DATA() *mod_data
1090@@ -57,6 +59,7 @@
1091 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1092 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1093 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1094+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1095
1096 #define PS_FUNCS(x) \
1097 PS_OPEN_FUNC(x); \
1098@@ -65,11 +68,12 @@
1099 PS_WRITE_FUNC(x); \
1100 PS_DESTROY_FUNC(x); \
1101 PS_GC_FUNC(x); \
1102- PS_CREATE_SID_FUNC(x)
1103+ PS_CREATE_SID_FUNC(x); \
1104+ PS_VALIDATE_SID_FUNC(x)
1105
1106 #define PS_MOD(x) \
1107 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1108- ps_delete_##x, ps_gc_##x, php_session_create_id
1109+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1110
1111 /* SID enabled module handler definitions */
1112 #define PS_FUNCS_SID(x) \
1113@@ -79,11 +83,12 @@
1114 PS_WRITE_FUNC(x); \
1115 PS_DESTROY_FUNC(x); \
1116 PS_GC_FUNC(x); \
1117- PS_CREATE_SID_FUNC(x)
1118+ PS_CREATE_SID_FUNC(x); \
1119+ PS_VALIDATE_SID(x)
1120
1121 #define PS_MOD_SID(x) \
1122 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1123- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1124+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1125
1126 typedef enum {
1127 php_session_disabled,
1128@@ -120,6 +125,7 @@
1129 zend_bool use_only_cookies;
1130 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1131 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1132+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1133 int send_cookie;
1134 int define_sid;
1135 } php_ps_globals;
1136diff -Nura php-4.4.4/ext/session/session.c hardening-patch-4.4.4-0.4.15/ext/session/session.c
1137--- php-4.4.4/ext/session/session.c 2006-08-01 10:33:13.000000000 +0200
1138+++ hardening-patch-4.4.4-0.4.15/ext/session/session.c 2006-09-05 20:30:51.000000000 +0200
1139@@ -155,6 +155,7 @@
1140 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1141 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1142 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1143+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1144 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1145 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1146 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1147@@ -643,6 +644,15 @@
1148 return;
1149 }
1150
1151+ /* If there is an ID, use session module to verify it */
1152+ if (PS(id)) {
1153+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1154+ efree(PS(id));
1155+ PS(id) = NULL;
1156+ PS(send_cookie) = 1;
1157+ }
1158+ }
1159+
1160 /* If there is no ID, use session module to create one */
1161 if (!PS(id))
1162 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1163@@ -1266,18 +1276,25 @@
1164 Sets user-level functions */
1165 PHP_FUNCTION(session_set_save_handler)
1166 {
1167- zval **args[6];
1168- int i;
1169+ zval **args[8];
1170+ int i, numargs;
1171 ps_user *mdata;
1172 char *name;
1173
1174- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
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
1182 if (PS(session_status) != php_session_none)
1183 RETURN_FALSE;
1184
1185- for (i = 0; i < 6; i++) {
1186+ for (i = 0; i < 8; i++) {
1187+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1188+ continue;
1189+ }
1190 if (!zend_is_callable(*args[i], 0, &name)) {
1191 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1192 efree(name);
1193@@ -1290,7 +1307,11 @@
1194
1195 mdata = emalloc(sizeof(*mdata));
1196
1197- for (i = 0; i < 6; i++) {
1198+ for (i = 0; i < 8; i++) {
1199+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1200+ mdata->names[i] = NULL;
1201+ continue;
1202+ }
1203 ZVAL_ADDREF(*args[i]);
1204 mdata->names[i] = *args[i];
1205 }
1206@@ -1351,12 +1372,24 @@
1207 Update the current session id with a newly generated one. */
1208 PHP_FUNCTION(session_regenerate_id)
1209 {
1210+ zend_bool del_ses = 0;
1211+
1212+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1213+ WRONG_PARAM_COUNT;
1214+ }
1215+
1216 if (SG(headers_sent)) {
1217 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
1218 RETURN_FALSE;
1219 }
1220 if (PS(session_status) == php_session_active) {
1221- if (PS(id)) efree(PS(id));
1222+ if (PS(id)) {
1223+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1224+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1225+ RETURN_FALSE;
1226+ }
1227+ efree(PS(id));
1228+ }
1229
1230 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1231
1232diff -Nura php-4.4.4/ext/session/tests/014.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt
1233--- php-4.4.4/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1234+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:30:51.000000000 +0200
1235@@ -5,6 +5,7 @@
1236 --INI--
1237 session.use_trans_sid=1
1238 session.use_cookies=0
1239+session.use_strict_mode=0
1240 session.cache_limiter=
1241 register_globals=1
1242 session.bug_compat_42=1
1243diff -Nura php-4.4.4/ext/session/tests/015.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt
1244--- php-4.4.4/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1245+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:30:51.000000000 +0200
1246@@ -5,6 +5,7 @@
1247 --INI--
1248 session.use_trans_sid=1
1249 session.use_cookies=0
1250+session.use_strict_mode=0
1251 session.cache_limiter=
1252 arg_separator.output=&
1253 session.name=PHPSESSID
1254diff -Nura php-4.4.4/ext/session/tests/018.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt
1255--- php-4.4.4/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1256+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:30:51.000000000 +0200
1257@@ -4,6 +4,7 @@
1258 <?php include('skipif.inc'); ?>
1259 --INI--
1260 session.use_cookies=0
1261+session.use_strict_mode=0
1262 session.cache_limiter=
1263 session.use_trans_sid=1
1264 session.name=PHPSESSID
1265diff -Nura php-4.4.4/ext/session/tests/020.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt
1266--- php-4.4.4/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1267+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:30:51.000000000 +0200
1268@@ -4,6 +4,7 @@
1269 <?php include('skipif.inc'); ?>
1270 --INI--
1271 session.use_cookies=0
1272+session.use_strict_mode=0
1273 session.cache_limiter=
1274 session.use_trans_sid=1
1275 arg_separator.output=&amp;
1276diff -Nura php-4.4.4/ext/session/tests/021.phpt hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt
1277--- php-4.4.4/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1278+++ hardening-patch-4.4.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:30:51.000000000 +0200
1279@@ -4,6 +4,7 @@
1280 <?php include('skipif.inc'); ?>
1281 --INI--
1282 session.use_cookies=0
1283+session.use_strict_mode=0
1284 session.cache_limiter=
1285 session.use_trans_sid=1
1286 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1287diff -Nura php-4.4.4/ext/standard/array.c hardening-patch-4.4.4-0.4.15/ext/standard/array.c
1288--- php-4.4.4/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100
1289+++ hardening-patch-4.4.4-0.4.15/ext/standard/array.c 2006-09-05 20:30:51.000000000 +0200
1290@@ -1162,6 +1162,32 @@
1291 }
1292 }
1293 }
1294+
1295+ if (var_name[0] == 'H') {
1296+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1297+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1298+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1299+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1300+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1301+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1302+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1303+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1304+ return 0;
1305+ }
1306+ } else if (var_name[0] == '_') {
1307+ if ((strcmp(var_name, "_COOKIE")==0)||
1308+ (strcmp(var_name, "_ENV")==0)||
1309+ (strcmp(var_name, "_FILES")==0)||
1310+ (strcmp(var_name, "_GET")==0)||
1311+ (strcmp(var_name, "_POST")==0)||
1312+ (strcmp(var_name, "_REQUEST")==0)||
1313+ (strcmp(var_name, "_SESSION")==0)||
1314+ (strcmp(var_name, "_SERVER")==0)) {
1315+ return 0;
1316+ }
1317+ } else if (strcmp(var_name, "GLOBALS")==0) {
1318+ return 0;
1319+ }
1320
1321 return 1;
1322 }
1323diff -Nura php-4.4.4/ext/standard/basic_functions.c hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c
1324--- php-4.4.4/ext/standard/basic_functions.c 2006-06-29 00:09:09.000000000 +0200
1325+++ hardening-patch-4.4.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:48.000000000 +0200
1326@@ -107,12 +107,14 @@
1327 typedef struct _php_shutdown_function_entry {
1328 zval **arguments;
1329 int arg_count;
1330+ zend_bool created_by_eval;
1331 } php_shutdown_function_entry;
1332
1333 typedef struct _user_tick_function_entry {
1334 zval **arguments;
1335 int arg_count;
1336 int calling;
1337+ zend_bool created_by_eval;
1338 } user_tick_function_entry;
1339
1340 /* some prototypes for local functions */
1341@@ -295,6 +297,8 @@
1342 PHP_FE(get_html_translation_table, NULL)
1343 PHP_FE(sha1, NULL)
1344 PHP_FE(sha1_file, NULL)
1345+ PHP_FE(sha256, NULL)
1346+ PHP_FE(sha256_file, NULL)
1347 PHP_NAMED_FE(md5,php_if_md5, NULL)
1348 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1349 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1350@@ -676,7 +680,7 @@
1351 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1352
1353 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1354- PHP_FE(realpath, NULL)
1355+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1356 #endif
1357
1358 #ifdef HAVE_FNMATCH
1359@@ -2101,6 +2105,13 @@
1360 {
1361 zval retval;
1362 char *function_name = NULL;
1363+#if HARDENING_PATCH
1364+ zend_uint orig_code_type = EG(in_code_type);
1365+
1366+ if (shutdown_function_entry->created_by_eval) {
1367+ EG(in_code_type) = ZEND_EVAL_CODE;
1368+ }
1369+#endif
1370
1371 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1372 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1373@@ -2116,6 +2127,9 @@
1374 if (function_name) {
1375 efree(function_name);
1376 }
1377+#if HARDENING_PATCH
1378+ EG(in_code_type) = orig_code_type;
1379+#endif
1380 return 0;
1381 }
1382
1383@@ -2123,6 +2137,13 @@
1384 {
1385 zval retval;
1386 zval *function = tick_fe->arguments[0];
1387+#if HARDENING_PATCH
1388+ zend_uint orig_code_type = EG(in_code_type);
1389+
1390+ if (tick_fe->created_by_eval) {
1391+ EG(in_code_type) = ZEND_EVAL_CODE;
1392+ }
1393+#endif
1394
1395 /* Prevent reentrant calls to the same user ticks function */
1396 if (! tick_fe->calling) {
1397@@ -2154,6 +2175,9 @@
1398
1399 tick_fe->calling = 0;
1400 }
1401+#if HARDENING_PATCH
1402+ EG(in_code_type) = orig_code_type;
1403+#endif
1404 }
1405
1406 static void run_user_tick_functions(int tick_count)
1407@@ -2222,6 +2246,13 @@
1408 efree(shutdown_function_entry.arguments);
1409 RETURN_FALSE;
1410 }
1411+#if HARDENING_PATCH
1412+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1413+ shutdown_function_entry.created_by_eval = 1;
1414+ } else {
1415+ shutdown_function_entry.created_by_eval = 0;
1416+ }
1417+#endif
1418
1419 /* Prevent entering of anything but valid callback (syntax check only!) */
1420 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1421@@ -2503,6 +2534,15 @@
1422
1423 convert_to_string_ex(varname);
1424
1425+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */
1426+ if (PG(safe_mode)) {
1427+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) ||
1428+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) ||
1429+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) {
1430+ RETURN_FALSE;
1431+ }
1432+ }
1433+
1434 zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME);
1435 }
1436 /* }}} */
1437@@ -2759,6 +2799,13 @@
1438 }
1439
1440 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1441+#if HARDENING_PATCH
1442+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1443+ tick_fe.created_by_eval = 1;
1444+ } else {
1445+ tick_fe.created_by_eval = 0;
1446+ }
1447+#endif
1448
1449 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1450 efree(tick_fe.arguments);
1451@@ -3057,6 +3104,35 @@
1452 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1453 }
1454
1455+ if (new_key[0] == 'H') {
1456+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1457+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1458+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1459+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1460+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1461+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1462+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1463+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1464+ efree(new_key);
1465+ return 0;
1466+ }
1467+ } else if (new_key[0] == '_') {
1468+ if ((strcmp(new_key, "_COOKIE")==0)||
1469+ (strcmp(new_key, "_ENV")==0)||
1470+ (strcmp(new_key, "_FILES")==0)||
1471+ (strcmp(new_key, "_GET")==0)||
1472+ (strcmp(new_key, "_POST")==0)||
1473+ (strcmp(new_key, "_REQUEST")==0)||
1474+ (strcmp(new_key, "_SESSION")==0)||
1475+ (strcmp(new_key, "_SERVER")==0)) {
1476+ efree(new_key);
1477+ return 0;
1478+ }
1479+ } else if (strcmp(new_key, "GLOBALS")==0) {
1480+ efree(new_key);
1481+ return 0;
1482+ }
1483+
1484 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1485 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1486
1487diff -Nura php-4.4.4/ext/standard/config.m4 hardening-patch-4.4.4-0.4.15/ext/standard/config.m4
1488--- php-4.4.4/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1489+++ hardening-patch-4.4.4-0.4.15/ext/standard/config.m4 2006-09-05 20:30:51.000000000 +0200
1490@@ -203,7 +203,7 @@
1491 if test "$ac_cv_crypt_blowfish" = "yes"; then
1492 ac_result=1
1493 else
1494- ac_result=0
1495+ ac_result=1
1496 fi
1497 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1498 ])
1499@@ -419,6 +419,6 @@
1500 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1501 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1502 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1503- var_unserializer.c ftok.c aggregation.c sha1.c )
1504+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1505
1506 PHP_ADD_MAKEFILE_FRAGMENT
1507diff -Nura php-4.4.4/ext/standard/crypt_blowfish.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c
1508--- php-4.4.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1509+++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:30:51.000000000 +0200
1510@@ -0,0 +1,748 @@
1511+/*
1512+ * This code comes from John the Ripper password cracker, with reentrant
1513+ * and crypt(3) interfaces added, but optimizations specific to password
1514+ * cracking removed.
1515+ *
1516+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1517+ * placed in the public domain.
1518+ *
1519+ * There's absolutely no warranty.
1520+ *
1521+ * It is my intent that you should be able to use this on your system,
1522+ * as a part of a software package, or anywhere else to improve security,
1523+ * ensure compatibility, or for any other purpose. I would appreciate
1524+ * it if you give credit where it is due and keep your modifications in
1525+ * the public domain as well, but I don't require that in order to let
1526+ * you place this code and any modifications you make under a license
1527+ * of your choice.
1528+ *
1529+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1530+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1531+ * ideas. The password hashing algorithm was designed by David Mazieres
1532+ * <dm at lcs.mit.edu>.
1533+ *
1534+ * There's a paper on the algorithm that explains its design decisions:
1535+ *
1536+ * http://www.usenix.org/events/usenix99/provos.html
1537+ *
1538+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1539+ * Blowfish library (I can't be sure if I would think of something if I
1540+ * hadn't seen his code).
1541+ */
1542+
1543+#include <string.h>
1544+
1545+#include <errno.h>
1546+#ifndef __set_errno
1547+#define __set_errno(val) errno = (val)
1548+#endif
1549+
1550+#undef __CONST
1551+#ifdef __GNUC__
1552+#define __CONST __const
1553+#else
1554+#define __CONST
1555+#endif
1556+
1557+#ifdef __i386__
1558+#define BF_ASM 0
1559+#define BF_SCALE 1
1560+#elif defined(__alpha__) || defined(__hppa__)
1561+#define BF_ASM 0
1562+#define BF_SCALE 1
1563+#else
1564+#define BF_ASM 0
1565+#define BF_SCALE 0
1566+#endif
1567+
1568+typedef unsigned int BF_word;
1569+
1570+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1571+#define BF_N 16
1572+
1573+typedef BF_word BF_key[BF_N + 2];
1574+
1575+typedef struct {
1576+ BF_word S[4][0x100];
1577+ BF_key P;
1578+} BF_ctx;
1579+
1580+/*
1581+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1582+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1583+ */
1584+static BF_word BF_magic_w[6] = {
1585+ 0x4F727068, 0x65616E42, 0x65686F6C,
1586+ 0x64657253, 0x63727944, 0x6F756274
1587+};
1588+
1589+/*
1590+ * P-box and S-box tables initialized with digits of Pi.
1591+ */
1592+static BF_ctx BF_init_state = {
1593+ {
1594+ {
1595+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1596+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1597+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1598+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1599+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1600+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1601+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1602+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1603+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1604+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1605+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1606+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1607+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1608+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1609+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1610+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1611+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1612+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1613+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1614+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1615+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1616+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1617+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1618+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1619+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1620+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1621+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1622+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1623+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1624+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1625+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1626+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1627+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1628+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1629+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1630+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1631+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1632+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1633+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1634+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1635+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1636+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1637+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1638+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1639+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1640+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1641+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1642+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1643+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1644+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1645+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1646+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1647+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1648+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1649+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1650+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1651+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1652+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1653+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1654+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1655+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1656+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1657+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1658+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1659+ }, {
1660+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1661+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1662+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1663+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1664+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1665+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1666+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1667+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1668+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1669+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1670+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1671+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1672+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1673+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1674+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1675+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1676+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1677+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1678+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1679+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1680+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1681+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1682+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1683+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1684+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1685+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1686+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1687+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1688+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1689+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1690+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1691+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1692+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1693+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1694+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1695+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1696+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1697+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1698+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1699+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1700+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1701+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1702+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1703+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1704+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1705+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1706+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1707+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1708+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1709+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1710+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1711+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1712+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1713+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1714+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1715+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1716+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1717+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1718+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1719+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1720+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1721+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1722+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1723+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1724+ }, {
1725+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1726+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1727+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1728+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1729+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1730+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1731+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1732+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1733+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1734+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1735+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1736+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1737+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1738+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1739+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1740+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1741+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1742+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1743+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1744+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1745+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1746+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1747+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1748+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1749+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1750+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1751+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1752+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1753+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1754+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1755+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1756+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1757+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1758+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1759+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1760+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1761+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1762+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1763+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1764+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1765+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1766+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1767+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1768+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1769+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1770+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1771+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1772+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1773+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1774+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1775+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1776+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1777+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1778+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1779+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1780+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1781+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1782+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1783+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1784+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1785+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1786+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1787+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1788+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1789+ }, {
1790+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1791+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1792+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1793+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1794+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1795+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1796+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1797+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1798+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1799+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1800+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1801+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1802+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1803+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1804+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1805+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1806+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1807+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1808+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1809+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1810+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1811+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1812+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1813+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1814+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1815+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1816+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1817+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1818+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1819+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1820+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1821+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1822+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1823+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1824+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1825+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1826+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1827+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1828+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1829+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1830+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1831+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1832+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1833+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1834+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1835+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1836+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1837+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1838+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1839+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1840+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1841+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1842+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1843+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1844+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1845+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1846+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1847+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1848+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1849+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1850+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1851+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1852+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1853+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1854+ }
1855+ }, {
1856+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1857+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1858+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1859+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1860+ 0x9216d5d9, 0x8979fb1b
1861+ }
1862+};
1863+
1864+static unsigned char BF_itoa64[64 + 1] =
1865+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1866+
1867+static unsigned char BF_atoi64[0x60] = {
1868+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1869+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1870+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1871+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1872+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1873+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1874+};
1875+
1876+/*
1877+ * This may be optimized out if built with function inlining and no BF_ASM.
1878+ */
1879+static void clean(void *data, int size)
1880+{
1881+#if BF_ASM
1882+ extern void _BF_clean(void *data);
1883+#endif
1884+ memset(data, 0, size);
1885+#if BF_ASM
1886+ _BF_clean(data);
1887+#endif
1888+}
1889+
1890+#define BF_safe_atoi64(dst, src) \
1891+{ \
1892+ tmp = (unsigned char)(src); \
1893+ if (tmp == '$') break; \
1894+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1895+ tmp = BF_atoi64[tmp]; \
1896+ if (tmp > 63) return -1; \
1897+ (dst) = tmp; \
1898+}
1899+
1900+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1901+{
1902+ unsigned char *dptr = (unsigned char *)dst;
1903+ unsigned char *end = dptr + size;
1904+ unsigned char *sptr = (unsigned char *)src;
1905+ unsigned int tmp, c1, c2, c3, c4;
1906+
1907+ do {
1908+ BF_safe_atoi64(c1, *sptr++);
1909+ BF_safe_atoi64(c2, *sptr++);
1910+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1911+ if (dptr >= end) break;
1912+
1913+ BF_safe_atoi64(c3, *sptr++);
1914+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1915+ if (dptr >= end) break;
1916+
1917+ BF_safe_atoi64(c4, *sptr++);
1918+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1919+ } while (dptr < end);
1920+
1921+ while (dptr < end)
1922+ *dptr++ = 0;
1923+
1924+ return 0;
1925+}
1926+
1927+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1928+{
1929+ unsigned char *sptr = (unsigned char *)src;
1930+ unsigned char *end = sptr + size;
1931+ unsigned char *dptr = (unsigned char *)dst;
1932+ unsigned int c1, c2;
1933+
1934+ do {
1935+ c1 = *sptr++;
1936+ *dptr++ = BF_itoa64[c1 >> 2];
1937+ c1 = (c1 & 0x03) << 4;
1938+ if (sptr >= end) {
1939+ *dptr++ = BF_itoa64[c1];
1940+ break;
1941+ }
1942+
1943+ c2 = *sptr++;
1944+ c1 |= c2 >> 4;
1945+ *dptr++ = BF_itoa64[c1];
1946+ c1 = (c2 & 0x0f) << 2;
1947+ if (sptr >= end) {
1948+ *dptr++ = BF_itoa64[c1];
1949+ break;
1950+ }
1951+
1952+ c2 = *sptr++;
1953+ c1 |= c2 >> 6;
1954+ *dptr++ = BF_itoa64[c1];
1955+ *dptr++ = BF_itoa64[c2 & 0x3f];
1956+ } while (sptr < end);
1957+}
1958+
1959+static void BF_swap(BF_word *x, int count)
1960+{
1961+ static int endianness_check = 1;
1962+ char *is_little_endian = (char *)&endianness_check;
1963+ BF_word tmp;
1964+
1965+ if (*is_little_endian)
1966+ do {
1967+ tmp = *x;
1968+ tmp = (tmp << 16) | (tmp >> 16);
1969+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1970+ } while (--count);
1971+}
1972+
1973+#if BF_SCALE
1974+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1975+#define BF_ROUND(L, R, N) \
1976+ tmp1 = L & 0xFF; \
1977+ tmp2 = L >> 8; \
1978+ tmp2 &= 0xFF; \
1979+ tmp3 = L >> 16; \
1980+ tmp3 &= 0xFF; \
1981+ tmp4 = L >> 24; \
1982+ tmp1 = data.ctx.S[3][tmp1]; \
1983+ tmp2 = data.ctx.S[2][tmp2]; \
1984+ tmp3 = data.ctx.S[1][tmp3]; \
1985+ tmp3 += data.ctx.S[0][tmp4]; \
1986+ tmp3 ^= tmp2; \
1987+ R ^= data.ctx.P[N + 1]; \
1988+ tmp3 += tmp1; \
1989+ R ^= tmp3;
1990+#else
1991+/* Architectures with no complicated addressing modes supported */
1992+#define BF_INDEX(S, i) \
1993+ (*((BF_word *)(((unsigned char *)S) + (i))))
1994+#define BF_ROUND(L, R, N) \
1995+ tmp1 = L & 0xFF; \
1996+ tmp1 <<= 2; \
1997+ tmp2 = L >> 6; \
1998+ tmp2 &= 0x3FC; \
1999+ tmp3 = L >> 14; \
2000+ tmp3 &= 0x3FC; \
2001+ tmp4 = L >> 22; \
2002+ tmp4 &= 0x3FC; \
2003+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
2004+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
2005+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
2006+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
2007+ tmp3 ^= tmp2; \
2008+ R ^= data.ctx.P[N + 1]; \
2009+ tmp3 += tmp1; \
2010+ R ^= tmp3;
2011+#endif
2012+
2013+/*
2014+ * Encrypt one block, BF_N is hardcoded here.
2015+ */
2016+#define BF_ENCRYPT \
2017+ L ^= data.ctx.P[0]; \
2018+ BF_ROUND(L, R, 0); \
2019+ BF_ROUND(R, L, 1); \
2020+ BF_ROUND(L, R, 2); \
2021+ BF_ROUND(R, L, 3); \
2022+ BF_ROUND(L, R, 4); \
2023+ BF_ROUND(R, L, 5); \
2024+ BF_ROUND(L, R, 6); \
2025+ BF_ROUND(R, L, 7); \
2026+ BF_ROUND(L, R, 8); \
2027+ BF_ROUND(R, L, 9); \
2028+ BF_ROUND(L, R, 10); \
2029+ BF_ROUND(R, L, 11); \
2030+ BF_ROUND(L, R, 12); \
2031+ BF_ROUND(R, L, 13); \
2032+ BF_ROUND(L, R, 14); \
2033+ BF_ROUND(R, L, 15); \
2034+ tmp4 = R; \
2035+ R = L; \
2036+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2037+
2038+#if BF_ASM
2039+#define BF_body() \
2040+ _BF_body_r(&data.ctx);
2041+#else
2042+#define BF_body() \
2043+ L = R = 0; \
2044+ ptr = data.ctx.P; \
2045+ do { \
2046+ ptr += 2; \
2047+ BF_ENCRYPT; \
2048+ *(ptr - 2) = L; \
2049+ *(ptr - 1) = R; \
2050+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2051+\
2052+ ptr = data.ctx.S[0]; \
2053+ do { \
2054+ ptr += 2; \
2055+ BF_ENCRYPT; \
2056+ *(ptr - 2) = L; \
2057+ *(ptr - 1) = R; \
2058+ } while (ptr < &data.ctx.S[3][0xFF]);
2059+#endif
2060+
2061+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2062+{
2063+ __CONST char *ptr = key;
2064+ int i, j;
2065+ BF_word tmp;
2066+
2067+ for (i = 0; i < BF_N + 2; i++) {
2068+ tmp = 0;
2069+ for (j = 0; j < 4; j++) {
2070+ tmp <<= 8;
2071+ tmp |= *ptr;
2072+
2073+ if (!*ptr) ptr = key; else ptr++;
2074+ }
2075+
2076+ expanded[i] = tmp;
2077+ initial[i] = BF_init_state.P[i] ^ tmp;
2078+ }
2079+}
2080+
2081+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2082+ char *output, int size)
2083+{
2084+#if BF_ASM
2085+ extern void _BF_body_r(BF_ctx *ctx);
2086+#endif
2087+ struct {
2088+ BF_ctx ctx;
2089+ BF_key expanded_key;
2090+ union {
2091+ BF_word salt[4];
2092+ BF_word output[6];
2093+ } binary;
2094+ } data;
2095+ BF_word L, R;
2096+ BF_word tmp1, tmp2, tmp3, tmp4;
2097+ BF_word *ptr;
2098+ BF_word count;
2099+ int i;
2100+
2101+ if (size < 7 + 22 + 31 + 1) {
2102+ __set_errno(ERANGE);
2103+ return NULL;
2104+ }
2105+
2106+ if (setting[0] != '$' ||
2107+ setting[1] != '2' ||
2108+ setting[2] != 'a' ||
2109+ setting[3] != '$' ||
2110+ setting[4] < '0' || setting[4] > '3' ||
2111+ setting[5] < '0' || setting[5] > '9' ||
2112+ setting[6] != '$') {
2113+ __set_errno(EINVAL);
2114+ return NULL;
2115+ }
2116+
2117+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2118+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2119+ clean(data.binary.salt, sizeof(data.binary.salt));
2120+ __set_errno(EINVAL);
2121+ return NULL;
2122+ }
2123+
2124+ BF_swap(data.binary.salt, 4);
2125+
2126+ BF_set_key(key, data.expanded_key, data.ctx.P);
2127+
2128+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2129+
2130+ L = R = 0;
2131+ for (i = 0; i < BF_N + 2; i += 2) {
2132+ L ^= data.binary.salt[i & 2];
2133+ R ^= data.binary.salt[(i & 2) + 1];
2134+ BF_ENCRYPT;
2135+ data.ctx.P[i] = L;
2136+ data.ctx.P[i + 1] = R;
2137+ }
2138+
2139+ ptr = data.ctx.S[0];
2140+ do {
2141+ ptr += 4;
2142+ L ^= data.binary.salt[(BF_N + 2) & 3];
2143+ R ^= data.binary.salt[(BF_N + 3) & 3];
2144+ BF_ENCRYPT;
2145+ *(ptr - 4) = L;
2146+ *(ptr - 3) = R;
2147+
2148+ L ^= data.binary.salt[(BF_N + 4) & 3];
2149+ R ^= data.binary.salt[(BF_N + 5) & 3];
2150+ BF_ENCRYPT;
2151+ *(ptr - 2) = L;
2152+ *(ptr - 1) = R;
2153+ } while (ptr < &data.ctx.S[3][0xFF]);
2154+
2155+ do {
2156+ data.ctx.P[0] ^= data.expanded_key[0];
2157+ data.ctx.P[1] ^= data.expanded_key[1];
2158+ data.ctx.P[2] ^= data.expanded_key[2];
2159+ data.ctx.P[3] ^= data.expanded_key[3];
2160+ data.ctx.P[4] ^= data.expanded_key[4];
2161+ data.ctx.P[5] ^= data.expanded_key[5];
2162+ data.ctx.P[6] ^= data.expanded_key[6];
2163+ data.ctx.P[7] ^= data.expanded_key[7];
2164+ data.ctx.P[8] ^= data.expanded_key[8];
2165+ data.ctx.P[9] ^= data.expanded_key[9];
2166+ data.ctx.P[10] ^= data.expanded_key[10];
2167+ data.ctx.P[11] ^= data.expanded_key[11];
2168+ data.ctx.P[12] ^= data.expanded_key[12];
2169+ data.ctx.P[13] ^= data.expanded_key[13];
2170+ data.ctx.P[14] ^= data.expanded_key[14];
2171+ data.ctx.P[15] ^= data.expanded_key[15];
2172+ data.ctx.P[16] ^= data.expanded_key[16];
2173+ data.ctx.P[17] ^= data.expanded_key[17];
2174+
2175+ BF_body();
2176+
2177+ tmp1 = data.binary.salt[0];
2178+ tmp2 = data.binary.salt[1];
2179+ tmp3 = data.binary.salt[2];
2180+ tmp4 = data.binary.salt[3];
2181+ data.ctx.P[0] ^= tmp1;
2182+ data.ctx.P[1] ^= tmp2;
2183+ data.ctx.P[2] ^= tmp3;
2184+ data.ctx.P[3] ^= tmp4;
2185+ data.ctx.P[4] ^= tmp1;
2186+ data.ctx.P[5] ^= tmp2;
2187+ data.ctx.P[6] ^= tmp3;
2188+ data.ctx.P[7] ^= tmp4;
2189+ data.ctx.P[8] ^= tmp1;
2190+ data.ctx.P[9] ^= tmp2;
2191+ data.ctx.P[10] ^= tmp3;
2192+ data.ctx.P[11] ^= tmp4;
2193+ data.ctx.P[12] ^= tmp1;
2194+ data.ctx.P[13] ^= tmp2;
2195+ data.ctx.P[14] ^= tmp3;
2196+ data.ctx.P[15] ^= tmp4;
2197+ data.ctx.P[16] ^= tmp1;
2198+ data.ctx.P[17] ^= tmp2;
2199+
2200+ BF_body();
2201+ } while (--count);
2202+
2203+ for (i = 0; i < 6; i += 2) {
2204+ L = BF_magic_w[i];
2205+ R = BF_magic_w[i + 1];
2206+
2207+ count = 64;
2208+ do {
2209+ BF_ENCRYPT;
2210+ } while (--count);
2211+
2212+ data.binary.output[i] = L;
2213+ data.binary.output[i + 1] = R;
2214+ }
2215+
2216+ memcpy(output, setting, 7 + 22 - 1);
2217+ output[7 + 22 - 1] = BF_itoa64[(int)
2218+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2219+
2220+/* This has to be bug-compatible with the original implementation, so
2221+ * only encode 23 of the 24 bytes. :-) */
2222+ BF_swap(data.binary.output, 6);
2223+ BF_encode(&output[7 + 22], data.binary.output, 23);
2224+ output[7 + 22 + 31] = '\0';
2225+
2226+/* Overwrite the most obvious sensitive data we have on the stack. Note
2227+ * that this does not guarantee there's no sensitive data left on the
2228+ * stack and/or in registers; I'm not aware of portable code that does. */
2229+ clean(&data, sizeof(data));
2230+
2231+ return output;
2232+}
2233+
2234+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2235+ __CONST char *input, int size, char *output, int output_size)
2236+{
2237+ if (size < 16 || output_size < 7 + 22 + 1 ||
2238+ (count && (count < 4 || count > 31))) {
2239+ if (output_size > 0) output[0] = '\0';
2240+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2241+ return NULL;
2242+ }
2243+
2244+ if (!count) count = 5;
2245+
2246+ output[0] = '$';
2247+ output[1] = '2';
2248+ output[2] = 'a';
2249+ output[3] = '$';
2250+ output[4] = '0' + count / 10;
2251+ output[5] = '0' + count % 10;
2252+ output[6] = '$';
2253+
2254+ BF_encode(&output[7], (BF_word *)input, 16);
2255+ output[7 + 22] = '\0';
2256+
2257+ return output;
2258+}
2259diff -Nura php-4.4.4/ext/standard/crypt.c hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c
2260--- php-4.4.4/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100
2261+++ hardening-patch-4.4.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:30:51.000000000 +0200
2262@@ -100,6 +100,8 @@
2263 return SUCCESS;
2264 }
2265
2266+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2267+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2268
2269 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2270
2271@@ -135,7 +137,14 @@
2272
2273 /* The automatic salt generation only covers standard DES and md5-crypt */
2274 if(!*salt) {
2275-#if PHP_MD5_CRYPT
2276+#if PHP_BLOWFISH_CRYPT
2277+ char randat[16];
2278+ int i;
2279+
2280+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2281+
2282+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2283+#elif PHP_MD5_CRYPT
2284 strcpy(salt, "$1$");
2285 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2286 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2287@@ -145,8 +154,24 @@
2288 salt[2] = '\0';
2289 #endif
2290 }
2291-
2292- RETVAL_STRING(crypt(str, salt), 1);
2293+
2294+ if (salt[0] == '$' &&
2295+ salt[1] == '2' &&
2296+ salt[2] == 'a' &&
2297+ salt[3] == '$' &&
2298+ salt[4] >= '0' && salt[4] <= '3' &&
2299+ salt[5] >= '0' && salt[5] <= '9' &&
2300+ salt[6] == '$') {
2301+
2302+ char output[PHP_MAX_SALT_LEN+1];
2303+
2304+ output[0] = 0;
2305+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2306+ RETVAL_STRING(output, 1);
2307+
2308+ } else {
2309+ RETVAL_STRING(crypt(str, salt), 1);
2310+ }
2311 }
2312 /* }}} */
2313 #endif
2314diff -Nura php-4.4.4/ext/standard/dl.c hardening-patch-4.4.4-0.4.15/ext/standard/dl.c
2315--- php-4.4.4/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100
2316+++ hardening-patch-4.4.4-0.4.15/ext/standard/dl.c 2006-09-05 20:30:51.000000000 +0200
2317@@ -160,8 +160,35 @@
2318 RETURN_FALSE;
2319 }
2320 module_entry = get_module();
2321+
2322+ /* check if Hardening-Patch is installed */
2323+ if (module_entry->zend_api < 1000000000) {
2324+ php_error_docref(NULL TSRMLS_CC, error_type,
2325+ "%s: Unable to initialize module\n"
2326+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2327+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2328+ "These options need to match\n",
2329+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2330+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2331+ DL_UNLOAD(handle);
2332+ RETURN_FALSE;
2333+ }
2334+
2335+ /* check if correct Hardening-Patch is installed */
2336+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2337+ php_error_docref(NULL TSRMLS_CC, error_type,
2338+ "%s: Unable to initialize module\n"
2339+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2340+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2341+ "These options need to match\n",
2342+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2343+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2344+ DL_UNLOAD(handle);
2345+ RETURN_FALSE;
2346+ }
2347+
2348 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2349- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2350+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2351 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2352 struct pre_4_1_0_module_entry {
2353 char *name;
2354@@ -195,7 +222,7 @@
2355 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2356 } else {
2357 name = module_entry->name;
2358- zend_api = module_entry->zend_api;
2359+ zend_api = module_entry->real_zend_api;
2360 zend_debug = module_entry->zend_debug;
2361 zts = module_entry->zts;
2362 }
2363diff -Nura php-4.4.4/ext/standard/file.c hardening-patch-4.4.4-0.4.15/ext/standard/file.c
2364--- php-4.4.4/ext/standard/file.c 2006-04-14 19:46:59.000000000 +0200
2365+++ hardening-patch-4.4.4-0.4.15/ext/standard/file.c 2006-09-05 20:30:51.000000000 +0200
2366@@ -2527,7 +2527,7 @@
2367 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2368 /* {{{ proto string realpath(string path)
2369 Return the resolved path */
2370-PHP_FUNCTION(realpath)
2371+PHP_FUNCTION(real_path)
2372 {
2373 zval **path;
2374 char resolved_path_buff[MAXPATHLEN];
2375diff -Nura php-4.4.4/ext/standard/file.h hardening-patch-4.4.4-0.4.15/ext/standard/file.h
2376--- php-4.4.4/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100
2377+++ hardening-patch-4.4.4-0.4.15/ext/standard/file.h 2006-09-05 20:30:51.000000000 +0200
2378@@ -64,7 +64,7 @@
2379 PHP_FUNCTION(fd_set);
2380 PHP_FUNCTION(fd_isset);
2381 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2382-PHP_FUNCTION(realpath);
2383+PHP_FUNCTION(real_path);
2384 #endif
2385 #ifdef HAVE_FNMATCH
2386 PHP_FUNCTION(fnmatch);
2387diff -Nura php-4.4.4/ext/standard/head.c hardening-patch-4.4.4-0.4.15/ext/standard/head.c
2388--- php-4.4.4/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100
2389+++ hardening-patch-4.4.4-0.4.15/ext/standard/head.c 2006-09-05 20:30:51.000000000 +0200
2390@@ -44,7 +44,7 @@
2391 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2392 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2393 return;
2394-
2395+
2396 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2397 }
2398 /* }}} */
2399diff -Nura php-4.4.4/ext/standard/mail.c hardening-patch-4.4.4-0.4.15/ext/standard/mail.c
2400--- php-4.4.4/ext/standard/mail.c 2006-01-01 14:46:57.000000000 +0100
2401+++ hardening-patch-4.4.4-0.4.15/ext/standard/mail.c 2006-09-05 20:30:51.000000000 +0200
2402@@ -78,6 +78,25 @@
2403 }
2404 /* }}} */
2405
2406+/* {{{ hphp_strcasestr */
2407+char *hphp_strcasestr(char *haystack, char *needle)
2408+{
2409+ unsigned char *t, *h, *n;
2410+
2411+ h = (unsigned char *) haystack;
2412+conts:
2413+ while (*h) {
2414+ n = (unsigned char *) needle;
2415+ for (t=h++; *n && *h; t++, n++) {
2416+ if (toupper(*t) != toupper(*n)) goto conts;
2417+ }
2418+ return ((char*)h-1);
2419+ }
2420+
2421+ return (NULL);
2422+}
2423+/* }}} */
2424+
2425 /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
2426 Send an email message */
2427 PHP_FUNCTION(mail)
2428@@ -103,6 +122,44 @@
2429 return;
2430 }
2431
2432+ if (HG(hphp_mailprotect) > 0) {
2433+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) {
2434+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped");
2435+ RETURN_FALSE;
2436+ }
2437+
2438+ /* check for spam attempts with buggy webforms */
2439+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) {
2440+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped");
2441+ RETURN_FALSE;
2442+ }
2443+
2444+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) {
2445+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped");
2446+ RETURN_FALSE;
2447+ }
2448+
2449+ if (HG(hphp_mailprotect) > 1) {
2450+ /* search for to, cc or bcc headers */
2451+ if (headers_len > 0 && headers != NULL) {
2452+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) {
2453+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter.");
2454+ RETURN_FALSE;
2455+ }
2456+
2457+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) {
2458+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter.");
2459+ RETURN_FALSE;
2460+ }
2461+
2462+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) {
2463+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter.");
2464+ RETURN_FALSE;
2465+ }
2466+ }
2467+ }
2468+ }
2469+
2470 if (to_len > 0) {
2471 to_r = estrndup(to, to_len);
2472 for (; to_len; to_len--) {
2473diff -Nura php-4.4.4/ext/standard/php_standard.h hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h
2474--- php-4.4.4/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100
2475+++ hardening-patch-4.4.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:30:51.000000000 +0200
2476@@ -28,6 +28,7 @@
2477 #include "php_mail.h"
2478 #include "md5.h"
2479 #include "sha1.h"
2480+#include "sha256.h"
2481 #include "html.h"
2482 #include "exec.h"
2483 #include "file.h"
2484diff -Nura php-4.4.4/ext/standard/sha256.c hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c
2485--- php-4.4.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2486+++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:30:51.000000000 +0200
2487@@ -0,0 +1,398 @@
2488+/*
2489+ +----------------------------------------------------------------------+
2490+ | PHP Version 5 |
2491+ +----------------------------------------------------------------------+
2492+ | Copyright (c) 1997-2004 The PHP Group |
2493+ +----------------------------------------------------------------------+
2494+ | This source file is subject to version 3.0 of the PHP license, |
2495+ | that is bundled with this package in the file LICENSE, and is |
2496+ | available through the world-wide-web at the following url: |
2497+ | http://www.php.net/license/3_0.txt. |
2498+ | If you did not receive a copy of the PHP license and are unable to |
2499+ | obtain it through the world-wide-web, please send a note to |
2500+ | license@php.net so we can mail you a copy immediately. |
2501+ +----------------------------------------------------------------------+
2502+ | Author: Stefan Esser <sesser@php.net> |
2503+ +----------------------------------------------------------------------+
2504+*/
2505+
2506+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2507+
2508+#include <stdio.h>
2509+#include "php.h"
2510+
2511+/* This code is heavily based on the PHP md5/sha1 implementations */
2512+
2513+#include "sha256.h"
2514+
2515+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2516+{
2517+ int i;
2518+
2519+ for (i = 0; i < 32; i++) {
2520+ sprintf(sha256str, "%02x", digest[i]);
2521+ sha256str += 2;
2522+ }
2523+
2524+ *sha256str = '\0';
2525+}
2526+
2527+/* {{{ proto string sha256(string str [, bool raw_output])
2528+ Calculate the sha256 hash of a string */
2529+PHP_FUNCTION(sha256)
2530+{
2531+ char *arg;
2532+ int arg_len;
2533+ zend_bool raw_output = 0;
2534+ char sha256str[65];
2535+ PHP_SHA256_CTX context;
2536+ unsigned char digest[32];
2537+
2538+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2539+ return;
2540+ }
2541+
2542+ sha256str[0] = '\0';
2543+ PHP_SHA256Init(&context);
2544+ PHP_SHA256Update(&context, arg, arg_len);
2545+ PHP_SHA256Final(digest, &context);
2546+ if (raw_output) {
2547+ RETURN_STRINGL(digest, 32, 1);
2548+ } else {
2549+ make_sha256_digest(sha256str, digest);
2550+ RETVAL_STRING(sha256str, 1);
2551+ }
2552+
2553+}
2554+
2555+/* }}} */
2556+
2557+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2558+ Calculate the sha256 hash of given filename */
2559+PHP_FUNCTION(sha256_file)
2560+{
2561+ char *arg;
2562+ int arg_len;
2563+ zend_bool raw_output = 0;
2564+ char sha256str[65];
2565+ unsigned char buf[1024];
2566+ unsigned char digest[32];
2567+ PHP_SHA256_CTX context;
2568+ int n;
2569+ FILE *fp;
2570+
2571+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2572+ return;
2573+ }
2574+
2575+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2576+ RETURN_FALSE;
2577+ }
2578+
2579+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2580+ RETURN_FALSE;
2581+ }
2582+
2583+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2584+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2585+ RETURN_FALSE;
2586+ }
2587+
2588+ PHP_SHA256Init(&context);
2589+
2590+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2591+ PHP_SHA256Update(&context, buf, n);
2592+ }
2593+
2594+ PHP_SHA256Final(digest, &context);
2595+
2596+ if (ferror(fp)) {
2597+ fclose(fp);
2598+ RETURN_FALSE;
2599+ }
2600+
2601+ fclose(fp);
2602+
2603+ if (raw_output) {
2604+ RETURN_STRINGL(digest, 32, 1);
2605+ } else {
2606+ make_sha256_digest(sha256str, digest);
2607+ RETVAL_STRING(sha256str, 1);
2608+ }
2609+}
2610+/* }}} */
2611+
2612+
2613+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2614+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2615+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2616+
2617+static unsigned char PADDING[64] =
2618+{
2619+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2620+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2621+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2622+};
2623+
2624+/* F, G, H and I are basic SHA256 functions.
2625+ */
2626+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2627+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2628+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2629+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2630+
2631+/* ROTATE_RIGHT rotates x right n bits.
2632+ */
2633+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2634+
2635+/* W[i]
2636+ */
2637+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2638+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2639+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2640+
2641+/* ROUND function of sha256
2642+ */
2643+
2644+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2645+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2646+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2647+ (d) += t1; \
2648+ }
2649+
2650+
2651+/* {{{ PHP_SHA256Init
2652+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2653+ */
2654+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2655+{
2656+ context->count[0] = context->count[1] = 0;
2657+ /* Load magic initialization constants.
2658+ */
2659+ context->state[0] = 0x6a09e667;
2660+ context->state[1] = 0xbb67ae85;
2661+ context->state[2] = 0x3c6ef372;
2662+ context->state[3] = 0xa54ff53a;
2663+ context->state[4] = 0x510e527f;
2664+ context->state[5] = 0x9b05688c;
2665+ context->state[6] = 0x1f83d9ab;
2666+ context->state[7] = 0x5be0cd19;
2667+}
2668+/* }}} */
2669+
2670+/* {{{ PHP_SHA256Update
2671+ SHA256 block update operation. Continues an SHA256 message-digest
2672+ operation, processing another message block, and updating the
2673+ context.
2674+ */
2675+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2676+ unsigned int inputLen)
2677+{
2678+ unsigned int i, index, partLen;
2679+
2680+ /* Compute number of bytes mod 64 */
2681+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2682+
2683+ /* Update number of bits */
2684+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2685+ < ((php_uint32) inputLen << 3))
2686+ context->count[1]++;
2687+ context->count[1] += ((php_uint32) inputLen >> 29);
2688+
2689+ partLen = 64 - index;
2690+
2691+ /* Transform as many times as possible.
2692+ */
2693+ if (inputLen >= partLen) {
2694+ memcpy
2695+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2696+ SHA256Transform(context->state, context->buffer);
2697+
2698+ for (i = partLen; i + 63 < inputLen; i += 64)
2699+ SHA256Transform(context->state, &input[i]);
2700+
2701+ index = 0;
2702+ } else
2703+ i = 0;
2704+
2705+ /* Buffer remaining input */
2706+ memcpy
2707+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2708+ inputLen - i);
2709+}
2710+/* }}} */
2711+
2712+/* {{{ PHP_SHA256Final
2713+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2714+ the message digest and zeroizing the context.
2715+ */
2716+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2717+{
2718+ unsigned char bits[8];
2719+ unsigned int index, padLen;
2720+
2721+ /* Save number of bits */
2722+ bits[7] = context->count[0] & 0xFF;
2723+ bits[6] = (context->count[0] >> 8) & 0xFF;
2724+ bits[5] = (context->count[0] >> 16) & 0xFF;
2725+ bits[4] = (context->count[0] >> 24) & 0xFF;
2726+ bits[3] = context->count[1] & 0xFF;
2727+ bits[2] = (context->count[1] >> 8) & 0xFF;
2728+ bits[1] = (context->count[1] >> 16) & 0xFF;
2729+ bits[0] = (context->count[1] >> 24) & 0xFF;
2730+
2731+ /* Pad out to 56 mod 64.
2732+ */
2733+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2734+ padLen = (index < 56) ? (56 - index) : (120 - index);
2735+ PHP_SHA256Update(context, PADDING, padLen);
2736+
2737+ /* Append length (before padding) */
2738+ PHP_SHA256Update(context, bits, 8);
2739+
2740+ /* Store state in digest */
2741+ SHA256Encode(digest, context->state, 32);
2742+
2743+ /* Zeroize sensitive information.
2744+ */
2745+ memset((unsigned char*) context, 0, sizeof(*context));
2746+}
2747+/* }}} */
2748+
2749+/* {{{ SHA256Transform
2750+ * SHA256 basic transformation. Transforms state based on block.
2751+ */
2752+static void SHA256Transform(state, block)
2753+php_uint32 state[8];
2754+const unsigned char block[64];
2755+{
2756+ php_uint32 a = state[0], b = state[1], c = state[2];
2757+ php_uint32 d = state[3], e = state[4], f = state[5];
2758+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2759+
2760+ SHA256Decode(x, block, 64);
2761+
2762+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2763+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2764+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2765+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2766+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2767+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2768+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2769+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2770+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2771+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2772+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2773+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2774+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2775+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2776+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2777+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2778+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2779+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2780+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2781+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2782+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2783+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2784+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2785+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2786+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2787+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2788+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2789+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2790+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2791+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2792+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2793+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2794+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2795+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2796+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2797+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2798+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2799+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2800+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2801+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2802+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2803+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2804+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2805+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2806+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2807+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2808+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2809+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2810+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2811+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2812+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2813+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2814+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2815+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2816+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2817+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2818+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2819+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2820+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2821+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2822+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2823+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2824+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2825+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2826+
2827+ state[0] += a;
2828+ state[1] += b;
2829+ state[2] += c;
2830+ state[3] += d;
2831+ state[4] += e;
2832+ state[5] += f;
2833+ state[6] += g;
2834+ state[7] += h;
2835+
2836+ /* Zeroize sensitive information. */
2837+ memset((unsigned char*) x, 0, sizeof(x));
2838+}
2839+/* }}} */
2840+
2841+/* {{{ SHA256Encode
2842+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2843+ a multiple of 4.
2844+ */
2845+static void SHA256Encode(output, input, len)
2846+unsigned char *output;
2847+php_uint32 *input;
2848+unsigned int len;
2849+{
2850+ unsigned int i, j;
2851+
2852+ for (i = 0, j = 0; j < len; i++, j += 4) {
2853+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2854+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2855+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2856+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2857+ }
2858+}
2859+/* }}} */
2860+
2861+/* {{{ SHA256Decode
2862+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2863+ a multiple of 4.
2864+ */
2865+static void SHA256Decode(output, input, len)
2866+php_uint32 *output;
2867+const unsigned char *input;
2868+unsigned int len;
2869+{
2870+ unsigned int i, j;
2871+
2872+ for (i = 0, j = 0; j < len; i++, j += 4)
2873+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2874+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2875+}
2876+/* }}} */
2877+
2878+/*
2879+ * Local variables:
2880+ * tab-width: 4
2881+ * c-basic-offset: 4
2882+ * End:
2883+ * vim600: sw=4 ts=4 fdm=marker
2884+ * vim<600: sw=4 ts=4
2885+ */
2886diff -Nura php-4.4.4/ext/standard/sha256.h hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h
2887--- php-4.4.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2888+++ hardening-patch-4.4.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:30:51.000000000 +0200
2889@@ -0,0 +1,40 @@
2890+/*
2891+ +----------------------------------------------------------------------+
2892+ | PHP Version 5 |
2893+ +----------------------------------------------------------------------+
2894+ | Copyright (c) 1997-2004 The PHP Group |
2895+ +----------------------------------------------------------------------+
2896+ | This source file is subject to version 3.0 of the PHP license, |
2897+ | that is bundled with this package in the file LICENSE, and is |
2898+ | available through the world-wide-web at the following url: |
2899+ | http://www.php.net/license/3_0.txt. |
2900+ | If you did not receive a copy of the PHP license and are unable to |
2901+ | obtain it through the world-wide-web, please send a note to |
2902+ | license@php.net so we can mail you a copy immediately. |
2903+ +----------------------------------------------------------------------+
2904+ | Author: Stefan Esser <sesser@php.net> |
2905+ +----------------------------------------------------------------------+
2906+*/
2907+
2908+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2909+
2910+#ifndef SHA256_H
2911+#define SHA256_H
2912+
2913+#include "ext/standard/basic_functions.h"
2914+
2915+/* SHA1 context. */
2916+typedef struct {
2917+ php_uint32 state[8]; /* state (ABCD) */
2918+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2919+ unsigned char buffer[64]; /* input buffer */
2920+} PHP_SHA256_CTX;
2921+
2922+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2923+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2924+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2925+
2926+PHP_FUNCTION(sha256);
2927+PHP_FUNCTION(sha256_file);
2928+
2929+#endif
2930diff -Nura php-4.4.4/ext/standard/syslog.c hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c
2931--- php-4.4.4/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100
2932+++ hardening-patch-4.4.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:30:51.000000000 +0200
2933@@ -42,6 +42,8 @@
2934 */
2935 PHP_MINIT_FUNCTION(syslog)
2936 {
2937+
2938+#if !HARDENING_PATCH
2939 /* error levels */
2940 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2941 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2942@@ -97,7 +99,7 @@
2943 /* AIX doesn't have LOG_PERROR */
2944 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2945 #endif
2946-
2947+#endif
2948 return SUCCESS;
2949 }
2950 /* }}} */
2951diff -Nura php-4.4.4/ext/varfilter/config.m4 hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4
2952--- php-4.4.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2953+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:30:51.000000000 +0200
2954@@ -0,0 +1,11 @@
2955+dnl
2956+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2957+dnl
2958+
2959+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2960+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2961+
2962+if test "$PHP_VARFILTER" != "no"; then
2963+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2964+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2965+fi
2966diff -Nura php-4.4.4/ext/varfilter/CREDITS hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS
2967--- php-4.4.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2968+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:30:51.000000000 +0200
2969@@ -0,0 +1,2 @@
2970+varfilter
2971+Stefan Esser
2972\ Kein Zeilenumbruch am Dateiende.
2973diff -Nura php-4.4.4/ext/varfilter/php_varfilter.h hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h
2974--- php-4.4.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2975+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:30:51.000000000 +0200
2976@@ -0,0 +1,144 @@
2977+/*
2978+ +----------------------------------------------------------------------+
2979+ | Hardened-PHP Project's varfilter extension |
2980+ +----------------------------------------------------------------------+
2981+ | Copyright (c) 2004-2005 Stefan Esser |
2982+ +----------------------------------------------------------------------+
2983+ | This source file is subject to version 2.02 of the PHP license, |
2984+ | that is bundled with this package in the file LICENSE, and is |
2985+ | available at through the world-wide-web at |
2986+ | http://www.php.net/license/2_02.txt. |
2987+ | If you did not receive a copy of the PHP license and are unable to |
2988+ | obtain it through the world-wide-web, please send a note to |
2989+ | license@php.net so we can mail you a copy immediately. |
2990+ +----------------------------------------------------------------------+
2991+ | Author: Stefan Esser <sesser@hardened-php.net> |
2992+ +----------------------------------------------------------------------+
2993+
2994+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2995+*/
2996+
2997+#ifndef PHP_VARFILTER_H
2998+#define PHP_VARFILTER_H
2999+
3000+extern zend_module_entry varfilter_module_entry;
3001+#define phpext_varfilter_ptr &varfilter_module_entry
3002+
3003+#ifdef PHP_WIN32
3004+#define PHP_VARFILTER_API __declspec(dllexport)
3005+#else
3006+#define PHP_VARFILTER_API
3007+#endif
3008+
3009+#ifdef ZTS
3010+#include "TSRM.h"
3011+#endif
3012+
3013+#include "SAPI.h"
3014+
3015+#include "php_variables.h"
3016+
3017+#ifdef ZEND_ENGINE_2
3018+#define HASH_HTTP_GET_VARS 0x2095733f
3019+#define HASH_HTTP_POST_VARS 0xbfee1265
3020+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
3021+#define HASH_HTTP_ENV_VARS 0x1fe186a8
3022+#define HASH_HTTP_SERVER_VARS 0xc987afd6
3023+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
3024+#define HASH_HTTP_POST_FILES 0x98eb1ddc
3025+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
3026+#else
3027+#define HASH_HTTP_GET_VARS 0x8d8645bd
3028+#define HASH_HTTP_POST_VARS 0x7c699bf3
3029+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
3030+#define HASH_HTTP_ENV_VARS 0x84da3016
3031+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
3032+#define HASH_HTTP_SESSION_VARS 0x322906f5
3033+#define HASH_HTTP_POST_FILES 0xe4e4ce70
3034+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
3035+#endif
3036+
3037+PHP_MINIT_FUNCTION(varfilter);
3038+PHP_MSHUTDOWN_FUNCTION(varfilter);
3039+PHP_RINIT_FUNCTION(varfilter);
3040+PHP_RSHUTDOWN_FUNCTION(varfilter);
3041+PHP_MINFO_FUNCTION(varfilter);
3042+
3043+
3044+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3045+/* request variables */
3046+ long max_request_variables;
3047+ long cur_request_variables;
3048+ long max_varname_length;
3049+ long max_totalname_length;
3050+ long max_value_length;
3051+ long max_array_depth;
3052+ long max_array_index_length;
3053+ zend_bool disallow_nul;
3054+/* cookie variables */
3055+ long max_cookie_vars;
3056+ long cur_cookie_vars;
3057+ long max_cookie_name_length;
3058+ long max_cookie_totalname_length;
3059+ long max_cookie_value_length;
3060+ long max_cookie_array_depth;
3061+ long max_cookie_array_index_length;
3062+ zend_bool disallow_cookie_nul;
3063+/* get variables */
3064+ long max_get_vars;
3065+ long cur_get_vars;
3066+ long max_get_name_length;
3067+ long max_get_totalname_length;
3068+ long max_get_value_length;
3069+ long max_get_array_depth;
3070+ long max_get_array_index_length;
3071+ zend_bool disallow_get_nul;
3072+/* post variables */
3073+ long max_post_vars;
3074+ long cur_post_vars;
3075+ long max_post_name_length;
3076+ long max_post_totalname_length;
3077+ long max_post_value_length;
3078+ long max_post_array_depth;
3079+ long max_post_array_index_length;
3080+ zend_bool disallow_post_nul;
3081+/* fileupload */
3082+ long max_uploads;
3083+ long cur_uploads;
3084+ zend_bool disallow_elf_files;
3085+ char *verification_script;
3086+
3087+ zend_bool no_more_variables;
3088+ zend_bool no_more_get_variables;
3089+ zend_bool no_more_post_variables;
3090+ zend_bool no_more_cookie_variables;
3091+ zend_bool no_more_uploads;
3092+
3093+ZEND_END_MODULE_GLOBALS(varfilter)
3094+
3095+
3096+#ifdef ZTS
3097+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3098+#else
3099+#define VARFILTER_G(v) (varfilter_globals.v)
3100+#endif
3101+
3102+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3103+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3104+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3105+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3106+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3107+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3108+
3109+
3110+
3111+#endif /* PHP_VARFILTER_H */
3112+
3113+
3114+/*
3115+ * Local variables:
3116+ * tab-width: 4
3117+ * c-basic-offset: 4
3118+ * indent-tabs-mode: t
3119+ * End:
3120+ */
3121diff -Nura php-4.4.4/ext/varfilter/varfilter.c hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c
3122--- php-4.4.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3123+++ hardening-patch-4.4.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:18.000000000 +0200
3124@@ -0,0 +1,915 @@
3125+/*
3126+ +----------------------------------------------------------------------+
3127+ | Hardened-PHP Project's varfilter extension |
3128+ +----------------------------------------------------------------------+
3129+ | Copyright (c) 2004-2005 Stefan Esser |
3130+ +----------------------------------------------------------------------+
3131+ | This source file is subject to version 2.02 of the PHP license, |
3132+ | that is bundled with this package in the file LICENSE, and is |
3133+ | available at through the world-wide-web at |
3134+ | http://www.php.net/license/2_02.txt. |
3135+ | If you did not receive a copy of the PHP license and are unable to |
3136+ | obtain it through the world-wide-web, please send a note to |
3137+ | license@php.net so we can mail you a copy immediately. |
3138+ +----------------------------------------------------------------------+
3139+ | Author: Stefan Esser <sesser@hardened-php.net> |
3140+ +----------------------------------------------------------------------+
3141+
3142+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3143+*/
3144+
3145+#ifdef HAVE_CONFIG_H
3146+#include "config.h"
3147+#endif
3148+
3149+#include "php.h"
3150+#include "php_ini.h"
3151+#include "ext/standard/info.h"
3152+#include "php_varfilter.h"
3153+#include "hardening_patch.h"
3154+
3155+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3156+
3157+/* True global resources - no need for thread safety here */
3158+static int le_varfilter;
3159+
3160+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3161+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3162+static zend_bool hooked = 0;
3163+
3164+/* {{{ varfilter_module_entry
3165+ */
3166+zend_module_entry varfilter_module_entry = {
3167+#if ZEND_MODULE_API_NO >= 20010901
3168+ STANDARD_MODULE_HEADER,
3169+#endif
3170+ "varfilter",
3171+ NULL,
3172+ PHP_MINIT(varfilter),
3173+ PHP_MSHUTDOWN(varfilter),
3174+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3175+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3176+ PHP_MINFO(varfilter),
3177+#if ZEND_MODULE_API_NO >= 20010901
3178+ "0.4.15", /* Replace with version number for your extension */
3179+#endif
3180+ STANDARD_MODULE_PROPERTIES
3181+};
3182+/* }}} */
3183+
3184+#ifdef COMPILE_DL_VARFILTER
3185+ZEND_GET_MODULE(varfilter)
3186+#endif
3187+
3188+/* {{{ PHP_INI
3189+ */
3190+PHP_INI_BEGIN()
3191+ /* for backward compatibility */
3192+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3193+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3194+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3195+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3196+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3197+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3198+
3199+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3200+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3201+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3202+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3203+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3204+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3205+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3206+
3207+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3208+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3209+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3210+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3211+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3212+ 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)
3213+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3214+
3215+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3216+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3217+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3218+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3219+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3220+ 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)
3221+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3222+
3223+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3224+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3225+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3226+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3227+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3228+ 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)
3229+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3230+
3231+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3232+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3233+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3234+
3235+
3236+PHP_INI_END()
3237+/* }}} */
3238+
3239+/* {{{ php_varfilter_init_globals
3240+ */
3241+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3242+{
3243+ varfilter_globals->max_request_variables = 200;
3244+ varfilter_globals->max_varname_length = 64;
3245+ varfilter_globals->max_value_length = 10000;
3246+ varfilter_globals->max_array_depth = 100;
3247+ varfilter_globals->max_totalname_length = 256;
3248+ varfilter_globals->max_array_index_length = 64;
3249+ varfilter_globals->disallow_nul = 1;
3250+
3251+ varfilter_globals->max_cookie_vars = 100;
3252+ varfilter_globals->max_cookie_name_length = 64;
3253+ varfilter_globals->max_cookie_totalname_length = 256;
3254+ varfilter_globals->max_cookie_value_length = 10000;
3255+ varfilter_globals->max_cookie_array_depth = 100;
3256+ varfilter_globals->max_cookie_array_index_length = 64;
3257+ varfilter_globals->disallow_cookie_nul = 1;
3258+
3259+ varfilter_globals->max_get_vars = 100;
3260+ varfilter_globals->max_get_name_length = 64;
3261+ varfilter_globals->max_get_totalname_length = 256;
3262+ varfilter_globals->max_get_value_length = 512;
3263+ varfilter_globals->max_get_array_depth = 50;
3264+ varfilter_globals->max_get_array_index_length = 64;
3265+ varfilter_globals->disallow_get_nul = 1;
3266+
3267+ varfilter_globals->max_post_vars = 200;
3268+ varfilter_globals->max_post_name_length = 64;
3269+ varfilter_globals->max_post_totalname_length = 256;
3270+ varfilter_globals->max_post_value_length = 65000;
3271+ varfilter_globals->max_post_array_depth = 100;
3272+ varfilter_globals->max_post_array_index_length = 64;
3273+ varfilter_globals->disallow_post_nul = 1;
3274+
3275+ varfilter_globals->max_uploads = 25;
3276+ varfilter_globals->disallow_elf_files = 1;
3277+ varfilter_globals->verification_script = NULL;
3278+
3279+ varfilter_globals->no_more_variables = 0;
3280+ varfilter_globals->no_more_get_variables = 0;
3281+ varfilter_globals->no_more_post_variables = 0;
3282+ varfilter_globals->no_more_cookie_variables = 0;
3283+ varfilter_globals->no_more_uploads = 0;
3284+
3285+ varfilter_globals->cur_request_variables = 0;
3286+ varfilter_globals->cur_get_vars = 0;
3287+ varfilter_globals->cur_post_vars = 0;
3288+ varfilter_globals->cur_cookie_vars = 0;
3289+
3290+ varfilter_globals->cur_uploads = 0;
3291+
3292+}
3293+/* }}} */
3294+
3295+
3296+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3297+{
3298+ HashTable *svars;
3299+ int retval, failure=0;
3300+
3301+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3302+
3303+ svars = Z_ARRVAL_P(track_vars_array);
3304+
3305+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3306+ if (retval == SUCCESS) failure = 1;
3307+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3308+ if (retval == SUCCESS) failure = 1;
3309+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3310+ if (retval == SUCCESS) failure = 1;
3311+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3312+ if (retval == SUCCESS) failure = 1;
3313+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3314+ if (retval == SUCCESS) failure = 1;
3315+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3316+ if (retval == SUCCESS) failure = 1;
3317+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3318+ if (retval == SUCCESS) failure = 1;
3319+ 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);
3320+ if (retval == SUCCESS) failure = 1;
3321+
3322+ if (failure) {
3323+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3324+ }
3325+}
3326+
3327+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3328+{
3329+ int retval = SAPI_HEADER_ADD, i;
3330+ char *tmp;
3331+
3332+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3333+
3334+ tmp = sapi_header->header;
3335+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3336+ if (tmp[0] == 0) {
3337+ char *fname = get_active_function_name(TSRMLS_C);
3338+
3339+ if (!fname) {
3340+ fname = "unknown";
3341+ }
3342+
3343+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3344+ sapi_header->header_len = i;
3345+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3346+ char *fname = get_active_function_name(TSRMLS_C);
3347+
3348+ if (!fname) {
3349+ fname = "unknown";
3350+ }
3351+
3352+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3353+ sapi_header->header_len = i;
3354+ tmp[0] = 0;
3355+ }
3356+ }
3357+ }
3358+
3359+ if (orig_header_handler) {
3360+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3361+ }
3362+
3363+ return retval;
3364+}
3365+
3366+/* {{{ PHP_MINIT_FUNCTION
3367+ */
3368+PHP_MINIT_FUNCTION(varfilter)
3369+{
3370+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3371+ REGISTER_INI_ENTRIES();
3372+
3373+ if (!hooked) {
3374+ void *temp;
3375+ hooked = 1;
3376+
3377+ temp = (void *)sapi_module.register_server_variables;
3378+ if (temp != varfilter_register_server_variables) {
3379+ orig_register_server_variables = temp;
3380+ }
3381+ temp = (void *)sapi_module.header_handler;
3382+ if (temp != varfilter_header_handler) {
3383+ orig_header_handler = temp;
3384+ }
3385+ }
3386+
3387+ sapi_register_input_filter(varfilter_input_filter);
3388+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3389+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3390+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3391+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3392+
3393+ sapi_module.header_handler = varfilter_header_handler;
3394+ sapi_module.register_server_variables = varfilter_register_server_variables;
3395+
3396+
3397+ return SUCCESS;
3398+}
3399+/* }}} */
3400+
3401+/* {{{ PHP_MSHUTDOWN_FUNCTION
3402+ */
3403+PHP_MSHUTDOWN_FUNCTION(varfilter)
3404+{
3405+ UNREGISTER_INI_ENTRIES();
3406+
3407+ return SUCCESS;
3408+}
3409+/* }}} */
3410+
3411+/* Remove if there's nothing to do at request start */
3412+/* {{{ PHP_RINIT_FUNCTION
3413+ */
3414+PHP_RINIT_FUNCTION(varfilter)
3415+{
3416+ VARFILTER_G(cur_request_variables) = 0;
3417+ VARFILTER_G(cur_get_vars) = 0;
3418+ VARFILTER_G(cur_post_vars) = 0;
3419+ VARFILTER_G(cur_cookie_vars) = 0;
3420+
3421+ VARFILTER_G(cur_uploads) = 0;
3422+
3423+ VARFILTER_G(no_more_variables) = 0;
3424+ VARFILTER_G(no_more_get_variables) = 0;
3425+ VARFILTER_G(no_more_post_variables) = 0;
3426+ VARFILTER_G(no_more_cookie_variables) = 0;
3427+ VARFILTER_G(no_more_uploads) = 0;
3428+
3429+ return SUCCESS;
3430+}
3431+/* }}} */
3432+
3433+/* Remove if there's nothing to do at request end */
3434+/* {{{ PHP_RSHUTDOWN_FUNCTION
3435+ */
3436+PHP_RSHUTDOWN_FUNCTION(varfilter)
3437+{
3438+ return SUCCESS;
3439+}
3440+/* }}} */
3441+
3442+/* {{{ PHP_MINFO_FUNCTION
3443+ */
3444+PHP_MINFO_FUNCTION(varfilter)
3445+{
3446+ php_info_print_table_start();
3447+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3448+ php_info_print_table_end();
3449+
3450+ DISPLAY_INI_ENTRIES();
3451+}
3452+/* }}} */
3453+
3454+/* {{{ normalize_varname
3455+ */
3456+static void normalize_varname(char *varname)
3457+{
3458+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3459+
3460+ /* overjump leading space */
3461+ while (*s == ' ') {
3462+ s++;
3463+ }
3464+
3465+ /* and remove it */
3466+ if (s != varname) {
3467+ memmove(varname, s, strlen(s)+1);
3468+ }
3469+
3470+ for (p=varname; *p && *p != '['; p++) {
3471+ switch(*p) {
3472+ case ' ':
3473+ case '.':
3474+ *p='_';
3475+ break;
3476+ }
3477+ }
3478+
3479+ /* find index */
3480+ index = strchr(varname, '[');
3481+ if (index) {
3482+ index++;
3483+ s=index;
3484+ } else {
3485+ return;
3486+ }
3487+
3488+ /* done? */
3489+ while (index) {
3490+
3491+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3492+ index++;
3493+ }
3494+ indexend = strchr(index, ']');
3495+ indexend = indexend ? indexend + 1 : index + strlen(index);
3496+
3497+ if (s != index) {
3498+ memmove(s, index, strlen(index)+1);
3499+ s += indexend-index;
3500+ } else {
3501+ s = indexend;
3502+ }
3503+
3504+ if (*s == '[') {
3505+ s++;
3506+ index = s;
3507+ } else {
3508+ index = NULL;
3509+ }
3510+ }
3511+ *s++='\0';
3512+}
3513+/* }}} */
3514+
3515+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3516+ */
3517+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3518+{
3519+ char *index, *prev_index = NULL, *var;
3520+ unsigned int var_len, total_len, depth = 0;
3521+
3522+ var = estrdup(varname);
3523+
3524+ /* Normalize the variable name */
3525+ normalize_varname(var);
3526+
3527+ /* Find length of variable name */
3528+ index = strchr(var, '[');
3529+ total_len = strlen(var);
3530+ var_len = index ? index-var : total_len;
3531+
3532+ /* Drop this variable if it exceeds the varname/total length limit */
3533+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3534+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3535+ goto return_failure;
3536+ }
3537+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3538+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3539+ goto return_failure;
3540+ }
3541+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3542+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3543+
3544+ goto return_failure;
3545+ }
3546+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3547+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3548+ goto return_failure;
3549+ }
3550+
3551+ /* Find out array depth */
3552+ while (index) {
3553+ unsigned int index_length;
3554+
3555+ depth++;
3556+ index = strchr(index+1, '[');
3557+
3558+ if (prev_index) {
3559+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3560+
3561+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3562+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3563+ goto return_failure;
3564+ }
3565+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3566+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3567+ goto return_failure;
3568+ }
3569+ prev_index = index;
3570+ }
3571+
3572+ }
3573+
3574+ /* Drop this variable if it exceeds the array depth limit */
3575+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3576+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3577+ goto return_failure;
3578+ }
3579+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3580+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3581+ goto return_failure;
3582+ }
3583+
3584+
3585+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3586+ /* This is to protect several silly scripts that do globalizing themself */
3587+
3588+ switch (var_len) {
3589+ case 18:
3590+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3591+ break;
3592+ case 17:
3593+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3594+ break;
3595+ case 16:
3596+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3597+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3598+ break;
3599+ case 15:
3600+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3601+ break;
3602+ case 14:
3603+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3604+ break;
3605+ case 13:
3606+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3607+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3608+ break;
3609+ case 8:
3610+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3611+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3612+ break;
3613+ case 7:
3614+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3615+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3616+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3617+ break;
3618+ case 6:
3619+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3620+ break;
3621+ case 5:
3622+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3623+ break;
3624+ case 4:
3625+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3626+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3627+ break;
3628+ }
3629+
3630+ efree(var);
3631+ return SUCCESS;
3632+protected_varname2:
3633+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3634+return_failure:
3635+ efree(var);
3636+ return FAILURE;
3637+}
3638+/* }}} */
3639+
3640+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3641+ */
3642+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3643+{
3644+ /* Drop if no more variables flag is set */
3645+ if (VARFILTER_G(no_more_uploads)) {
3646+ return FAILURE;
3647+ }
3648+ /* Drop this fileupload if the limit is reached */
3649+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3650+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3651+ VARFILTER_G(no_more_uploads) = 1;
3652+ return FAILURE;
3653+ }
3654+
3655+ return SUCCESS;
3656+}
3657+/* }}} */
3658+
3659+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3660+ */
3661+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3662+{
3663+
3664+ if (VARFILTER_G(disallow_elf_files)) {
3665+
3666+ if (offset == 0 && buffer_len > 10) {
3667+
3668+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3669+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3670+ return FAILURE;
3671+ }
3672+ }
3673+
3674+ }
3675+
3676+ return SUCCESS;
3677+}
3678+/* }}} */
3679+
3680+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3681+ */
3682+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3683+{
3684+ int retval = SUCCESS;
3685+
3686+ if (VARFILTER_G(verification_script)) {
3687+ char cmd[8192];
3688+ FILE *in;
3689+ int first=1;
3690+
3691+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3692+
3693+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3694+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3695+ return FAILURE;
3696+ }
3697+
3698+ retval = FAILURE;
3699+
3700+ /* read and forget the result */
3701+ while (1) {
3702+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3703+ if (readbytes<=0) {
3704+ break;
3705+ }
3706+ if (first) {
3707+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3708+ first = 0;
3709+ }
3710+ }
3711+ pclose(in);
3712+ }
3713+
3714+ if (retval != SUCCESS) {
3715+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3716+ return FAILURE;
3717+ }
3718+
3719+ VARFILTER_G(cur_uploads)++;
3720+ return SUCCESS;
3721+}
3722+/* }}} */
3723+
3724+/* {{{ SAPI_INPUT_FILTER_FUNC
3725+ */
3726+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3727+{
3728+ char *index, *prev_index = NULL;
3729+ unsigned int var_len, total_len, depth = 0;
3730+
3731+ /* Drop this variable if the limit was reached */
3732+ switch (arg) {
3733+ case PARSE_GET:
3734+ if (VARFILTER_G(no_more_get_variables)) {
3735+ return 0;
3736+ }
3737+ break;
3738+ case PARSE_POST:
3739+ if (VARFILTER_G(no_more_post_variables)) {
3740+ return 0;
3741+ }
3742+ break;
3743+ case PARSE_COOKIE:
3744+ if (VARFILTER_G(no_more_cookie_variables)) {
3745+ return 0;
3746+ }
3747+ break;
3748+ default: /* we do not want to protect parse_str() and friends */
3749+ if (new_val_len) {
3750+ *new_val_len = val_len;
3751+ }
3752+ return 1;
3753+ }
3754+ if (VARFILTER_G(no_more_variables)) {
3755+ return 0;
3756+ }
3757+
3758+ /* Drop this variable if the limit is now reached */
3759+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3760+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3761+ VARFILTER_G(no_more_variables) = 1;
3762+ return 0;
3763+ }
3764+ switch (arg) {
3765+ case PARSE_GET:
3766+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3767+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3768+ VARFILTER_G(no_more_get_variables) = 1;
3769+ return 0;
3770+ }
3771+ break;
3772+ case PARSE_COOKIE:
3773+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3774+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3775+ VARFILTER_G(no_more_cookie_variables) = 1;
3776+ return 0;
3777+ }
3778+ break;
3779+ case PARSE_POST:
3780+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3781+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3782+ VARFILTER_G(no_more_post_variables) = 1;
3783+ return 0;
3784+ }
3785+ break;
3786+ }
3787+
3788+
3789+ /* Drop this variable if it exceeds the value length limit */
3790+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3791+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3792+ return 0;
3793+ }
3794+ switch (arg) {
3795+ case PARSE_GET:
3796+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3797+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3798+ return 0;
3799+ }
3800+ break;
3801+ case PARSE_COOKIE:
3802+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3803+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3804+ return 0;
3805+ }
3806+ break;
3807+ case PARSE_POST:
3808+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3809+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3810+ return 0;
3811+ }
3812+ break;
3813+ }
3814+
3815+ /* Normalize the variable name */
3816+ normalize_varname(var);
3817+
3818+ /* Find length of variable name */
3819+ index = strchr(var, '[');
3820+ total_len = strlen(var);
3821+ var_len = index ? index-var : total_len;
3822+
3823+ /* Drop this variable if it exceeds the varname/total length limit */
3824+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3825+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3826+ return 0;
3827+ }
3828+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3829+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3830+ return 0;
3831+ }
3832+ switch (arg) {
3833+ case PARSE_GET:
3834+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3835+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3836+ return 0;
3837+ }
3838+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3839+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3840+ return 0;
3841+ }
3842+ break;
3843+ case PARSE_COOKIE:
3844+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3845+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3846+ return 0;
3847+ }
3848+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3849+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3850+ return 0;
3851+ }
3852+ break;
3853+ case PARSE_POST:
3854+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3855+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3856+ return 0;
3857+ }
3858+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3859+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3860+ return 0;
3861+ }
3862+ break;
3863+ }
3864+
3865+ /* Find out array depth */
3866+ while (index) {
3867+ unsigned int index_length;
3868+
3869+ depth++;
3870+ index = strchr(index+1, '[');
3871+
3872+ if (prev_index) {
3873+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3874+
3875+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3876+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3877+ return 0;
3878+ }
3879+ switch (arg) {
3880+ case PARSE_GET:
3881+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3882+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3883+ return 0;
3884+ }
3885+ break;
3886+ case PARSE_COOKIE:
3887+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3888+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3889+ return 0;
3890+ }
3891+ break;
3892+ case PARSE_POST:
3893+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3894+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3895+ return 0;
3896+ }
3897+ break;
3898+ }
3899+ prev_index = index;
3900+ }
3901+
3902+ }
3903+
3904+ /* Drop this variable if it exceeds the array depth limit */
3905+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3906+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3907+ return 0;
3908+ }
3909+ switch (arg) {
3910+ case PARSE_GET:
3911+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3912+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3913+ return 0;
3914+ }
3915+ break;
3916+ case PARSE_COOKIE:
3917+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3918+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3919+ return 0;
3920+ }
3921+ break;
3922+ case PARSE_POST:
3923+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3924+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3925+ return 0;
3926+ }
3927+ break;
3928+ }
3929+
3930+ /* Check if variable value is truncated by a \0 */
3931+
3932+ if (val && *val && val_len != strlen(*val)) {
3933+
3934+ if (VARFILTER_G(disallow_nul)) {
3935+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3936+ return 0;
3937+ }
3938+ switch (arg) {
3939+ case PARSE_GET:
3940+ if (VARFILTER_G(disallow_get_nul)) {
3941+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3942+ return 0;
3943+ }
3944+ break;
3945+ case PARSE_COOKIE:
3946+ if (VARFILTER_G(disallow_cookie_nul)) {
3947+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3948+ return 0;
3949+ }
3950+ break;
3951+ case PARSE_POST:
3952+ if (VARFILTER_G(disallow_post_nul)) {
3953+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3954+ return 0;
3955+ }
3956+ break;
3957+ }
3958+ }
3959+
3960+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3961+ /* This is to protect several silly scripts that do globalizing themself */
3962+
3963+ switch (var_len) {
3964+ case 18:
3965+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3966+ break;
3967+ case 17:
3968+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3969+ break;
3970+ case 16:
3971+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3972+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3973+ break;
3974+ case 15:
3975+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3976+ break;
3977+ case 14:
3978+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3979+ break;
3980+ case 13:
3981+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3982+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3983+ break;
3984+ case 8:
3985+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3986+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3987+ break;
3988+ case 7:
3989+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3990+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3991+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3992+ break;
3993+ case 6:
3994+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3995+ break;
3996+ case 5:
3997+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3998+ break;
3999+ case 4:
4000+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
4001+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
4002+ break;
4003+ }
4004+
4005+ /* Okay let PHP register this variable */
4006+ VARFILTER_G(cur_request_variables)++;
4007+ switch (arg) {
4008+ case PARSE_GET:
4009+ VARFILTER_G(cur_get_vars)++;
4010+ break;
4011+ case PARSE_COOKIE:
4012+ VARFILTER_G(cur_cookie_vars)++;
4013+ break;
4014+ case PARSE_POST:
4015+ VARFILTER_G(cur_post_vars)++;
4016+ break;
4017+ }
4018+
4019+ if (new_val_len) {
4020+ *new_val_len = val_len;
4021+ }
4022+
4023+ return 1;
4024+protected_varname:
4025+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
4026+ return 0;
4027+}
4028+/* }}} */
4029+
4030+/*
4031+ * Local variables:
4032+ * tab-width: 4
4033+ * c-basic-offset: 4
4034+ * End:
4035+ * vim600: noet sw=4 ts=4 fdm=marker
4036+ * vim<600: noet sw=4 ts=4
4037+ */
4038+
4039+
4040diff -Nura php-4.4.4/main/fopen_wrappers.c hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c
4041--- php-4.4.4/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100
4042+++ hardening-patch-4.4.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:45.000000000 +0200
4043@@ -106,7 +106,10 @@
4044 }
4045
4046 /* Resolve the real path into resolved_name */
4047- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) {
4048+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
4049+ return -2;
4050+ }
4051+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) {
4052 /* Handler for basedirs that end with a / */
4053 resolved_basedir_len = strlen(resolved_basedir);
4054 if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
4055@@ -116,14 +119,20 @@
4056 }
4057 }
4058
4059+ resolved_name_len = strlen(resolved_name);
4060 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
4061- resolved_name_len = strlen(resolved_name);
4062 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
4063 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
4064 resolved_name[++resolved_name_len] = '\0';
4065 }
4066 }
4067
4068+ if (resolved_name_len == resolved_basedir_len - 1) {
4069+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4070+ resolved_basedir_len--;
4071+ }
4072+ }
4073+
4074 /* Check the path */
4075 #ifdef PHP_WIN32
4076 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4077@@ -137,7 +146,7 @@
4078 }
4079 } else {
4080 /* Unable to resolve the real path, return -1 */
4081- return -1;
4082+ return -3;
4083 }
4084 }
4085 /* }}} */
4086@@ -156,22 +165,44 @@
4087 char *pathbuf;
4088 char *ptr;
4089 char *end;
4090+ char path_copy[MAXPATHLEN];
4091+ int path_len;
4092+
4093+ /* Special case path ends with a trailing slash */
4094+ path_len = strlen(path);
4095+ if (path_len >= MAXPATHLEN) {
4096+ errno = EPERM; /* we deny permission to open it */
4097+ return -1;
4098+ }
4099+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4100+ memcpy(path_copy, path, path_len+1);
4101+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4102+ path_copy[path_len] = '\0';
4103+ path = (const char *)&path_copy;
4104+ }
4105
4106 pathbuf = estrdup(PG(open_basedir));
4107
4108 ptr = pathbuf;
4109
4110 while (ptr && *ptr) {
4111+ int res;
4112 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
4113 if (end != NULL) {
4114 *end = '\0';
4115 end++;
4116 }
4117
4118- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
4119+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC);
4120+ if (res == 0) {
4121 efree(pathbuf);
4122 return 0;
4123 }
4124+ if (res == -2) {
4125+ efree(pathbuf);
4126+ errno = EPERM;
4127+ return -1;
4128+ }
4129
4130 ptr = end;
4131 }
4132diff -Nura php-4.4.4/main/hardened_globals.h hardening-patch-4.4.4-0.4.15/main/hardened_globals.h
4133--- php-4.4.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4134+++ hardening-patch-4.4.4-0.4.15/main/hardened_globals.h 2006-09-05 20:30:51.000000000 +0200
4135@@ -0,0 +1,64 @@
4136+/*
4137+ +----------------------------------------------------------------------+
4138+ | Hardening-Patch for PHP |
4139+ +----------------------------------------------------------------------+
4140+ | Copyright (c) 2004-2005 Stefan Esser |
4141+ +----------------------------------------------------------------------+
4142+ | This source file is subject to version 2.02 of the PHP license, |
4143+ | that is bundled with this package in the file LICENSE, and is |
4144+ | available at through the world-wide-web at |
4145+ | http://www.php.net/license/2_02.txt. |
4146+ | If you did not receive a copy of the PHP license and are unable to |
4147+ | obtain it through the world-wide-web, please send a note to |
4148+ | license@php.net so we can mail you a copy immediately. |
4149+ +----------------------------------------------------------------------+
4150+ | Author: Stefan Esser <sesser@hardened-php.net> |
4151+ +----------------------------------------------------------------------+
4152+ */
4153+
4154+#ifndef HARDENED_GLOBALS_H
4155+#define HARDENED_GLOBALS_H
4156+
4157+typedef struct _hardened_globals hardened_globals_struct;
4158+
4159+#ifdef ZTS
4160+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4161+extern int hardened_globals_id;
4162+#else
4163+# define HG(v) (hardened_globals.v)
4164+extern struct _hardened_globals hardened_globals;
4165+#endif
4166+
4167+
4168+struct _hardened_globals {
4169+#if HARDENING_PATCH_MM_PROTECT
4170+ unsigned int canary_1;
4171+ unsigned int canary_2;
4172+#endif
4173+#if HARDENING_PATCH_LL_PROTECT
4174+ unsigned int canary_3;
4175+ unsigned int canary_4;
4176+ unsigned int ll_canary_inited;
4177+#endif
4178+ zend_bool hphp_sql_bailout_on_error;
4179+ zend_bool hphp_multiheader;
4180+ unsigned long hphp_mailprotect;
4181+ long hard_memory_limit;
4182+ HashTable *eval_whitelist;
4183+ HashTable *eval_blacklist;
4184+ HashTable *func_whitelist;
4185+ HashTable *func_blacklist;
4186+ HashTable *include_whitelist;
4187+ HashTable *include_blacklist;
4188+ unsigned int dummy;
4189+};
4190+
4191+
4192+#endif /* HARDENED_GLOBALS_H */
4193+
4194+/*
4195+ * Local variables:
4196+ * tab-width: 4
4197+ * c-basic-offset: 4
4198+ * End:
4199+ */
4200diff -Nura php-4.4.4/main/hardening_patch.c hardening-patch-4.4.4-0.4.15/main/hardening_patch.c
4201--- php-4.4.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4202+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.c 2006-09-07 18:47:49.000000000 +0200
4203@@ -0,0 +1,430 @@
4204+/*
4205+ +----------------------------------------------------------------------+
4206+ | Hardening Patch for PHP |
4207+ +----------------------------------------------------------------------+
4208+ | Copyright (c) 2004-2005 Stefan Esser |
4209+ +----------------------------------------------------------------------+
4210+ | This source file is subject to version 2.02 of the PHP license, |
4211+ | that is bundled with this package in the file LICENSE, and is |
4212+ | available at through the world-wide-web at |
4213+ | http://www.php.net/license/2_02.txt. |
4214+ | If you did not receive a copy of the PHP license and are unable to |
4215+ | obtain it through the world-wide-web, please send a note to |
4216+ | license@php.net so we can mail you a copy immediately. |
4217+ +----------------------------------------------------------------------+
4218+ | Author: Stefan Esser <sesser@hardened-php.net> |
4219+ +----------------------------------------------------------------------+
4220+ */
4221+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4222+
4223+#include "php.h"
4224+
4225+#include <stdio.h>
4226+#include <stdlib.h>
4227+
4228+#if HAVE_UNISTD_H
4229+#include <unistd.h>
4230+#endif
4231+#include "SAPI.h"
4232+#include "php_globals.h"
4233+
4234+#if HARDENING_PATCH
4235+
4236+#ifdef HAVE_SYS_SOCKET_H
4237+#include <sys/socket.h>
4238+#endif
4239+
4240+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4241+#undef AF_UNIX
4242+#endif
4243+
4244+#if defined(AF_UNIX)
4245+#include <sys/un.h>
4246+#endif
4247+
4248+#define SYSLOG_PATH "/dev/log"
4249+
4250+#include "snprintf.h"
4251+
4252+#include "hardening_patch.h"
4253+
4254+#ifdef ZTS
4255+#include "hardened_globals.h"
4256+int hardened_globals_id;
4257+#else
4258+struct _hardened_globals hardened_globals;
4259+#endif
4260+
4261+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4262+{
4263+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4264+}
4265+
4266+
4267+PHPAPI void hardened_startup()
4268+{
4269+#ifdef ZTS
4270+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4271+#else
4272+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4273+#endif
4274+}
4275+
4276+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4277+{
4278+ HG(canary_1) = php_canary();
4279+ HG(canary_2) = php_canary();
4280+}
4281+
4282+char *loglevel2string(int loglevel)
4283+{
4284+ switch (loglevel) {
4285+ case S_FILES:
4286+ return "FILES";
4287+ case S_INCLUDE:
4288+ return "INCLUDE";
4289+ case S_MEMORY:
4290+ return "MEMORY";
4291+ case S_MISC:
4292+ return "MISC";
4293+ case S_SQL:
4294+ return "SQL";
4295+ case S_EXECUTOR:
4296+ return "EXECUTOR";
4297+ case S_VARS:
4298+ return "VARS";
4299+ default:
4300+ return "UNKNOWN";
4301+ }
4302+}
4303+
4304+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4305+{
4306+#if defined(AF_UNIX)
4307+ int s, r, i=0;
4308+ struct sockaddr_un saun;
4309+ char buf[4096+64];
4310+ char error[4096+100];
4311+ char *ip_address;
4312+ char *fname;
4313+ int lineno;
4314+ va_list ap;
4315+ TSRMLS_FETCH();
4316+
4317+ if (EG(hphp_log_use_x_forwarded_for)) {
4318+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4319+ if (ip_address == NULL) {
4320+ ip_address = "X-FORWARDED-FOR not set";
4321+ }
4322+ } else {
4323+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4324+ if (ip_address == NULL) {
4325+ ip_address = "REMOTE_ADDR not set";
4326+ }
4327+ }
4328+
4329+
4330+ va_start(ap, fmt);
4331+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4332+ va_end(ap);
4333+ while (error[i]) {
4334+ if (error[i] < 32) error[i] = '.';
4335+ i++;
4336+ }
4337+
4338+ if (zend_is_executing(TSRMLS_C)) {
4339+ lineno = zend_get_executed_lineno(TSRMLS_C);
4340+ fname = zend_get_executed_filename(TSRMLS_C);
4341+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4342+ } else {
4343+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4344+ if (fname==NULL) {
4345+ fname = "unknown";
4346+ }
4347+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4348+ }
4349+
4350+ /* Syslog-Logging disabled? */
4351+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4352+ goto log_sapi;
4353+ }
4354+
4355+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4356+
4357+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4358+ if (s == -1) {
4359+ goto log_sapi;
4360+ }
4361+
4362+ memset(&saun, 0, sizeof(saun));
4363+ saun.sun_family = AF_UNIX;
4364+ strcpy(saun.sun_path, SYSLOG_PATH);
4365+ /*saun.sun_len = sizeof(saun);*/
4366+
4367+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4368+ if (r) {
4369+ close(s);
4370+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4371+ if (s == -1) {
4372+ goto log_sapi;
4373+ }
4374+
4375+ memset(&saun, 0, sizeof(saun));
4376+ saun.sun_family = AF_UNIX;
4377+ strcpy(saun.sun_path, SYSLOG_PATH);
4378+ /*saun.sun_len = sizeof(saun);*/
4379+
4380+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4381+ if (r) {
4382+ close(s);
4383+ goto log_sapi;
4384+ }
4385+ }
4386+ send(s, error, strlen(error), 0);
4387+
4388+ close(s);
4389+
4390+log_sapi:
4391+ /* SAPI Logging activated? */
4392+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4393+ sapi_module.log_message(buf);
4394+ }
4395+
4396+log_script:
4397+ /* script logging activaed? */
4398+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4399+ char cmd[8192], *cmdpos, *bufpos;
4400+ FILE *in;
4401+ int space;
4402+
4403+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4404+ space = sizeof(cmd) - strlen(cmd);
4405+ cmdpos = cmd + strlen(cmd);
4406+ bufpos = buf;
4407+ if (space <= 1) return;
4408+ while (space > 2 && *bufpos) {
4409+ if (*bufpos == '\'') {
4410+ if (space<=5) break;
4411+ *cmdpos++ = '\'';
4412+ *cmdpos++ = '\\';
4413+ *cmdpos++ = '\'';
4414+ *cmdpos++ = '\'';
4415+ bufpos++;
4416+ space-=4;
4417+ } else {
4418+ *cmdpos++ = *bufpos++;
4419+ space--;
4420+ }
4421+ }
4422+ *cmdpos++ = '\'';
4423+ *cmdpos = 0;
4424+
4425+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4426+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4427+ return;
4428+ }
4429+ /* read and forget the result */
4430+ while (1) {
4431+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4432+ if (readbytes<=0) {
4433+ break;
4434+ }
4435+ }
4436+ pclose(in);
4437+ }
4438+
4439+#endif
4440+}
4441+#endif
4442+
4443+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4444+
4445+/* will be replaced later with more compatible method */
4446+PHPAPI unsigned int php_canary()
4447+{
4448+ time_t t;
4449+ unsigned int canary;
4450+ int fd;
4451+
4452+ fd = open("/dev/urandom", 0);
4453+ if (fd != -1) {
4454+ int r = read(fd, &canary, sizeof(canary));
4455+ close(fd);
4456+ if (r == sizeof(canary)) {
4457+ return (canary);
4458+ }
4459+ }
4460+ /* not good but we never want to do this */
4461+ time(&t);
4462+ canary = *(unsigned int *)&t + getpid() << 16;
4463+ return (canary);
4464+}
4465+#endif
4466+
4467+#if HARDENING_PATCH_INC_PROTECT
4468+
4469+PHPAPI int php_is_valid_include(zval *z)
4470+{
4471+ char *filename;
4472+ int len, i;
4473+ TSRMLS_FETCH();
4474+
4475+ /* must be of type string */
4476+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4477+ return (0);
4478+ }
4479+
4480+ /* short cut */
4481+ filename = z->value.str.val;
4482+ len = z->value.str.len;
4483+
4484+ /* 1. must be shorter than MAXPATHLEN */
4485+ if (len > MAXPATHLEN) {
4486+ char *fname = estrndup(filename, len);
4487+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4488+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4489+ efree(fname);
4490+ return (0);
4491+ }
4492+
4493+ /* 2. must not be cutted */
4494+ if (len != strlen(filename)) {
4495+ char *fname = estrndup(filename, len);
4496+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4497+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4498+ efree(fname);
4499+ return (0);
4500+ }
4501+
4502+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4503+ if (strstr(filename, "://")) {
4504+ char *fname = estrndup(filename, len);
4505+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4506+
4507+ /* no black or whitelist then disallow all */
4508+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4509+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4510+ efree(fname);
4511+ return (0);
4512+ }
4513+
4514+ /* whitelist is stronger than blacklist */
4515+ if (HG(include_whitelist)) {
4516+ char *s, *t, *h, *index;
4517+ uint indexlen;
4518+ ulong numindex;
4519+
4520+ s = filename;
4521+
4522+ do {
4523+ zend_bool isOk = 0;
4524+ int tlen;
4525+
4526+ t = h = strstr(s, "://");
4527+ if (h == NULL) break;
4528+
4529+
4530+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4531+ t--;
4532+ }
4533+
4534+ tlen = strlen(t);
4535+
4536+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4537+ do {
4538+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4539+
4540+ if (r==HASH_KEY_NON_EXISTANT) {
4541+ break;
4542+ }
4543+ if (r==HASH_KEY_IS_STRING) {
4544+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4545+ if (strncmp(t, index, indexlen-1)==0) {
4546+ isOk = 1;
4547+ break;
4548+ }
4549+ }
4550+ }
4551+
4552+ zend_hash_move_forward(HG(include_whitelist));
4553+ } while (1);
4554+
4555+ /* not found in whitelist */
4556+ if (!isOk) {
4557+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4558+ efree(fname);
4559+ return 0;
4560+ }
4561+
4562+ s = h + 3;
4563+ } while (1);
4564+ } else {
4565+ /* okay then handle the blacklist */
4566+ char *s, *t, *h, *index;
4567+ uint indexlen;
4568+ ulong numindex;
4569+
4570+ s = filename;
4571+
4572+ do {
4573+ int tlen;
4574+
4575+ t = h = strstr(s, "://");
4576+ if (h == NULL) break;
4577+
4578+
4579+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4580+ t--;
4581+ }
4582+
4583+ tlen = strlen(t);
4584+
4585+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4586+ do {
4587+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4588+
4589+ if (r==HASH_KEY_NON_EXISTANT) {
4590+ break;
4591+ }
4592+ if (r==HASH_KEY_IS_STRING) {
4593+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4594+ if (strncmp(t, index, indexlen-1)==0) {
4595+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4596+ efree(fname);
4597+ return 0;
4598+ }
4599+ }
4600+ }
4601+
4602+ zend_hash_move_forward(HG(include_blacklist));
4603+ } while (1);
4604+
4605+ s = h + 3;
4606+ } while (1);
4607+ }
4608+
4609+ efree(fname);
4610+ }
4611+
4612+ /* 4. must not be an uploaded file */
4613+ if (SG(rfc1867_uploaded_files)) {
4614+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4615+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4616+ return (0);
4617+ }
4618+ }
4619+
4620+ /* passed all tests */
4621+ return (1);
4622+}
4623+
4624+#endif
4625+
4626+/*
4627+ * Local variables:
4628+ * tab-width: 4
4629+ * c-basic-offset: 4
4630+ * End:
4631+ * vim600: sw=4 ts=4 fdm=marker
4632+ * vim<600: sw=4 ts=4
4633+ */
4634diff -Nura php-4.4.4/main/hardening_patch.h hardening-patch-4.4.4-0.4.15/main/hardening_patch.h
4635--- php-4.4.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4636+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:06.000000000 +0200
4637@@ -0,0 +1,46 @@
4638+/*
4639+ +----------------------------------------------------------------------+
4640+ | Hardening Patch for PHP |
4641+ +----------------------------------------------------------------------+
4642+ | Copyright (c) 2004-2005 Stefan Esser |
4643+ +----------------------------------------------------------------------+
4644+ | This source file is subject to version 2.02 of the PHP license, |
4645+ | that is bundled with this package in the file LICENSE, and is |
4646+ | available at through the world-wide-web at |
4647+ | http://www.php.net/license/2_02.txt. |
4648+ | If you did not receive a copy of the PHP license and are unable to |
4649+ | obtain it through the world-wide-web, please send a note to |
4650+ | license@php.net so we can mail you a copy immediately. |
4651+ +----------------------------------------------------------------------+
4652+ | Author: Stefan Esser <sesser@hardened-php.net> |
4653+ +----------------------------------------------------------------------+
4654+ */
4655+
4656+#ifndef HARDENING_PATCH_H
4657+#define HARDENING_PATCH_H
4658+
4659+#include "zend.h"
4660+
4661+#if HARDENING_PATCH
4662+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4663+PHPAPI void hardened_startup();
4664+#define HARDENING_PATCH_VERSION "0.4.15"
4665+
4666+#endif
4667+
4668+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4669+PHPAPI unsigned int php_canary();
4670+#endif
4671+
4672+#if HARDENING_PATCH_INC_PROTECT
4673+PHPAPI int php_is_valid_include(zval *z);
4674+#endif
4675+
4676+#endif /* HARDENING_PATCH_H */
4677+
4678+/*
4679+ * Local variables:
4680+ * tab-width: 4
4681+ * c-basic-offset: 4
4682+ * End:
4683+ */
4684diff -Nura php-4.4.4/main/hardening_patch.m4 hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4
4685--- php-4.4.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4686+++ hardening-patch-4.4.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:30:51.000000000 +0200
4687@@ -0,0 +1,95 @@
4688+dnl
4689+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4690+dnl
4691+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4692+dnl
4693+
4694+AC_ARG_ENABLE(hardening-patch-mm-protect,
4695+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4696+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4697+],[
4698+ DO_HARDENING_PATCH_MM_PROTECT=yes
4699+])
4700+
4701+AC_ARG_ENABLE(hardening-patch-ll-protect,
4702+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4703+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4704+],[
4705+ DO_HARDENING_PATCH_LL_PROTECT=yes
4706+])
4707+
4708+AC_ARG_ENABLE(hardening-patch-inc-protect,
4709+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4710+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4711+],[
4712+ DO_HARDENING_PATCH_INC_PROTECT=yes
4713+])
4714+
4715+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4716+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4717+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4718+],[
4719+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4720+])
4721+
4722+AC_ARG_ENABLE(hardening-patch-hash-protect,
4723+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4724+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4725+],[
4726+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4727+])
4728+
4729+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4730+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4731+
4732+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4733+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4734+
4735+AC_MSG_CHECKING(whether to protect include/require statements)
4736+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4737+
4738+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4739+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4740+
4741+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4742+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4743+
4744+
4745+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4746+
4747+
4748+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4749+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4750+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4751+else
4752+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4753+fi
4754+
4755+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4756+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4757+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4758+else
4759+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4760+fi
4761+
4762+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4763+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4764+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4765+else
4766+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4767+fi
4768+
4769+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4770+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4771+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4772+else
4773+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4774+fi
4775+
4776+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4777+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4778+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4779+else
4780+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4781+fi
4782+
4783diff -Nura php-4.4.4/main/main.c hardening-patch-4.4.4-0.4.15/main/main.c
4784--- php-4.4.4/main/main.c 2006-05-19 00:36:14.000000000 +0200
4785+++ hardening-patch-4.4.4-0.4.15/main/main.c 2006-09-05 20:30:51.000000000 +0200
4786@@ -92,6 +92,10 @@
4787 PHPAPI int core_globals_id;
4788 #endif
4789
4790+#if HARDENING_PATCH
4791+#include "hardened_globals.h"
4792+#endif
4793+
4794 #define ERROR_BUF_LEN 1024
4795
4796 typedef struct {
4797@@ -142,17 +146,39 @@
4798 */
4799 static PHP_INI_MH(OnChangeMemoryLimit)
4800 {
4801+#if HARDENING_PATCH
4802+ long hard_memory_limit = 1<<30;
4803+
4804+ if (stage == ZEND_INI_STAGE_RUNTIME) {
4805+ if (HG(hard_memory_limit) == 0) {
4806+ HG(hard_memory_limit) = PG(memory_limit);
4807+ }
4808+ hard_memory_limit = HG(hard_memory_limit);
4809+ } else {
4810+ HG(hard_memory_limit) = 0;
4811+ }
4812+#endif
4813 if (new_value) {
4814 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4815+#if HARDENING_PATCH
4816+ if (PG(memory_limit) > hard_memory_limit) {
4817+ PG(memory_limit) = hard_memory_limit;
4818+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4819+ return FAILURE;
4820+ }
4821+#endif
4822 } else {
4823+#if HARDENING_PATCH
4824+ PG(memory_limit) = hard_memory_limit;
4825+#else
4826 PG(memory_limit) = 1<<30; /* effectively, no limit */
4827+#endif
4828 }
4829 return zend_set_memory_limit(PG(memory_limit));
4830 }
4831 /* }}} */
4832 #endif
4833
4834-
4835 /* {{{ php_disable_functions
4836 */
4837 static void php_disable_functions(TSRMLS_D)
4838@@ -1008,6 +1034,9 @@
4839
4840 zend_try {
4841 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4842+#if HARDENING_PATCH
4843+ hardened_clear_mm_canaries(TSRMLS_C);
4844+#endif
4845 } zend_end_try();
4846
4847 zend_try {
4848@@ -1098,6 +1127,10 @@
4849 tsrm_ls = ts_resource(0);
4850 #endif
4851
4852+#if HARDENING_PATCH
4853+ hardened_startup();
4854+#endif
4855+
4856 sapi_initialize_empty_request(TSRMLS_C);
4857 sapi_activate(TSRMLS_C);
4858
4859@@ -1109,6 +1142,12 @@
4860
4861 php_output_startup();
4862
4863+#if HARDENING_PATCH_INC_PROTECT
4864+ zuf.is_valid_include = php_is_valid_include;
4865+#endif
4866+#if HARDENING_PATCH
4867+ zuf.security_log_function = php_security_log;
4868+#endif
4869 zuf.error_function = php_error_cb;
4870 zuf.printf_function = php_printf;
4871 zuf.write_function = php_body_write_wrapper;
4872@@ -1210,6 +1249,10 @@
4873 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4874 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);
4875 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4876+#if HARDENING_PATCH
4877+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4878+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4879+#endif
4880 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4881 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4882 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4883@@ -1317,7 +1360,7 @@
4884 */
4885 static inline void php_register_server_variables(TSRMLS_D)
4886 {
4887- zval *array_ptr=NULL;
4888+ zval *array_ptr=NULL, *vptr;
4889
4890 ALLOC_ZVAL(array_ptr);
4891 array_init(array_ptr);
4892diff -Nura php-4.4.4/main/php_config.h.in hardening-patch-4.4.4-0.4.15/main/php_config.h.in
4893--- php-4.4.4/main/php_config.h.in 2006-08-15 14:01:21.000000000 +0200
4894+++ hardening-patch-4.4.4-0.4.15/main/php_config.h.in 2006-09-05 20:30:51.000000000 +0200
4895@@ -1,4 +1,4 @@
4896-/* main/php_config.h.in. Generated automatically from configure.in by autoheader. */
4897+/* main/php_config.h.in. Generated automatically from configure.in by autoheader 2.13. */
4898 /* Leave this file alone */
4899 #define ZEND_API
4900 #define ZEND_DLEXPORT
4901@@ -865,6 +865,39 @@
4902 /* Enabling BIND8 compatibility for Panther */
4903 #undef BIND_8_COMPAT
4904
4905+/* Hardening-Patch */
4906+#undef HARDENING_PATCH
4907+
4908+/* Memory Manager Protection */
4909+#undef HARDENING_PATCH_MM_PROTECT
4910+
4911+/* Memory Manager Protection */
4912+#undef HARDENING_PATCH_MM_PROTECT
4913+
4914+/* Linked List Protection */
4915+#undef HARDENING_PATCH_LL_PROTECT
4916+
4917+/* Linked List Protection */
4918+#undef HARDENING_PATCH_LL_PROTECT
4919+
4920+/* Include/Require Protection */
4921+#undef HARDENING_PATCH_INC_PROTECT
4922+
4923+/* Include/Require Protection */
4924+#undef HARDENING_PATCH_INC_PROTECT
4925+
4926+/* Fmt String Protection */
4927+#undef HARDENING_PATCH_FMT_PROTECT
4928+
4929+/* Fmt String Protection */
4930+#undef HARDENING_PATCH_FMT_PROTECT
4931+
4932+/* HashTable DTOR Protection */
4933+#undef HARDENING_PATCH_HASH_PROTECT
4934+
4935+/* HashTable DTOR Protection */
4936+#undef HARDENING_PATCH_HASH_PROTECT
4937+
4938 /* Whether you have AOLserver */
4939 #undef HAVE_AOLSERVER
4940
4941@@ -1148,6 +1181,12 @@
4942 /* Define if you have the getaddrinfo function */
4943 #undef HAVE_GETADDRINFO
4944
4945+/* Whether realpath is broken */
4946+#undef PHP_BROKEN_REALPATH
4947+
4948+/* Whether realpath is broken */
4949+#undef PHP_BROKEN_REALPATH
4950+
4951 /* Whether system headers declare timezone */
4952 #undef HAVE_DECLARED_TIMEZONE
4953
4954diff -Nura php-4.4.4/main/php_content_types.c hardening-patch-4.4.4-0.4.15/main/php_content_types.c
4955--- php-4.4.4/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100
4956+++ hardening-patch-4.4.4-0.4.15/main/php_content_types.c 2006-09-05 20:30:51.000000000 +0200
4957@@ -77,6 +77,7 @@
4958 sapi_register_post_entries(php_post_entries);
4959 sapi_register_default_post_reader(php_default_post_reader);
4960 sapi_register_treat_data(php_default_treat_data);
4961+ sapi_register_input_filter(php_default_input_filter);
4962 return SUCCESS;
4963 }
4964 /* }}} */
4965diff -Nura php-4.4.4/main/php.h hardening-patch-4.4.4-0.4.15/main/php.h
4966--- php-4.4.4/main/php.h 2006-01-01 14:46:59.000000000 +0100
4967+++ hardening-patch-4.4.4-0.4.15/main/php.h 2006-09-05 20:30:51.000000000 +0200
4968@@ -35,11 +35,19 @@
4969 #include "zend_qsort.h"
4970 #include "php_compat.h"
4971
4972+
4973 #include "zend_API.h"
4974
4975 #undef sprintf
4976 #define sprintf php_sprintf
4977
4978+#if HARDENING_PATCH
4979+#if HAVE_REALPATH
4980+#undef realpath
4981+#define realpath php_realpath
4982+#endif
4983+#endif
4984+
4985 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4986 #undef PHP_DEBUG
4987 #define PHP_DEBUG ZEND_DEBUG
4988@@ -409,6 +417,10 @@
4989 #endif
4990 #endif /* !XtOffsetOf */
4991
4992+#if HARDENING_PATCH
4993+#include "hardening_patch.h"
4994+#endif
4995+
4996 #endif
4997
4998 /*
4999diff -Nura php-4.4.4/main/php_variables.c hardening-patch-4.4.4-0.4.15/main/php_variables.c
5000--- php-4.4.4/main/php_variables.c 2006-02-13 13:19:10.000000000 +0100
5001+++ hardening-patch-4.4.4-0.4.15/main/php_variables.c 2006-09-05 20:30:51.000000000 +0200
5002@@ -238,17 +238,28 @@
5003 while (var) {
5004 val = strchr(var, '=');
5005 if (val) { /* have a value */
5006- int val_len;
5007+ unsigned int val_len, new_val_len;
5008
5009 *val++ = '\0';
5010 php_url_decode(var, strlen(var));
5011 val_len = php_url_decode(val, strlen(val));
5012- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5013+ val = estrndup(val, val_len);
5014+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5015+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5016+ }
5017+ efree(val);
5018 }
5019 var = php_strtok_r(NULL, "&", &strtok_buf);
5020 }
5021 }
5022
5023+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
5024+{
5025+ /* TODO: check .ini setting here and apply user-defined input filter */
5026+ *new_val_len = val_len;
5027+ return 1;
5028+}
5029+
5030 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
5031 {
5032 char *res = NULL, *var, *val, *separator=NULL;
5033@@ -326,15 +337,26 @@
5034 while (var) {
5035 val = strchr(var, '=');
5036 if (val) { /* have a value */
5037- int val_len;
5038+ unsigned int val_len, new_val_len;
5039
5040 *val++ = '\0';
5041 php_url_decode(var, strlen(var));
5042 val_len = php_url_decode(val, strlen(val));
5043- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5044+ val = estrndup(val, val_len);
5045+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5046+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5047+ }
5048+ efree(val);
5049 } else {
5050+ unsigned int val_len, new_val_len;
5051+
5052 php_url_decode(var, strlen(var));
5053- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
5054+ val_len = 0;
5055+ val = estrndup("", 0);
5056+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5057+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5058+ }
5059+ efree(val);
5060 }
5061 var = php_strtok_r(NULL, separator, &strtok_buf);
5062 }
5063diff -Nura php-4.4.4/main/rfc1867.c hardening-patch-4.4.4-0.4.15/main/rfc1867.c
5064--- php-4.4.4/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100
5065+++ hardening-patch-4.4.4-0.4.15/main/rfc1867.c 2006-09-05 20:30:51.000000000 +0200
5066@@ -128,6 +128,8 @@
5067 #define UPLOAD_ERROR_D 4 /* No file uploaded */
5068 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
5069 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
5070+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
5071+
5072
5073 void php_rfc1867_register_constants(TSRMLS_D)
5074 {
5075@@ -138,6 +140,7 @@
5076 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
5077 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
5078 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
5079+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
5080 }
5081
5082 static void normalize_protected_variable(char *varname TSRMLS_DC)
5083@@ -849,6 +852,7 @@
5084 char buff[FILLUNIT];
5085 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
5086 int blen=0, wlen=0;
5087+ unsigned long offset;
5088
5089 zend_llist_clean(&header);
5090
5091@@ -897,21 +901,24 @@
5092 if (!filename && param) {
5093
5094 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
5095+ unsigned int new_val_len; /* Dummy variable */
5096
5097 if (!value) {
5098 value = estrdup("");
5099 }
5100
5101+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
5102 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
5103- if (php_mb_encoding_translation(TSRMLS_C)) {
5104- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5105- &num_vars, &num_vars_max TSRMLS_CC);
5106- } else {
5107- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5108- }
5109+ if (php_mb_encoding_translation(TSRMLS_C)) {
5110+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5111+ &num_vars, &num_vars_max TSRMLS_CC);
5112+ } else {
5113+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5114+ }
5115 #else
5116- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5117+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5118 #endif
5119+ }
5120 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
5121 max_file_size = atol(value);
5122 }
5123@@ -963,7 +970,11 @@
5124 tmp++;
5125 }
5126 }
5127-
5128+
5129+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
5130+ skip_upload = 1;
5131+ }
5132+
5133 total_bytes = cancel_upload = 0;
5134
5135 if (!skip_upload) {
5136@@ -987,6 +998,11 @@
5137 cancel_upload = UPLOAD_ERROR_D;
5138 }
5139
5140+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
5141+ cancel_upload = UPLOAD_ERROR_X;
5142+ }
5143+
5144+ offset = 0;
5145 end = 0;
5146 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
5147 {
5148@@ -997,6 +1013,11 @@
5149 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
5150 cancel_upload = UPLOAD_ERROR_B;
5151 } else if (blen > 0) {
5152+
5153+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
5154+ cancel_upload = UPLOAD_ERROR_X;
5155+ }
5156+
5157 wlen = write(fd, buff, blen);
5158
5159 if (wlen < blen) {
5160@@ -1004,6 +1025,7 @@
5161 cancel_upload = UPLOAD_ERROR_F;
5162 } else {
5163 total_bytes += wlen;
5164+ offset += wlen;
5165 }
5166 }
5167 }
5168@@ -1025,6 +1047,10 @@
5169 }
5170 #endif
5171
5172+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5173+ cancel_upload = UPLOAD_ERROR_X;
5174+ }
5175+
5176 if (cancel_upload) {
5177 if (temp_filename) {
5178 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5179diff -Nura php-4.4.4/main/SAPI.c hardening-patch-4.4.4-0.4.15/main/SAPI.c
5180--- php-4.4.4/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100
5181+++ hardening-patch-4.4.4-0.4.15/main/SAPI.c 2006-09-05 20:30:51.000000000 +0200
5182@@ -854,6 +854,37 @@
5183 return SUCCESS;
5184 }
5185
5186+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))
5187+{
5188+ sapi_module.input_filter = input_filter;
5189+ return SUCCESS;
5190+}
5191+
5192+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5193+{
5194+ sapi_module.upload_varname_filter = upload_varname_filter;
5195+ return SUCCESS;
5196+}
5197+
5198+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5199+{
5200+ sapi_module.pre_upload_filter = pre_upload_filter;
5201+ return SUCCESS;
5202+}
5203+
5204+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))
5205+{
5206+ sapi_module.upload_content_filter = upload_content_filter;
5207+ return SUCCESS;
5208+}
5209+
5210+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5211+{
5212+ sapi_module.post_upload_filter = post_upload_filter;
5213+ return SUCCESS;
5214+}
5215+
5216+
5217
5218 SAPI_API int sapi_flush(TSRMLS_D)
5219 {
5220diff -Nura php-4.4.4/main/SAPI.h hardening-patch-4.4.4-0.4.15/main/SAPI.h
5221--- php-4.4.4/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100
5222+++ hardening-patch-4.4.4-0.4.15/main/SAPI.h 2006-09-05 20:30:51.000000000 +0200
5223@@ -101,9 +101,10 @@
5224 char *current_user;
5225 int current_user_length;
5226
5227- /* this is necessary for CLI module */
5228- int argc;
5229- char **argv;
5230+ /* this is necessary for CLI module */
5231+ int argc;
5232+ char **argv;
5233+
5234 } sapi_request_info;
5235
5236
5237@@ -177,6 +178,10 @@
5238 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5239 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5240 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5241+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));
5242+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5243+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));
5244+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5245
5246 SAPI_API int sapi_flush(TSRMLS_D);
5247 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5248@@ -238,8 +243,16 @@
5249 int (*get_target_uid)(uid_t * TSRMLS_DC);
5250 int (*get_target_gid)(gid_t * TSRMLS_DC);
5251
5252+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5253+
5254+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5255+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5256+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5257+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5258+
5259 void (*ini_defaults)(HashTable *configuration_hash);
5260 int phpinfo_as_text;
5261+
5262 };
5263
5264
5265@@ -262,16 +275,27 @@
5266
5267 #define SAPI_DEFAULT_MIMETYPE "text/html"
5268 #define SAPI_DEFAULT_CHARSET ""
5269+
5270+#if HARDENING_PATCH
5271+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5272+#else
5273 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5274+#endif
5275
5276 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5277 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5278
5279 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5280+#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)
5281+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5282+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5283+#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)
5284+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5285
5286 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5287 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5288 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5289+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5290
5291 #define STANDARD_SAPI_MODULE_PROPERTIES
5292
5293diff -Nura php-4.4.4/main/snprintf.c hardening-patch-4.4.4-0.4.15/main/snprintf.c
5294--- php-4.4.4/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100
5295+++ hardening-patch-4.4.4-0.4.15/main/snprintf.c 2006-09-05 20:30:51.000000000 +0200
5296@@ -1014,7 +1014,11 @@
5297
5298
5299 case 'n':
5300+#if HARDENING_PATCH_FMT_PROTECT
5301+ php_security_log(S_MISC, "'n' specifier within format string");
5302+#else
5303 *(va_arg(ap, int *)) = cc;
5304+#endif
5305 break;
5306
5307 /*
5308diff -Nura php-4.4.4/main/spprintf.c hardening-patch-4.4.4-0.4.15/main/spprintf.c
5309--- php-4.4.4/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100
5310+++ hardening-patch-4.4.4-0.4.15/main/spprintf.c 2006-09-05 20:30:51.000000000 +0200
5311@@ -630,7 +630,11 @@
5312
5313
5314 case 'n':
5315+#if HARDENING_PATCH_FMT_PROTECT
5316+ php_security_log(S_MISC, "'n' specifier within format string");
5317+#else
5318 *(va_arg(ap, int *)) = xbuf->len;
5319+#endif
5320 break;
5321
5322 /*
5323diff -Nura php-4.4.4/php.ini-dist hardening-patch-4.4.4-0.4.15/php.ini-dist
5324--- php-4.4.4/php.ini-dist 2005-12-30 18:19:43.000000000 +0100
5325+++ hardening-patch-4.4.4-0.4.15/php.ini-dist 2006-09-05 20:30:51.000000000 +0200
5326@@ -1114,6 +1114,209 @@
5327 ;exif.decode_jis_motorola = JIS
5328 ;exif.decode_jis_intel = JIS
5329
5330+[hardening-patch]
5331+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5332+; Hardening-Patch's logging ;
5333+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5334+
5335+;
5336+; hphp.log.syslog - Configures level for alerts reported through syslog
5337+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5338+; hphp.log.script - Configures level for alerts reported through external script
5339+;
5340+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5341+; Or each number up to get desired Hardening-Patch's reporting level
5342+;
5343+; S_ALL - All alerts
5344+; S_MEMORY - All canary violations and the safe unlink protection use this class
5345+; S_VARS - All variable filters trigger this class
5346+; S_FILES - All violation of uploaded files filter use this class
5347+; S_INCLUDE - The protection against malicious include filenames use this class
5348+; S_SQL - Failed SQL queries in MySQL are logged with this class
5349+; S_EXECUTOR - The execution depth protection uses this logging class
5350+; S_MISC - All other log messages (f.e. format string protection) use this class
5351+;
5352+; Example:
5353+;
5354+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5355+; memory alerts through syslog and SQL+Include alerts fo the script
5356+;
5357+;hphp.log.syslog = S_MEMORY
5358+;hphp.log.sapi = S_ALL & ~S_MEMORY
5359+;hphp.log.script = S_INCLUDE | S_SQL
5360+;
5361+; Syslog logging:
5362+;
5363+; - Facility configuration: one of the following facilities
5364+;
5365+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5366+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5367+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5368+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5369+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5370+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5371+; LOG_PERROR
5372+;
5373+; - Priority configuration: one of the followinf priorities
5374+;
5375+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5376+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5377+;
5378+hphp.log.syslog.priority = LOG_ALERT
5379+hphp.log.syslog.facility = LOG_USER
5380+;
5381+; Script logging:
5382+;
5383+;hphp.log.script.name = /home/hphp/log_script
5384+;
5385+; Alert configuration:
5386+;
5387+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5388+;
5389+;hphp.log.use-x-forwarded-for = On
5390+;
5391+
5392+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5393+; Hardening-Patch's Executor options ;
5394+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5395+
5396+; Execution depth limit
5397+;hphp.executor.max_depth = 8000
5398+
5399+; White-/blacklist for function calls during normal execution
5400+;hphp.executor.func.whitelist = ord,chr
5401+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5402+
5403+; White-/blacklist for function calls during eval() execution
5404+;hphp.executor.eval.whitelist = ord,chr
5405+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5406+
5407+; White-/blacklist for URLs allowes in include filenames
5408+;
5409+; - When both options are not set all URLs are forbidden
5410+;
5411+; - When both options are set whitelist is taken and blacklist ignored
5412+;
5413+; - An entry in the lists is either a URL sheme like: http, https
5414+; or the beginning of an URL like: php://input
5415+;
5416+;hphp.executor.include.whitelist = cookietest
5417+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5418+
5419+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5420+; Hardening-Patch's REQUEST variable filters ;
5421+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5422+
5423+; Limits the number of REQUEST variables
5424+hphp.request.max_vars = 200
5425+
5426+; Limits the length of variable names (without indices)
5427+hphp.request.max_varname_length = 64
5428+
5429+; Limits the length of complete variable names (with indices)
5430+hphp.request.max_totalname_length = 256
5431+
5432+; Limits the length of array indices
5433+hphp.request.max_array_index_length = 64
5434+
5435+; Limits the depth of arrays
5436+hphp.request.max_array_depth = 100
5437+
5438+; Limits the length of variable values
5439+hphp.request.max_value_length = 65000
5440+
5441+; Disallow ASCII-NUL characters in input
5442+hphp.request.disallow_nul = 1
5443+
5444+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5445+; Hardening-Patch's COOKIE variable filters ;
5446+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5447+
5448+; Limits the number of COOKIE variables
5449+hphp.cookie.max_vars = 100
5450+
5451+; Limits the length of variable names (without indices)
5452+hphp.cookie.max_name_length = 64
5453+
5454+; Limits the length of complete variable names (with indices)
5455+hphp.cookie.max_totalname_length = 256
5456+
5457+; Limits the length of array indices
5458+hphp.cookie.max_array_index_length = 64
5459+
5460+; Limits the depth of arrays
5461+hphp.cookie.max_array_depth = 100
5462+
5463+; Limits the length of variable values
5464+hphp.cookie.max_value_length = 10000
5465+
5466+; Disallow ASCII-NUL characters in input
5467+hphp.cookie.disallow_nul = 1
5468+
5469+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5470+; Hardening-Patch's GET variable filters ;
5471+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5472+
5473+; Limits the number of COOKIE variables
5474+hphp.get.max_vars = 100
5475+
5476+; Limits the length of variable names (without indices)
5477+hphp.get.max_name_length = 64
5478+
5479+; Limits the length of complete variable names (with indices)
5480+hphp.get.max_totalname_length = 256
5481+
5482+; Limits the length of array indices
5483+hphp.get.max_array_index_length = 64
5484+
5485+; Limits the depth of arrays
5486+hphp.get.max_array_depth = 50
5487+
5488+; Limits the length of variable values
5489+hphp.get.max_value_length = 512
5490+
5491+; Disallow ASCII-NUL characters in input
5492+hphp.get.disallow_nul = 1
5493+
5494+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5495+; Hardening-Patch's POST variable filters ;
5496+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5497+
5498+; Limits the number of POST variables
5499+hphp.post.max_vars = 200
5500+
5501+; Limits the length of variable names (without indices)
5502+hphp.post.max_name_length = 64
5503+
5504+; Limits the length of complete variable names (with indices)
5505+hphp.post.max_totalname_length = 256
5506+
5507+; Limits the length of array indices
5508+hphp.post.max_array_index_length = 64
5509+
5510+; Limits the depth of arrays
5511+hphp.post.max_array_depth = 100
5512+
5513+; Limits the length of variable values
5514+hphp.post.max_value_length = 65000
5515+
5516+; Disallow ASCII-NUL characters in input
5517+hphp.post.disallow_nul = 1
5518+
5519+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5520+; Hardening-Patch's fileupload variable filters ;
5521+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5522+
5523+; Limits the number of uploadable files
5524+hphp.upload.max_uploads = 25
5525+
5526+; Filter out the upload of ELF executables
5527+hphp.upload.disallow_elf_files = On
5528+
5529+; External filterscript for upload verification
5530+;hphp.upload.verification_script = /home/hphp/verify_script
5531+
5532+
5533 ; Local Variables:
5534 ; tab-width: 4
5535 ; End:
5536diff -Nura php-4.4.4/php.ini-recommended hardening-patch-4.4.4-0.4.15/php.ini-recommended
5537--- php-4.4.4/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100
5538+++ hardening-patch-4.4.4-0.4.15/php.ini-recommended 2006-09-05 20:30:51.000000000 +0200
5539@@ -1112,6 +1112,209 @@
5540 ;exif.decode_jis_motorola = JIS
5541 ;exif.decode_jis_intel = JIS
5542
5543+[hardening-patch]
5544+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5545+; Hardening-Patch's logging ;
5546+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5547+
5548+;
5549+; hphp.log.syslog - Configures level for alerts reported through syslog
5550+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5551+; hphp.log.script - Configures level for alerts reported through external script
5552+;
5553+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5554+; Or each number up to get desired Hardening-Patch's reporting level
5555+;
5556+; S_ALL - All alerts
5557+; S_MEMORY - All canary violations and the safe unlink protection use this class
5558+; S_VARS - All variable filters trigger this class
5559+; S_FILES - All violation of uploaded files filter use this class
5560+; S_INCLUDE - The protection against malicious include filenames use this class
5561+; S_SQL - Failed SQL queries in MySQL are logged with this class
5562+; S_EXECUTOR - The execution depth protection uses this logging class
5563+; S_MISC - All other log messages (f.e. format string protection) use this class
5564+;
5565+; Example:
5566+;
5567+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5568+; memory alerts through syslog and SQL+Include alerts fo the script
5569+;
5570+;hphp.log.syslog = S_MEMORY
5571+;hphp.log.sapi = S_ALL & ~S_MEMORY
5572+;hphp.log.script = S_INCLUDE | S_SQL
5573+;
5574+; Syslog logging:
5575+;
5576+; - Facility configuration: one of the following facilities
5577+;
5578+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5579+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5580+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5581+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5582+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5583+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5584+; LOG_PERROR
5585+;
5586+; - Priority configuration: one of the followinf priorities
5587+;
5588+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5589+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5590+;
5591+hphp.log.syslog.priority = LOG_ALERT
5592+hphp.log.syslog.facility = LOG_USER
5593+;
5594+; Script logging:
5595+;
5596+;hphp.log.script.name = /home/hphp/log_script
5597+;
5598+; Alert configuration:
5599+;
5600+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5601+;
5602+;hphp.log.use-x-forwarded-for = On
5603+;
5604+
5605+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5606+; Hardening-Patch's Executor options ;
5607+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5608+
5609+; Execution depth limit
5610+;hphp.executor.max_depth = 8000
5611+
5612+; White-/blacklist for function calls during normal execution
5613+;hphp.executor.func.whitelist = ord,chr
5614+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5615+
5616+; White-/blacklist for function calls during eval() execution
5617+;hphp.executor.eval.whitelist = ord,chr
5618+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5619+
5620+; White-/blacklist for URLs allowes in include filenames
5621+;
5622+; - When both options are not set all URLs are forbidden
5623+;
5624+; - When both options are set whitelist is taken and blacklist ignored
5625+;
5626+; - An entry in the lists is either a URL sheme like: http, https
5627+; or the beginning of an URL like: php://input
5628+;
5629+;hphp.executor.include.whitelist = cookietest
5630+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5631+
5632+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5633+; Hardening-Patch's REQUEST variable filters ;
5634+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5635+
5636+; Limits the number of REQUEST variables
5637+hphp.request.max_vars = 200
5638+
5639+; Limits the length of variable names (without indices)
5640+hphp.request.max_varname_length = 64
5641+
5642+; Limits the length of complete variable names (with indices)
5643+hphp.request.max_totalname_length = 256
5644+
5645+; Limits the length of array indices
5646+hphp.request.max_array_index_length = 64
5647+
5648+; Limits the depth of arrays
5649+hphp.request.max_array_depth = 100
5650+
5651+; Limits the length of variable values
5652+hphp.request.max_value_length = 65000
5653+
5654+; Disallow ASCII-NUL characters in input
5655+hphp.request.disallow_nul = 1
5656+
5657+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5658+; Hardening-Patch's COOKIE variable filters ;
5659+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5660+
5661+; Limits the number of COOKIE variables
5662+hphp.cookie.max_vars = 100
5663+
5664+; Limits the length of variable names (without indices)
5665+hphp.cookie.max_name_length = 64
5666+
5667+; Limits the length of complete variable names (with indices)
5668+hphp.cookie.max_totalname_length = 256
5669+
5670+; Limits the length of array indices
5671+hphp.cookie.max_array_index_length = 64
5672+
5673+; Limits the depth of arrays
5674+hphp.cookie.max_array_depth = 100
5675+
5676+; Limits the length of variable values
5677+hphp.cookie.max_value_length = 10000
5678+
5679+; Disallow ASCII-NUL characters in input
5680+hphp.cookie.disallow_nul = 1
5681+
5682+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5683+; Hardening-Patch's GET variable filters ;
5684+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5685+
5686+; Limits the number of COOKIE variables
5687+hphp.get.max_vars = 100
5688+
5689+; Limits the length of variable names (without indices)
5690+hphp.get.max_name_length = 64
5691+
5692+; Limits the length of complete variable names (with indices)
5693+hphp.get.max_totalname_length = 256
5694+
5695+; Limits the length of array indices
5696+hphp.get.max_array_index_length = 64
5697+
5698+; Limits the depth of arrays
5699+hphp.get.max_array_depth = 50
5700+
5701+; Limits the length of variable values
5702+hphp.get.max_value_length = 512
5703+
5704+; Disallow ASCII-NUL characters in input
5705+hphp.get.disallow_nul = 1
5706+
5707+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5708+; Hardening-Patch's POST variable filters ;
5709+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5710+
5711+; Limits the number of POST variables
5712+hphp.post.max_vars = 200
5713+
5714+; Limits the length of variable names (without indices)
5715+hphp.post.max_name_length = 64
5716+
5717+; Limits the length of complete variable names (with indices)
5718+hphp.post.max_totalname_length = 256
5719+
5720+; Limits the length of array indices
5721+hphp.post.max_array_index_length = 64
5722+
5723+; Limits the depth of arrays
5724+hphp.post.max_array_depth = 100
5725+
5726+; Limits the length of variable values
5727+hphp.post.max_value_length = 65000
5728+
5729+; Disallow ASCII-NUL characters in input
5730+hphp.post.disallow_nul = 1
5731+
5732+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5733+; Hardening-Patch's fileupload variable filters ;
5734+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5735+
5736+; Limits the number of uploadable files
5737+hphp.upload.max_uploads = 25
5738+
5739+; Filter out the upload of ELF executables
5740+hphp.upload.disallow_elf_files = On
5741+
5742+; External filterscript for upload verification
5743+;hphp.upload.verification_script = /home/hphp/verify_script
5744+
5745+
5746 ; Local Variables:
5747 ; tab-width: 4
5748 ; End:
5749diff -Nura php-4.4.4/README.input_filter hardening-patch-4.4.4-0.4.15/README.input_filter
5750--- php-4.4.4/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5751+++ hardening-patch-4.4.4-0.4.15/README.input_filter 2006-09-05 20:30:51.000000000 +0200
5752@@ -0,0 +1,193 @@
5753+Input Filter Support ported from PHP 5
5754+--------------------------------------
5755+
5756+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5757+and can be quite difficult to prevent. Whenever you accept user data
5758+and somehow display this data back to users, you are likely vulnerable
5759+to XSS hacks.
5760+
5761+The Input Filter support in PHP 5 is aimed at providing the framework
5762+through which a company-wide or site-wide security policy can be
5763+enforced. It is implemented as a SAPI hook and is called from the
5764+treat_data and post handler functions. To implement your own security
5765+policy you will need to write a standard PHP extension.
5766+
5767+A simple implementation might look like the following. This stores the
5768+original raw user data and adds a my_get_raw() function while the normal
5769+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5770+data. In this simple example all I am doing is calling strip_tags() on
5771+the data. If register_globals is turned on, the default globals that
5772+are created will be stripped ($foo) while a $RAW_foo is created with the
5773+original user input.
5774+
5775+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5776+ zval *post_array;
5777+ zval *get_array;
5778+ zval *cookie_array;
5779+ZEND_END_MODULE_GLOBALS(my_input_filter)
5780+
5781+#ifdef ZTS
5782+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5783+#else
5784+#define IF_G(v) (my_input_filter_globals.v)
5785+#endif
5786+
5787+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5788+
5789+function_entry my_input_filter_functions[] = {
5790+ PHP_FE(my_get_raw, NULL)
5791+ {NULL, NULL, NULL}
5792+};
5793+
5794+zend_module_entry my_input_filter_module_entry = {
5795+ STANDARD_MODULE_HEADER,
5796+ "my_input_filter",
5797+ my_input_filter_functions,
5798+ PHP_MINIT(my_input_filter),
5799+ PHP_MSHUTDOWN(my_input_filter),
5800+ NULL,
5801+ PHP_RSHUTDOWN(my_input_filter),
5802+ PHP_MINFO(my_input_filter),
5803+ "0.1",
5804+ STANDARD_MODULE_PROPERTIES
5805+};
5806+
5807+PHP_MINIT_FUNCTION(my_input_filter)
5808+{
5809+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5810+
5811+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5812+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5813+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5814+
5815+ sapi_register_input_filter(my_sapi_input_filter);
5816+ return SUCCESS;
5817+}
5818+
5819+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5820+{
5821+ if(IF_G(get_array)) {
5822+ zval_ptr_dtor(&IF_G(get_array));
5823+ IF_G(get_array) = NULL;
5824+ }
5825+ if(IF_G(post_array)) {
5826+ zval_ptr_dtor(&IF_G(post_array));
5827+ IF_G(post_array) = NULL;
5828+ }
5829+ if(IF_G(cookie_array)) {
5830+ zval_ptr_dtor(&IF_G(cookie_array));
5831+ IF_G(cookie_array) = NULL;
5832+ }
5833+ return SUCCESS;
5834+}
5835+
5836+PHP_MINFO_FUNCTION(my_input_filter)
5837+{
5838+ php_info_print_table_start();
5839+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5840+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5841+ php_info_print_table_end();
5842+}
5843+
5844+/* The filter handler. If you return 1 from it, then PHP also registers the
5845+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5846+ * you can use this if your filter already registers the variable under a
5847+ * different name, or if you just don't want the variable registered at all. */
5848+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5849+{
5850+ zval new_var;
5851+ zval *array_ptr = NULL;
5852+ char *raw_var;
5853+ int var_len;
5854+
5855+ assert(*val != NULL);
5856+
5857+ switch(arg) {
5858+ case PARSE_GET:
5859+ if(!IF_G(get_array)) {
5860+ ALLOC_ZVAL(array_ptr);
5861+ array_init(array_ptr);
5862+ INIT_PZVAL(array_ptr);
5863+ }
5864+ IF_G(get_array) = array_ptr;
5865+ break;
5866+ case PARSE_POST:
5867+ if(!IF_G(post_array)) {
5868+ ALLOC_ZVAL(array_ptr);
5869+ array_init(array_ptr);
5870+ INIT_PZVAL(array_ptr);
5871+ }
5872+ IF_G(post_array) = array_ptr;
5873+ break;
5874+ case PARSE_COOKIE:
5875+ if(!IF_G(cookie_array)) {
5876+ ALLOC_ZVAL(array_ptr);
5877+ array_init(array_ptr);
5878+ INIT_PZVAL(array_ptr);
5879+ }
5880+ IF_G(cookie_array) = array_ptr;
5881+ break;
5882+ }
5883+ Z_STRLEN(new_var) = val_len;
5884+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5885+ Z_TYPE(new_var) = IS_STRING;
5886+
5887+ var_len = strlen(var);
5888+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5889+ strcpy(raw_var, "RAW_");
5890+ strlcat(raw_var,var,var_len+5);
5891+
5892+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5893+
5894+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5895+
5896+ *new_val_len = strlen(*val);
5897+ return 1;
5898+}
5899+
5900+PHP_FUNCTION(my_get_raw)
5901+{
5902+ long arg;
5903+ char *var;
5904+ int var_len;
5905+ zval **tmp;
5906+ zval *array_ptr = NULL;
5907+ HashTable *hash_ptr;
5908+ char *raw_var;
5909+
5910+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
5911+ return;
5912+ }
5913+
5914+ switch(arg) {
5915+ case PARSE_GET:
5916+ array_ptr = IF_G(get_array);
5917+ break;
5918+ case PARSE_POST:
5919+ array_ptr = IF_G(post_array);
5920+ break;
5921+ case PARSE_COOKIE:
5922+ array_ptr = IF_G(post_array);
5923+ break;
5924+ }
5925+
5926+ if(!array_ptr) RETURN_FALSE;
5927+
5928+ /*
5929+ * I'm changing the variable name here because when running with register_globals on,
5930+ * the variable will end up in the global symbol table
5931+ */
5932+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5933+ strcpy(raw_var, "RAW_");
5934+ strlcat(raw_var,var,var_len+5);
5935+ hash_ptr = HASH_OF(array_ptr);
5936+
5937+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
5938+ *return_value = **tmp;
5939+ zval_copy_ctor(return_value);
5940+ } else {
5941+ RETVAL_FALSE;
5942+ }
5943+ efree(raw_var);
5944+}
5945+
5946diff -Nura php-4.4.4/run-tests.php hardening-patch-4.4.4-0.4.15/run-tests.php
5947--- php-4.4.4/run-tests.php 2006-01-18 18:59:41.000000000 +0100
5948+++ hardening-patch-4.4.4-0.4.15/run-tests.php 2006-09-05 20:30:51.000000000 +0200
5949@@ -152,6 +152,10 @@
5950 'error_reporting=2047',
5951 'display_errors=1',
5952 'log_errors=0',
5953+ 'hphp.executor.include.whitelist=cookietest',
5954+ 'hphp.log.syslog=0',
5955+ 'hphp.log.sapi=0',
5956+ 'hphp.log.script=0',
5957 'html_errors=0',
5958 'track_errors=1',
5959 'report_memleaks=1',
5960diff -Nura php-4.4.4/sapi/apache/mod_php4.c hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c
5961--- php-4.4.4/sapi/apache/mod_php4.c 2006-05-13 23:42:14.000000000 +0200
5962+++ hardening-patch-4.4.4-0.4.15/sapi/apache/mod_php4.c 2006-09-05 20:30:51.000000000 +0200
5963@@ -451,7 +451,7 @@
5964 sapi_apache_get_fd,
5965 sapi_apache_force_http_10,
5966 sapi_apache_get_target_uid,
5967- sapi_apache_get_target_gid
5968+ sapi_apache_get_target_gid,
5969 };
5970 /* }}} */
5971
5972@@ -897,7 +897,11 @@
5973 {
5974 TSRMLS_FETCH();
5975 if (PG(expose_php)) {
5976+#if HARDENING_PATCH
5977+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5978+#else
5979 ap_add_version_component("PHP/" PHP_VERSION);
5980+#endif
5981 }
5982 }
5983 #endif
5984diff -Nura php-4.4.4/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c
5985--- php-4.4.4/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
5986+++ hardening-patch-4.4.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200
5987@@ -562,7 +562,11 @@
5988 {
5989 TSRMLS_FETCH();
5990 if (PG(expose_php)) {
5991+#if HARDENING_PATCH
5992+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5993+#else
5994 ap_add_version_component(p, "PHP/" PHP_VERSION);
5995+#endif
5996 }
5997 }
5998
5999diff -Nura php-4.4.4/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c
6000--- php-4.4.4/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6001+++ hardening-patch-4.4.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:30:51.000000000 +0200
6002@@ -340,7 +340,11 @@
6003 {
6004 TSRMLS_FETCH();
6005 if (PG(expose_php)) {
6006+#if HARDENING_PATCH
6007+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6008+#else
6009 ap_add_version_component(p, "PHP/" PHP_VERSION);
6010+#endif
6011 }
6012 }
6013
6014diff -Nura php-4.4.4/sapi/cgi/cgi_main.c hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c
6015--- php-4.4.4/sapi/cgi/cgi_main.c 2006-02-22 16:11:53.000000000 +0100
6016+++ hardening-patch-4.4.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:30:51.000000000 +0200
6017@@ -1435,11 +1435,19 @@
6018 SG(headers_sent) = 1;
6019 SG(request_info).no_headers = 1;
6020 }
6021+#if HARDENING_PATCH
6022+#if ZEND_DEBUG
6023+ 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());
6024+#else
6025+ 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());
6026+#endif
6027+#else
6028 #if ZEND_DEBUG
6029 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());
6030 #else
6031 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());
6032 #endif
6033+#endif
6034 php_end_ob_buffers(1 TSRMLS_CC);
6035 exit(0);
6036 break;
6037diff -Nura php-4.4.4/sapi/cli/php_cli.c hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c
6038--- php-4.4.4/sapi/cli/php_cli.c 2006-05-18 22:33:46.000000000 +0200
6039+++ hardening-patch-4.4.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:30:51.000000000 +0200
6040@@ -656,11 +656,19 @@
6041 if (php_request_startup(TSRMLS_C)==FAILURE) {
6042 goto err;
6043 }
6044+#if HARDENING_PATCH
6045+#if ZEND_DEBUG
6046+ 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());
6047+#else
6048+ 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());
6049+#endif
6050+#else
6051 #if ZEND_DEBUG
6052 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());
6053 #else
6054 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());
6055 #endif
6056+#endif
6057 php_end_ob_buffers(1 TSRMLS_CC);
6058 exit_status=0;
6059 goto out;
6060diff -Nura php-4.4.4/TSRM/TSRM.h hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h
6061--- php-4.4.4/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
6062+++ hardening-patch-4.4.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:30:51.000000000 +0200
6063@@ -33,6 +33,13 @@
6064 # define TSRM_API
6065 #endif
6066
6067+#if HARDENING_PATCH
6068+# if HAVE_REALPATH
6069+# undef realpath
6070+# define realpath php_realpath
6071+# endif
6072+#endif
6073+
6074 /* Only compile multi-threading functions if we're in ZTS mode */
6075 #ifdef ZTS
6076
6077@@ -84,6 +91,7 @@
6078
6079 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
6080
6081+
6082 #ifdef __cplusplus
6083 extern "C" {
6084 #endif
6085diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c
6086--- php-4.4.4/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100
6087+++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:30:51.000000000 +0200
6088@@ -179,6 +179,178 @@
6089 return p;
6090 }
6091
6092+#if HARDENING_PATCH
6093+CWD_API char *php_realpath(const char *path, char *resolved)
6094+{
6095+ struct stat sb;
6096+ char *p, *q, *s;
6097+ size_t left_len, resolved_len;
6098+ unsigned symlinks;
6099+ int serrno, slen;
6100+ int is_dir = 1;
6101+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
6102+
6103+ serrno = errno;
6104+ symlinks = 0;
6105+ if (path[0] == '/') {
6106+ resolved[0] = '/';
6107+ resolved[1] = '\0';
6108+ if (path[1] == '\0')
6109+ return (resolved);
6110+ resolved_len = 1;
6111+ left_len = strlcpy(left, path + 1, sizeof(left));
6112+ } else {
6113+ if (getcwd(resolved, PATH_MAX) == NULL) {
6114+ strlcpy(resolved, ".", PATH_MAX);
6115+ return (NULL);
6116+ }
6117+ resolved_len = strlen(resolved);
6118+ left_len = strlcpy(left, path, sizeof(left));
6119+ }
6120+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
6121+ errno = ENAMETOOLONG;
6122+ return (NULL);
6123+ }
6124+
6125+ /*
6126+ * Iterate over path components in `left'.
6127+ */
6128+ while (left_len != 0) {
6129+ /*
6130+ * Extract the next path component and adjust `left'
6131+ * and its length.
6132+ */
6133+ p = strchr(left, '/');
6134+ s = p ? p : left + left_len;
6135+ if (s - left >= sizeof(next_token)) {
6136+ errno = ENAMETOOLONG;
6137+ return (NULL);
6138+ }
6139+ memcpy(next_token, left, s - left);
6140+ next_token[s - left] = '\0';
6141+ left_len -= s - left;
6142+ if (p != NULL)
6143+ memmove(left, s + 1, left_len + 1);
6144+ if (resolved[resolved_len - 1] != '/') {
6145+ if (resolved_len + 1 >= PATH_MAX) {
6146+ errno = ENAMETOOLONG;
6147+ return (NULL);
6148+ }
6149+ resolved[resolved_len++] = '/';
6150+ resolved[resolved_len] = '\0';
6151+ }
6152+ if (next_token[0] == '\0')
6153+ continue;
6154+ else if (strcmp(next_token, ".") == 0)
6155+ continue;
6156+ else if (strcmp(next_token, "..") == 0) {
6157+ /*
6158+ * Strip the last path component except when we have
6159+ * single "/"
6160+ */
6161+ if (!is_dir) {
6162+ errno = ENOENT;
6163+ return (NULL);
6164+ }
6165+ if (resolved_len > 1) {
6166+ resolved[resolved_len - 1] = '\0';
6167+ q = strrchr(resolved, '/');
6168+ *q = '\0';
6169+ resolved_len = q - resolved;
6170+ }
6171+ continue;
6172+ }
6173+
6174+ /*
6175+ * Append the next path component and lstat() it. If
6176+ * lstat() fails we still can return successfully if
6177+ * there are no more path components left.
6178+ */
6179+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6180+ if (resolved_len >= PATH_MAX) {
6181+ errno = ENAMETOOLONG;
6182+ return (NULL);
6183+ }
6184+ if (lstat(resolved, &sb) != 0) {
6185+ if (errno == ENOENT) {
6186+ if (p == NULL) {
6187+ errno = serrno;
6188+ return (resolved);
6189+ } else
6190+ /* dirty hack to support a vanilla PHP feature */
6191+ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
6192+ resolved_len = strlcat(resolved, "/", PATH_MAX);
6193+ resolved_len = strlcat(resolved, left, PATH_MAX);
6194+ if (resolved_len >= PATH_MAX) {
6195+ errno = ENAMETOOLONG;
6196+ return (NULL);
6197+ }
6198+ errno = serrno;
6199+ return (resolved);
6200+ }
6201+ }
6202+ return (NULL);
6203+ }
6204+ if (S_ISLNK(sb.st_mode)) {
6205+ if (symlinks++ > MAXSYMLINKS) {
6206+ errno = ELOOP;
6207+ return (NULL);
6208+ }
6209+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6210+ if (slen < 0)
6211+ return (NULL);
6212+ symlink[slen] = '\0';
6213+ if (symlink[0] == '/') {
6214+ resolved[1] = 0;
6215+ resolved_len = 1;
6216+ } else if (resolved_len > 1) {
6217+ /* Strip the last path component. */
6218+ resolved[resolved_len - 1] = '\0';
6219+ q = strrchr(resolved, '/');
6220+ *q = '\0';
6221+ resolved_len = q - resolved;
6222+ }
6223+
6224+ /*
6225+ * If there are any path components left, then
6226+ * append them to symlink. The result is placed
6227+ * in `left'.
6228+ */
6229+ if (p != NULL) {
6230+ if (symlink[slen - 1] != '/') {
6231+ if (slen + 1 >= sizeof(symlink)) {
6232+ errno = ENAMETOOLONG;
6233+ return (NULL);
6234+ }
6235+ symlink[slen] = '/';
6236+ symlink[slen + 1] = 0;
6237+ }
6238+ left_len = strlcat(symlink, left, sizeof(left));
6239+ if (left_len >= sizeof(left)) {
6240+ errno = ENAMETOOLONG;
6241+ return (NULL);
6242+ }
6243+ }
6244+ left_len = strlcpy(left, symlink, sizeof(left));
6245+ } else {
6246+ if (S_ISDIR(sb.st_mode)) {
6247+ is_dir = 1;
6248+ } else {
6249+ is_dir = 0;
6250+ }
6251+ }
6252+ }
6253+
6254+ /*
6255+ * Remove trailing slash except when the resolved pathname
6256+ * is a single "/".
6257+ */
6258+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6259+ resolved[resolved_len - 1] = '\0';
6260+ return (resolved);
6261+}
6262+#endif
6263+
6264 CWD_API void virtual_cwd_startup(void)
6265 {
6266 char cwd[MAXPATHLEN];
6267@@ -300,8 +472,11 @@
6268
6269 if (path_length == 0)
6270 return (0);
6271- if (path_length >= MAXPATHLEN)
6272+ if (path_length >= MAXPATHLEN) {
6273+ state->cwd[0] = 0;
6274+ state->cwd_length = 0;
6275 return (1);
6276+ }
6277
6278 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6279 /* cwd_length can be 0 when getcwd() fails.
6280@@ -313,8 +488,9 @@
6281 path = resolved_path;
6282 path_length = strlen(path);
6283 } else {
6284- /* disable for now
6285- return 1; */
6286+ state->cwd[0] = 0;
6287+ state->cwd_length = 0;
6288+ return 1;
6289 }
6290 }
6291 } else { /* Concat current directory with relative path and then run realpath() on it */
6292@@ -323,6 +499,8 @@
6293
6294 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6295 if (!tmp) {
6296+ state->cwd[0] = 0;
6297+ state->cwd_length = 0;
6298 return 1;
6299 }
6300 memcpy(ptr, state->cwd, state->cwd_length);
6301@@ -332,6 +510,8 @@
6302 ptr += path_length;
6303 *ptr = '\0';
6304 if (strlen(tmp) >= MAXPATHLEN) {
6305+ state->cwd[0] = 0;
6306+ state->cwd_length = 0;
6307 free(tmp);
6308 return 1;
6309 }
6310@@ -340,9 +520,10 @@
6311 path = resolved_path;
6312 path_length = strlen(path);
6313 } else {
6314- /* disable for now
6315+ state->cwd[0] = 0;
6316+ state->cwd_length = 0;
6317 free(tmp);
6318- return 1; */
6319+ return 1;
6320 }
6321 }
6322 free(tmp);
6323diff -Nura php-4.4.4/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h
6324--- php-4.4.4/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100
6325+++ hardening-patch-4.4.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:30:51.000000000 +0200
6326@@ -128,6 +128,22 @@
6327
6328 typedef int (*verify_path_func)(const cwd_state *);
6329
6330+#ifndef HAVE_STRLCPY
6331+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6332+#undef strlcpy
6333+#define strlcpy php_strlcpy
6334+#endif
6335+
6336+#ifndef HAVE_STRLCAT
6337+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6338+#undef strlcat
6339+#define strlcat php_strlcat
6340+#endif
6341+
6342+
6343+#if HARDENING_PATCH
6344+CWD_API char *php_realpath(const char *path, char *resolved);
6345+#endif
6346 CWD_API void virtual_cwd_startup(void);
6347 CWD_API void virtual_cwd_shutdown(void);
6348 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6349diff -Nura php-4.4.4/Zend/zend_alloc.c hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c
6350--- php-4.4.4/Zend/zend_alloc.c 2006-08-10 19:27:12.000000000 +0200
6351+++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:30:51.000000000 +0200
6352@@ -56,6 +56,11 @@
6353 # define END_MAGIC_SIZE 0
6354 #endif
6355
6356+#if HARDENING_PATCH_MM_PROTECT
6357+# define CANARY_SIZE sizeof(unsigned int)
6358+#else
6359+# define CANARY_SIZE 0
6360+#endif
6361
6362 # if MEMORY_LIMIT
6363 # if ZEND_DEBUG
6364@@ -104,9 +109,17 @@
6365 if (p==AG(head)) { \
6366 AG(head) = p->pNext; \
6367 } else { \
6368+ if (p != p->pLast->pNext) { \
6369+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6370+ exit(1); \
6371+ } \
6372 p->pLast->pNext = p->pNext; \
6373 } \
6374 if (p->pNext) { \
6375+ if (p != p->pNext->pLast) { \
6376+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6377+ exit(1); \
6378+ } \
6379 p->pNext->pLast = p->pLast; \
6380 }
6381
6382@@ -138,6 +151,12 @@
6383 DECLARE_CACHE_VARS();
6384 TSRMLS_FETCH();
6385
6386+#if HARDENING_PATCH_MM_PROTECT
6387+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6388+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6389+ exit(1);
6390+ }
6391+#endif
6392 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6393
6394 if (size > INT_MAX || SIZE < size) {
6395@@ -159,6 +178,10 @@
6396 AG(cache_stats)[CACHE_INDEX][1]++;
6397 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6398 #endif
6399+#if HARDENING_PATCH_MM_PROTECT
6400+ p->canary = HG(canary_1);
6401+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6402+#endif
6403 p->cached = 0;
6404 p->size = size;
6405 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6406@@ -174,7 +197,7 @@
6407 AG(allocated_memory_peak) = AG(allocated_memory);
6408 }
6409 #endif
6410- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6411+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6412 }
6413
6414 emalloc_error:
6415@@ -206,7 +229,10 @@
6416 # endif
6417 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6418 #endif
6419-
6420+#if HARDENING_PATCH_MM_PROTECT
6421+ p->canary = HG(canary_1);
6422+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6423+#endif
6424 HANDLE_UNBLOCK_INTERRUPTIONS();
6425 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6426 }
6427@@ -233,17 +259,36 @@
6428 return emalloc_rel(lval + offset);
6429 }
6430 }
6431-
6432+
6433+#if HARDENING_PATCH
6434+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6435+#endif
6436 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6437 return 0;
6438 }
6439
6440 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6441 {
6442+#if HARDENING_PATCH_MM_PROTECT
6443+ unsigned int canary_2;
6444+#endif
6445 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6446 DECLARE_CACHE_VARS();
6447 TSRMLS_FETCH();
6448
6449+#if HARDENING_PATCH_MM_PROTECT
6450+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6451+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6452+ if (canary_2 != HG(canary_2)) {
6453+efree_canary_mismatch:
6454+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6455+ exit(1);
6456+ }
6457+ /* to catch double efree()s */
6458+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6459+ p->canary = 0;
6460+#endif
6461+
6462 #if defined(ZTS) && TSRM_DEBUG
6463 if (p->thread_id != tsrm_thread_id()) {
6464 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6465@@ -288,6 +333,9 @@
6466 size_t _size = nmemb * size;
6467
6468 if (nmemb && (_size/nmemb!=size)) {
6469+#if HARDENING_PATCH
6470+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6471+#endif
6472 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6473 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6474 kill(getpid(), SIGSEGV);
6475@@ -307,6 +355,9 @@
6476
6477 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6478 {
6479+#if HARDENING_PATCH_MM_PROTECT
6480+ unsigned int canary_2;
6481+#endif
6482 zend_mem_header *p;
6483 zend_mem_header *orig;
6484 DECLARE_CACHE_VARS();
6485@@ -318,6 +369,16 @@
6486
6487 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6488
6489+#if HARDENING_PATCH_MM_PROTECT
6490+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6491+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6492+ if (canary_2 != HG(canary_2)) {
6493+erealloc_canary_mismatch:
6494+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6495+ exit(1);
6496+ }
6497+#endif
6498+
6499 #if defined(ZTS) && TSRM_DEBUG
6500 if (p->thread_id != tsrm_thread_id()) {
6501 void *new_p;
6502@@ -348,7 +409,7 @@
6503 }
6504 #endif
6505 REMOVE_POINTER_FROM_LIST(p);
6506- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6507+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6508 erealloc_error:
6509 if (!p) {
6510 if (!allow_failure) {
6511@@ -371,6 +432,9 @@
6512 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6513 #endif
6514
6515+#if HARDENING_PATCH_MM_PROTECT
6516+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6517+#endif
6518 p->size = size;
6519
6520 HANDLE_UNBLOCK_INTERRUPTIONS();
6521@@ -445,6 +509,10 @@
6522 {
6523 AG(head) = NULL;
6524
6525+#if HARDENING_PATCH_MM_PROTECT
6526+ HG(canary_1) = zend_canary();
6527+ HG(canary_2) = zend_canary();
6528+#endif
6529 #if MEMORY_LIMIT
6530 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6531 AG(allocated_memory) = 0;
6532diff -Nura php-4.4.4/Zend/zend_alloc.h hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h
6533--- php-4.4.4/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100
6534+++ hardening-patch-4.4.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:30:51.000000000 +0200
6535@@ -32,6 +32,9 @@
6536 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6537
6538 typedef struct _zend_mem_header {
6539+#if HARDENING_PATCH_MM_PROTECT
6540+ unsigned int canary;
6541+#endif
6542 #if ZEND_DEBUG
6543 long magic;
6544 char *filename;
6545diff -Nura php-4.4.4/Zend/zend_builtin_functions.c hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c
6546--- php-4.4.4/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100
6547+++ hardening-patch-4.4.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:30:51.000000000 +0200
6548@@ -49,6 +49,9 @@
6549 static ZEND_FUNCTION(crash);
6550 #endif
6551 #endif
6552+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6553+static ZEND_FUNCTION(heap_overflow);
6554+#endif
6555 static ZEND_FUNCTION(get_included_files);
6556 static ZEND_FUNCTION(is_subclass_of);
6557 static ZEND_FUNCTION(is_a);
6558@@ -101,6 +104,9 @@
6559 ZEND_FE(crash, NULL)
6560 #endif
6561 #endif
6562+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6563+ ZEND_FE(heap_overflow, NULL)
6564+#endif
6565 ZEND_FE(get_included_files, NULL)
6566 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6567 ZEND_FE(is_subclass_of, NULL)
6568@@ -805,6 +811,19 @@
6569
6570 #endif /* ZEND_DEBUG */
6571
6572+
6573+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6574+ZEND_FUNCTION(heap_overflow)
6575+{
6576+ char *nowhere = emalloc(10);
6577+
6578+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6579+
6580+ efree(nowhere);
6581+}
6582+#endif
6583+
6584+
6585 /* {{{ proto array get_included_files(void)
6586 Returns an array with the file names that were include_once()'d */
6587 ZEND_FUNCTION(get_included_files)
6588diff -Nura php-4.4.4/Zend/zend.c hardening-patch-4.4.4-0.4.15/Zend/zend.c
6589--- php-4.4.4/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100
6590+++ hardening-patch-4.4.4-0.4.15/Zend/zend.c 2006-09-05 20:30:51.000000000 +0200
6591@@ -53,6 +53,12 @@
6592 ZEND_API void (*zend_unblock_interruptions)(void);
6593 ZEND_API void (*zend_ticks_function)(int ticks);
6594 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6595+#if HARDENING_PATCH
6596+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6597+#endif
6598+#if HARDENING_PATCH_INC_PROTECT
6599+ZEND_API int (*zend_is_valid_include)(zval *z);
6600+#endif
6601
6602 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6603
6604@@ -70,9 +76,391 @@
6605 return SUCCESS;
6606 }
6607
6608+#if HARDENING_PATCH
6609+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6610+{
6611+ if (!new_value) {
6612+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6613+ } else {
6614+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6615+ }
6616+ return SUCCESS;
6617+}
6618+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6619+{
6620+ if (!new_value) {
6621+ EG(hphp_log_syslog_facility) = LOG_USER;
6622+ } else {
6623+ EG(hphp_log_syslog_facility) = atoi(new_value);
6624+ }
6625+ return SUCCESS;
6626+}
6627+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6628+{
6629+ if (!new_value) {
6630+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6631+ } else {
6632+ EG(hphp_log_syslog_priority) = atoi(new_value);
6633+ }
6634+ return SUCCESS;
6635+}
6636+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6637+{
6638+ if (!new_value) {
6639+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6640+ } else {
6641+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6642+ }
6643+ return SUCCESS;
6644+}
6645+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6646+{
6647+ if (!new_value) {
6648+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6649+ } else {
6650+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6651+ }
6652+ return SUCCESS;
6653+}
6654+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6655+{
6656+ if (EG(hphp_log_scriptname)) {
6657+ pefree(EG(hphp_log_scriptname),1);
6658+ }
6659+ EG(hphp_log_scriptname) = NULL;
6660+ if (new_value) {
6661+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6662+ }
6663+ return SUCCESS;
6664+}
6665+
6666+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6667+{
6668+ char *s = NULL, *e, *val;
6669+ unsigned long dummy = 1;
6670+
6671+ if (!new_value) {
6672+include_whitelist_destroy:
6673+ if (HG(include_whitelist)) {
6674+ zend_hash_destroy(HG(include_whitelist));
6675+ pefree(HG(include_whitelist),1);
6676+ }
6677+ HG(include_whitelist) = NULL;
6678+ return SUCCESS;
6679+ }
6680+ if (!(*new_value)) {
6681+ goto include_whitelist_destroy;
6682+ }
6683+
6684+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6685+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6686+
6687+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6688+ e = val;
6689+
6690+ while (*e) {
6691+ switch (*e) {
6692+ case ' ':
6693+ case ',':
6694+ if (s) {
6695+ *e = '\0';
6696+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6697+ s = NULL;
6698+ }
6699+ break;
6700+ default:
6701+ if (!s) {
6702+ s = e;
6703+ }
6704+ break;
6705+ }
6706+ e++;
6707+ }
6708+ if (s) {
6709+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6710+ }
6711+ efree(val);
6712+
6713+ return SUCCESS;
6714+}
6715+
6716+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6717+{
6718+ char *s = NULL, *e, *val;
6719+ unsigned long dummy = 1;
6720+
6721+ if (!new_value) {
6722+include_blacklist_destroy:
6723+ if (HG(include_blacklist)) {
6724+ zend_hash_destroy(HG(include_blacklist));
6725+ pefree(HG(include_blacklist),1);
6726+ }
6727+ HG(include_blacklist) = NULL;
6728+ return SUCCESS;
6729+ }
6730+ if (!(*new_value)) {
6731+ goto include_blacklist_destroy;
6732+ }
6733+
6734+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6735+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6736+
6737+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6738+ e = val;
6739+
6740+ while (*e) {
6741+ switch (*e) {
6742+ case ' ':
6743+ case ',':
6744+ if (s) {
6745+ *e = '\0';
6746+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6747+ s = NULL;
6748+ }
6749+ break;
6750+ default:
6751+ if (!s) {
6752+ s = e;
6753+ }
6754+ break;
6755+ }
6756+ e++;
6757+ }
6758+ if (s) {
6759+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6760+ }
6761+ efree(val);
6762+
6763+ return SUCCESS;
6764+}
6765+
6766+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6767+{
6768+ char *s = NULL, *e, *val;
6769+ unsigned long dummy = 1;
6770+
6771+ if (!new_value) {
6772+eval_whitelist_destroy:
6773+ if (HG(eval_whitelist)) {
6774+ zend_hash_destroy(HG(eval_whitelist));
6775+ pefree(HG(eval_whitelist),1);
6776+ }
6777+ HG(eval_whitelist) = NULL;
6778+ return SUCCESS;
6779+ }
6780+ if (!(*new_value)) {
6781+ goto eval_whitelist_destroy;
6782+ }
6783+
6784+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6785+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6786+
6787+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6788+ e = val;
6789+
6790+ while (*e) {
6791+ switch (*e) {
6792+ case ' ':
6793+ case ',':
6794+ if (s) {
6795+ *e = '\0';
6796+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6797+ s = NULL;
6798+ }
6799+ break;
6800+ default:
6801+ if (!s) {
6802+ s = e;
6803+ }
6804+ break;
6805+ }
6806+ e++;
6807+ }
6808+ if (s) {
6809+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6810+ }
6811+ efree(val);
6812+
6813+ return SUCCESS;
6814+}
6815+
6816+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6817+{
6818+ char *s = NULL, *e, *val;
6819+ unsigned long dummy = 1;
6820+
6821+ if (!new_value) {
6822+eval_blacklist_destroy:
6823+ if (HG(eval_blacklist)) {
6824+ zend_hash_destroy(HG(eval_blacklist));
6825+ pefree(HG(eval_blacklist), 1);
6826+ }
6827+ HG(eval_blacklist) = NULL;
6828+ return SUCCESS;
6829+ }
6830+ if (!(*new_value)) {
6831+ goto eval_blacklist_destroy;
6832+ }
6833+
6834+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6835+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6836+
6837+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6838+ e = val;
6839+
6840+ while (*e) {
6841+ switch (*e) {
6842+ case ' ':
6843+ case ',':
6844+ if (s) {
6845+ *e = '\0';
6846+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6847+ s = NULL;
6848+ }
6849+ break;
6850+ default:
6851+ if (!s) {
6852+ s = e;
6853+ }
6854+ break;
6855+ }
6856+ e++;
6857+ }
6858+ if (s) {
6859+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6860+ }
6861+ efree(val);
6862+
6863+
6864+ return SUCCESS;
6865+}
6866+
6867+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6868+{
6869+ char *s = NULL, *e, *val;
6870+ unsigned long dummy = 1;
6871+
6872+ if (!new_value) {
6873+func_whitelist_destroy:
6874+ if (HG(func_whitelist)) {
6875+ zend_hash_destroy(HG(func_whitelist));
6876+ pefree(HG(func_whitelist),1);
6877+ }
6878+ HG(func_whitelist) = NULL;
6879+ return SUCCESS;
6880+ }
6881+ if (!(*new_value)) {
6882+ goto func_whitelist_destroy;
6883+ }
6884+
6885+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6886+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6887+
6888+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6889+ e = val;
6890+
6891+ while (*e) {
6892+ switch (*e) {
6893+ case ' ':
6894+ case ',':
6895+ if (s) {
6896+ *e = '\0';
6897+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6898+ s = NULL;
6899+ }
6900+ break;
6901+ default:
6902+ if (!s) {
6903+ s = e;
6904+ }
6905+ break;
6906+ }
6907+ e++;
6908+ }
6909+ if (s) {
6910+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6911+ }
6912+ efree(val);
6913+
6914+ return SUCCESS;
6915+}
6916+
6917+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6918+{
6919+ char *s = NULL, *e, *val;
6920+ unsigned long dummy = 1;
6921+
6922+ if (!new_value) {
6923+func_blacklist_destroy:
6924+ if (HG(func_blacklist)) {
6925+ zend_hash_destroy(HG(func_blacklist));
6926+ pefree(HG(func_blacklist),1);
6927+ }
6928+ HG(func_blacklist) = NULL;
6929+ return SUCCESS;
6930+ }
6931+ if (!(*new_value)) {
6932+ goto func_blacklist_destroy;
6933+ }
6934+
6935+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6936+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6937+
6938+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6939+ e = val;
6940+
6941+ while (*e) {
6942+ switch (*e) {
6943+ case ' ':
6944+ case ',':
6945+ if (s) {
6946+ *e = '\0';
6947+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6948+ s = NULL;
6949+ }
6950+ break;
6951+ default:
6952+ if (!s) {
6953+ s = e;
6954+ }
6955+ break;
6956+ }
6957+ e++;
6958+ }
6959+ if (s) {
6960+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6961+ }
6962+ efree(val);
6963+
6964+
6965+ return SUCCESS;
6966+}
6967+
6968+#endif
6969
6970 ZEND_INI_BEGIN()
6971 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6972+#if HARDENING_PATCH
6973+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6974+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6975+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6976+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6977+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6978+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6979+ 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)
6980+
6981+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6982+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6983+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6984+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6985+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6986+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6987+
6988+ 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)
6989+ 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)
6990+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6991+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals)
6992+#endif
6993 ZEND_INI_END()
6994
6995
6996@@ -354,8 +742,12 @@
6997 zend_init_rsrc_plist(TSRMLS_C);
6998 EG(lambda_count)=0;
6999 EG(user_error_handler) = NULL;
7000+ EG(in_code_type) = 0;
7001 EG(in_execution) = 0;
7002 EG(current_execute_data) = NULL;
7003+#if HARDENING_PATCH
7004+ EG(hphp_log_scriptname) = NULL;
7005+#endif
7006 }
7007
7008
7009@@ -420,6 +812,14 @@
7010 extern zend_scanner_globals language_scanner_globals;
7011 #endif
7012
7013+ /* Set up Hardening-Patch utility functions first */
7014+#if HARDENING_PATCH
7015+ zend_security_log = utility_functions->security_log_function;
7016+#endif
7017+#if HARDENING_PATCH_INC_PROTECT
7018+ zend_is_valid_include = utility_functions->is_valid_include;
7019+#endif
7020+
7021 #ifdef ZTS
7022 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
7023 #else
7024@@ -619,6 +1019,7 @@
7025 }
7026 CG(unclean_shutdown) = 1;
7027 CG(in_compilation) = EG(in_execution) = 0;
7028+ EG(in_code_type) = 0;
7029 EG(current_execute_data) = NULL;
7030 longjmp(EG(bailout), FAILURE);
7031 }
7032diff -Nura php-4.4.4/Zend/zend_canary.c hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c
7033--- php-4.4.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
7034+++ hardening-patch-4.4.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:30:51.000000000 +0200
7035@@ -0,0 +1,58 @@
7036+/*
7037+ +----------------------------------------------------------------------+
7038+ | Hardening-Patch for PHP |
7039+ +----------------------------------------------------------------------+
7040+ | Copyright (c) 2004-2005 Stefan Esser |
7041+ +----------------------------------------------------------------------+
7042+ | This source file is subject to version 2.02 of the PHP license, |
7043+ | that is bundled with this package in the file LICENSE, and is |
7044+ | available at through the world-wide-web at |
7045+ | http://www.php.net/license/2_02.txt. |
7046+ | If you did not receive a copy of the PHP license and are unable to |
7047+ | obtain it through the world-wide-web, please send a note to |
7048+ | license@php.net so we can mail you a copy immediately. |
7049+ +----------------------------------------------------------------------+
7050+ | Author: Stefan Esser <sesser@hardened-php.net> |
7051+ +----------------------------------------------------------------------+
7052+ */
7053+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
7054+
7055+#include "zend.h"
7056+
7057+#include <stdio.h>
7058+#include <stdlib.h>
7059+
7060+
7061+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7062+
7063+/* will be replaced later with more compatible method */
7064+ZEND_API unsigned int zend_canary()
7065+{
7066+ time_t t;
7067+ unsigned int canary;
7068+ int fd;
7069+
7070+ fd = open("/dev/urandom", 0);
7071+ if (fd != -1) {
7072+ int r = read(fd, &canary, sizeof(canary));
7073+ close(fd);
7074+ if (r == sizeof(canary)) {
7075+ return (canary);
7076+ }
7077+ }
7078+ /* not good but we never want to do this */
7079+ time(&t);
7080+ canary = *(unsigned int *)&t + getpid() << 16;
7081+ return (canary);
7082+}
7083+#endif
7084+
7085+
7086+/*
7087+ * Local variables:
7088+ * tab-width: 4
7089+ * c-basic-offset: 4
7090+ * End:
7091+ * vim600: sw=4 ts=4 fdm=marker
7092+ * vim<600: sw=4 ts=4
7093+ */
7094diff -Nura php-4.4.4/Zend/zend_compile.c hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c
7095--- php-4.4.4/Zend/zend_compile.c 2006-02-23 19:07:16.000000000 +0100
7096+++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:30:51.000000000 +0200
7097@@ -768,6 +768,13 @@
7098 op_array.function_name = name;
7099 op_array.arg_types = NULL;
7100 op_array.return_reference = return_reference;
7101+#if HARDENING_PATCH
7102+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7103+ op_array.created_by_eval = 1;
7104+ } else {
7105+ op_array.created_by_eval = 0;
7106+ }
7107+#endif
7108
7109 if (is_method) {
7110 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) {
7111diff -Nura php-4.4.4/Zend/zend_compile.h hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h
7112--- php-4.4.4/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100
7113+++ hardening-patch-4.4.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:30:51.000000000 +0200
7114@@ -106,6 +106,9 @@
7115 char *filename;
7116
7117 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
7118+#if HARDENING_PATCH
7119+ zend_bool created_by_eval;
7120+#endif
7121 };
7122
7123
7124@@ -549,6 +552,7 @@
7125 #define ZEND_USER_FUNCTION 2
7126 #define ZEND_OVERLOADED_FUNCTION 3
7127 #define ZEND_EVAL_CODE 4
7128+#define ZEND_SANDBOX_CODE 6
7129
7130 #define ZEND_INTERNAL_CLASS 1
7131 #define ZEND_USER_CLASS 2
7132diff -Nura php-4.4.4/Zend/zend_constants.c hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c
7133--- php-4.4.4/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100
7134+++ hardening-patch-4.4.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:30:51.000000000 +0200
7135@@ -111,6 +111,74 @@
7136 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
7137
7138 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
7139+#if HARDENING_PATCH
7140+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
7141+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
7142+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
7143+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
7144+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
7145+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
7146+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
7147+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
7148+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
7149+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
7150+
7151+ /* error levels */
7152+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
7153+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
7154+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
7155+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
7156+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
7157+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
7158+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
7159+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
7160+ /* facility: type of program logging the message */
7161+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
7162+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
7163+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
7164+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
7165+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
7166+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
7167+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
7168+#ifdef LOG_NEWS
7169+ /* No LOG_NEWS on HP-UX */
7170+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
7171+#endif
7172+#ifdef LOG_UUCP
7173+ /* No LOG_UUCP on HP-UX */
7174+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
7175+#endif
7176+#ifdef LOG_CRON
7177+ /* apparently some systems don't have this one */
7178+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
7179+#endif
7180+#ifdef LOG_AUTHPRIV
7181+ /* AIX doesn't have LOG_AUTHPRIV */
7182+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7183+#endif
7184+#if !defined(PHP_WIN32) && !defined(NETWARE)
7185+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7186+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7187+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7188+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7189+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7190+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7191+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7192+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7193+#endif
7194+ /* options */
7195+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7196+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7197+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7198+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7199+#ifdef LOG_NOWAIT
7200+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7201+#endif
7202+#ifdef LOG_PERROR
7203+ /* AIX doesn't have LOG_PERROR */
7204+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7205+#endif
7206+#endif
7207
7208 /* true/false constants */
7209 {
7210diff -Nura php-4.4.4/Zend/zend_errors.h hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h
7211--- php-4.4.4/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100
7212+++ hardening-patch-4.4.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:30:51.000000000 +0200
7213@@ -36,5 +36,18 @@
7214 #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)
7215 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7216
7217+#if HARDENING_PATCH
7218+#define S_MEMORY (1<<0L)
7219+#define S_VARS (1<<1L)
7220+#define S_FILES (1<<2L)
7221+#define S_INCLUDE (1<<3L)
7222+#define S_SQL (1<<4L)
7223+#define S_EXECUTOR (1<<5L)
7224+#define S_MAIL (1<<6L)
7225+#define S_MISC (1<<30L)
7226+#define S_INTERNAL (1<<29L)
7227+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR)
7228+#endif
7229+
7230 #endif /* ZEND_ERRORS_H */
7231
7232diff -Nura php-4.4.4/Zend/zend_execute_API.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c
7233--- php-4.4.4/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100
7234+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:30:51.000000000 +0200
7235@@ -142,6 +142,7 @@
7236 EG(class_table) = CG(class_table);
7237
7238 EG(in_execution) = 0;
7239+ EG(in_code_type) = 0;
7240
7241 zend_ptr_stack_init(&EG(argument_stack));
7242
7243@@ -431,12 +432,14 @@
7244 zend_execute_data execute_data;
7245
7246 /* Initialize execute_data */
7247+ memset(&execute_data, 0, sizeof(execute_data));
7248 EX(fbc) = NULL;
7249 EX(object).ptr = NULL;
7250 EX(ce) = NULL;
7251 EX(Ts) = NULL;
7252 EX(op_array) = NULL;
7253 EX(opline) = NULL;
7254+ EX(execute_depth) = 0;
7255
7256 *retval_ptr_ptr = NULL;
7257
7258@@ -494,6 +497,39 @@
7259 zval_dtor(&function_name_copy);
7260 return FAILURE;
7261 }
7262+#if HARDENING_PATCH
7263+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7264+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7265+ if (HG(eval_whitelist) != NULL) {
7266+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7267+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7268+ zval_dtor(&function_name_copy);
7269+ zend_bailout();
7270+ }
7271+ } else if (HG(eval_blacklist) != NULL) {
7272+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7273+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7274+ zval_dtor(&function_name_copy);
7275+ zend_bailout();
7276+ }
7277+ }
7278+ }
7279+
7280+ if (HG(func_whitelist) != NULL) {
7281+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7282+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7283+ zval_dtor(&function_name_copy);
7284+ zend_bailout();
7285+ }
7286+ } else if (HG(func_blacklist) != NULL) {
7287+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7288+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7289+ zval_dtor(&function_name_copy);
7290+ zend_bailout();
7291+ }
7292+ }
7293+ }
7294+#endif
7295 zval_dtor(&function_name_copy);
7296
7297 for (i=0; i<param_count; i++) {
7298@@ -606,8 +642,7 @@
7299 return SUCCESS;
7300 }
7301
7302-
7303-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7304+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7305 {
7306 zval pv;
7307 zend_op_array *new_op_array;
7308@@ -640,6 +675,7 @@
7309 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7310 zend_op **original_opline_ptr = EG(opline_ptr);
7311
7312+ new_op_array->type = type;
7313 EG(return_value_ptr_ptr) = &local_retval_ptr;
7314 EG(active_op_array) = new_op_array;
7315 EG(no_extensions)=1;
7316@@ -673,6 +709,10 @@
7317 return retval;
7318 }
7319
7320+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7321+{
7322+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7323+}
7324
7325 void execute_new_code(TSRMLS_D)
7326 {
7327diff -Nura php-4.4.4/Zend/zend_execute.c hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c
7328--- php-4.4.4/Zend/zend_execute.c 2006-08-11 15:04:14.000000000 +0200
7329+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:30:51.000000000 +0200
7330@@ -1042,6 +1042,7 @@
7331 zend_execute_data execute_data;
7332
7333 /* Initialize execute_data */
7334+ memset(&execute_data, 0, sizeof(execute_data));
7335 EX(fbc) = NULL;
7336 EX(ce) = NULL;
7337 EX(object).ptr = NULL;
7338@@ -1053,9 +1054,21 @@
7339 }
7340 EX(prev_execute_data) = EG(current_execute_data);
7341 EX(original_in_execution)=EG(in_execution);
7342+ EX(original_in_code_type)=EG(in_code_type);
7343
7344 EG(current_execute_data) = &execute_data;
7345
7346+#if HARDENING_PATCH
7347+ EX(execute_depth) = 0;
7348+
7349+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7350+ EG(in_code_type) = ZEND_EVAL_CODE;
7351+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7352+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7353+ op_array->type = ZEND_EVAL_CODE;
7354+ }
7355+#endif
7356+
7357 EG(in_execution) = 1;
7358 if (op_array->start_op) {
7359 EX(opline) = op_array->start_op;
7360@@ -1087,6 +1100,19 @@
7361 }
7362 }
7363
7364+#if HARDENING_PATCH
7365+ if (EX(prev_execute_data) == NULL) {
7366+ EX(execute_depth) = 0;
7367+ } else {
7368+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7369+ }
7370+
7371+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7372+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7373+ zend_bailout();
7374+ }
7375+#endif
7376+
7377 while (1) {
7378 #ifdef ZEND_WIN32
7379 if (EG(timed_out)) {
7380@@ -1634,6 +1660,36 @@
7381 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7382 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7383 }
7384+#if HARDENING_PATCH
7385+ if (active_function_table == EG(function_table)) {
7386+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7387+ if (HG(eval_whitelist) != NULL) {
7388+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7389+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7390+ zend_bailout();
7391+ }
7392+ } else if (HG(eval_blacklist) != NULL) {
7393+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7394+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7395+ zend_bailout();
7396+ }
7397+ }
7398+ }
7399+
7400+ if (HG(func_whitelist) != NULL) {
7401+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7402+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7403+ zend_bailout();
7404+ }
7405+ } else if (HG(func_blacklist) != NULL) {
7406+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7407+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7408+ zend_bailout();
7409+ }
7410+ }
7411+ }
7412+#endif
7413+
7414 zval_dtor(&tmp);
7415 EX(fbc) = function;
7416 overloaded_function_call_cont:
7417@@ -1649,6 +1705,35 @@
7418 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7419 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7420 }
7421+#if HARDENING_PATCH
7422+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7423+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7424+ if (HG(eval_whitelist) != NULL) {
7425+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7426+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7427+ zend_bailout();
7428+ }
7429+ } else if (HG(eval_blacklist) != NULL) {
7430+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7431+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7432+ zend_bailout();
7433+ }
7434+ }
7435+ }
7436+
7437+ if (HG(func_whitelist) != NULL) {
7438+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7439+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7440+ zend_bailout();
7441+ }
7442+ } else if (HG(func_blacklist) != NULL) {
7443+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7444+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7445+ zend_bailout();
7446+ }
7447+ }
7448+ }
7449+#endif
7450 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7451 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7452 EX(object).ptr = NULL;
7453@@ -1821,6 +1906,7 @@
7454 efree(EX(Ts));
7455 }
7456 EG(in_execution) = EX(original_in_execution);
7457+ EG(in_code_type) = EX(original_in_code_type);
7458 EG(current_execute_data) = EX(prev_execute_data);
7459 return;
7460 }
7461@@ -2210,7 +2296,12 @@
7462 int dummy = 1;
7463 zend_file_handle file_handle = {0};
7464
7465+#if HARDENING_PATCH_INC_PROTECT
7466+ if (zend_is_valid_include(inc_filename)
7467+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7468+#else
7469 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7470+#endif
7471 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7472
7473 file_handle.filename = inc_filename->value.str.val;
7474@@ -2239,6 +2330,11 @@
7475 break;
7476 case ZEND_INCLUDE:
7477 case ZEND_REQUIRE:
7478+#if HARDENING_PATCH_INC_PROTECT
7479+ if (!zend_is_valid_include(inc_filename)) {
7480+ break;
7481+ }
7482+#endif
7483 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7484 break;
7485 case ZEND_EVAL: {
7486diff -Nura php-4.4.4/Zend/zend_execute_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h
7487--- php-4.4.4/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100
7488+++ hardening-patch-4.4.4-0.4.15/Zend/zend_execute_globals.h 2006-09-05 20:30:51.000000000 +0200
7489@@ -60,6 +60,8 @@
7490 object_info object;
7491 temp_variable *Ts;
7492 zend_bool original_in_execution;
7493+ zend_uint original_in_code_type;
7494+ zend_uint execute_depth;
7495 zend_op_array *op_array;
7496 struct _zend_execute_data *prev_execute_data;
7497 } zend_execute_data;
7498diff -Nura php-4.4.4/Zend/zend_extensions.c hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c
7499--- php-4.4.4/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100
7500+++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:30:51.000000000 +0200
7501@@ -54,23 +54,44 @@
7502 return FAILURE;
7503 }
7504
7505+ /* check if module is compiled against Hardening-Patch */
7506+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7507+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7508+ "The Hardening-Patch version %d is installed.\n\n",
7509+ new_extension->name,
7510+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7511+ DL_UNLOAD(handle);
7512+ return FAILURE;
7513+ }
7514+
7515+
7516+ /* check if module is compiled against correct Hardening-Patch version */
7517+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7518+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7519+ "The Hardening-Patch version %d is installed.\n\n",
7520+ new_extension->name,
7521+ extension_version_info->zend_extension_api_no,
7522+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7523+ DL_UNLOAD(handle);
7524+ return FAILURE;
7525+ }
7526
7527 /* allow extension to proclaim compatibility with any Zend version */
7528- 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)) {
7529- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7530+ 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)) {
7531+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7532 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7533 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7534 new_extension->name,
7535- extension_version_info->zend_extension_api_no,
7536+ extension_version_info->real_zend_extension_api_no,
7537 ZEND_EXTENSION_API_NO);
7538 DL_UNLOAD(handle);
7539 return FAILURE;
7540- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7541+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7542 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7543 "The Zend Engine API version %d which is installed, is newer.\n"
7544 "Contact %s at %s for a later version of %s.\n\n",
7545 new_extension->name,
7546- extension_version_info->zend_extension_api_no,
7547+ extension_version_info->real_zend_extension_api_no,
7548 ZEND_EXTENSION_API_NO,
7549 new_extension->author,
7550 new_extension->URL,
7551diff -Nura php-4.4.4/Zend/zend_extensions.h hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h
7552--- php-4.4.4/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100
7553+++ hardening-patch-4.4.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:30:51.000000000 +0200
7554@@ -23,6 +23,9 @@
7555
7556 #include "zend_compile.h"
7557
7558+/* Create own API version number for Hardening-Patch */
7559+
7560+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7561 #define ZEND_EXTENSION_API_NO 20050606
7562
7563 typedef struct _zend_extension_version_info {
7564@@ -30,6 +33,7 @@
7565 char *required_zend_version;
7566 unsigned char thread_safe;
7567 unsigned char debug;
7568+ int real_zend_extension_api_no;
7569 } zend_extension_version_info;
7570
7571
7572@@ -96,7 +100,7 @@
7573
7574
7575 #define ZEND_EXTENSION() \
7576- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7577+ 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 }
7578
7579 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7580 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7581diff -Nura php-4.4.4/Zend/zend_globals.h hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h
7582--- php-4.4.4/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100
7583+++ hardening-patch-4.4.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:30:51.000000000 +0200
7584@@ -163,6 +163,16 @@
7585
7586 int error_reporting;
7587 int orig_error_reporting;
7588+#if HARDENING_PATCH
7589+ int hphp_log_syslog;
7590+ int hphp_log_syslog_facility;
7591+ int hphp_log_syslog_priority;
7592+ int hphp_log_sapi;
7593+ int hphp_log_script;
7594+ char *hphp_log_scriptname;
7595+ zend_bool hphp_log_use_x_forwarded_for;
7596+ long hphp_executor_max_depth;
7597+#endif
7598 int exit_status;
7599
7600 zend_op_array *active_op_array;
7601@@ -176,6 +186,7 @@
7602 int ticks_count;
7603
7604 zend_bool in_execution;
7605+ zend_uint in_code_type;
7606 zend_bool bailout_set;
7607 zend_bool full_tables_cleanup;
7608
7609diff -Nura php-4.4.4/Zend/zend.h hardening-patch-4.4.4-0.4.15/Zend/zend.h
7610--- php-4.4.4/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100
7611+++ hardening-patch-4.4.4-0.4.15/Zend/zend.h 2006-09-05 20:30:51.000000000 +0200
7612@@ -274,9 +274,10 @@
7613 struct _zval_struct {
7614 /* Variable information */
7615 zvalue_value value; /* value */
7616+ zend_uint refcount;
7617+ zend_ushort flags;
7618 zend_uchar type; /* active type */
7619 zend_uchar is_ref;
7620- zend_ushort refcount;
7621 };
7622
7623
7624@@ -337,6 +338,12 @@
7625 void (*ticks_function)(int ticks);
7626 void (*on_timeout)(int seconds TSRMLS_DC);
7627 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7628+#if HARDENING_PATCH
7629+ void (*security_log_function)(int loglevel, char *fmt, ...);
7630+#endif
7631+#if HARDENING_PATCH_INC_PROTECT
7632+ int (*is_valid_include)(zval *z);
7633+#endif
7634 } zend_utility_functions;
7635
7636
7637@@ -468,7 +475,16 @@
7638 extern ZEND_API void (*zend_ticks_function)(int ticks);
7639 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);
7640 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7641+#if HARDENING_PATCH
7642+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7643+#endif
7644+#if HARDENING_PATCH_INC_PROTECT
7645+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7646+#endif
7647
7648+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7649+ZEND_API unsigned int zend_canary(void);
7650+#endif
7651
7652 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7653
7654@@ -575,6 +591,11 @@
7655
7656 #define ZEND_MAX_RESERVED_RESOURCES 4
7657
7658+#if HARDENING_PATCH
7659+#include "hardened_globals.h"
7660+#include "php_syslog.h"
7661+#endif
7662+
7663 #endif /* ZEND_H */
7664
7665 /*
7666diff -Nura php-4.4.4/Zend/zend_hash.c hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c
7667--- php-4.4.4/Zend/zend_hash.c 2006-02-01 10:11:55.000000000 +0100
7668+++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:30:51.000000000 +0200
7669@@ -26,6 +26,17 @@
7670 # include <stdlib.h>
7671 #endif
7672
7673+#if HARDENING_PATCH_HASH_PROTECT
7674+ unsigned int zend_hash_canary = 0x1234567;
7675+ zend_bool zend_hash_canary_inited = 0;
7676+#endif
7677+
7678+#define CHECK_HASH_CANARY(hash) \
7679+ if (zend_hash_canary != (hash)->canary) { \
7680+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7681+ exit(1); \
7682+ }
7683+
7684 #define HANDLE_NUMERIC(key, length, func) { \
7685 register char *tmp=key; \
7686 \
7687@@ -175,6 +186,9 @@
7688 {
7689 uint i = 3;
7690 Bucket **tmp;
7691+#if HARDENING_PATCH_HASH_PROTECT
7692+ TSRMLS_FETCH();
7693+#endif
7694
7695 SET_INCONSISTENT(HT_OK);
7696
7697@@ -184,6 +198,13 @@
7698
7699 ht->nTableSize = 1 << i;
7700 ht->nTableMask = ht->nTableSize - 1;
7701+#if HARDENING_PATCH_HASH_PROTECT
7702+ if (zend_hash_canary_inited==0) {
7703+ zend_hash_canary = zend_canary();
7704+ zend_hash_canary_inited = 1;
7705+ }
7706+ ht->canary = zend_hash_canary;
7707+#endif
7708 ht->pDestructor = pDestructor;
7709 ht->pListHead = NULL;
7710 ht->pListTail = NULL;
7711@@ -259,6 +280,9 @@
7712 }
7713 #endif
7714 if (ht->pDestructor) {
7715+#if HARDENING_PATCH_HASH_PROTECT
7716+ CHECK_HASH_CANARY(ht);
7717+#endif
7718 ht->pDestructor(p->pData);
7719 }
7720 UPDATE_DATA(ht, p, pData, nDataSize);
7721@@ -327,6 +351,9 @@
7722 }
7723 #endif
7724 if (ht->pDestructor) {
7725+#if HARDENING_PATCH_HASH_PROTECT
7726+ CHECK_HASH_CANARY(ht);
7727+#endif
7728 ht->pDestructor(p->pData);
7729 }
7730 UPDATE_DATA(ht, p, pData, nDataSize);
7731@@ -402,6 +429,9 @@
7732 }
7733 #endif
7734 if (ht->pDestructor) {
7735+#if HARDENING_PATCH_HASH_PROTECT
7736+ CHECK_HASH_CANARY(ht);
7737+#endif
7738 ht->pDestructor(p->pData);
7739 }
7740 UPDATE_DATA(ht, p, pData, nDataSize);
7741@@ -450,7 +480,7 @@
7742 IS_CONSISTENT(ht);
7743
7744 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7745- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7746+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7747 if (t) {
7748 HANDLE_BLOCK_INTERRUPTIONS();
7749 ht->arBuckets = t;
7750@@ -460,6 +490,7 @@
7751 HANDLE_UNBLOCK_INTERRUPTIONS();
7752 return SUCCESS;
7753 }
7754+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7755 return FAILURE;
7756 }
7757 return SUCCESS;
7758@@ -526,6 +557,9 @@
7759 ht->pInternalPointer = p->pListNext;
7760 }
7761 if (ht->pDestructor) {
7762+#if HARDENING_PATCH_HASH_PROTECT
7763+ CHECK_HASH_CANARY(ht);
7764+#endif
7765 ht->pDestructor(p->pData);
7766 }
7767 if (!p->pDataPtr) {
7768@@ -555,6 +589,9 @@
7769 q = p;
7770 p = p->pListNext;
7771 if (ht->pDestructor) {
7772+#if HARDENING_PATCH_HASH_PROTECT
7773+ CHECK_HASH_CANARY(ht);
7774+#endif
7775 ht->pDestructor(q->pData);
7776 }
7777 if (!q->pDataPtr && q->pData) {
7778@@ -581,6 +618,9 @@
7779 q = p;
7780 p = p->pListNext;
7781 if (ht->pDestructor) {
7782+#if HARDENING_PATCH_HASH_PROTECT
7783+ CHECK_HASH_CANARY(ht);
7784+#endif
7785 ht->pDestructor(q->pData);
7786 }
7787 if (!q->pDataPtr && q->pData) {
7788@@ -610,6 +650,9 @@
7789 HANDLE_BLOCK_INTERRUPTIONS();
7790
7791 if (ht->pDestructor) {
7792+#if HARDENING_PATCH_HASH_PROTECT
7793+ CHECK_HASH_CANARY(ht);
7794+#endif
7795 ht->pDestructor(p->pData);
7796 }
7797 if (!p->pDataPtr) {
7798diff -Nura php-4.4.4/Zend/zend_hash.h hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h
7799--- php-4.4.4/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100
7800+++ hardening-patch-4.4.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:30:51.000000000 +0200
7801@@ -54,6 +54,9 @@
7802 } Bucket;
7803
7804 typedef struct _hashtable {
7805+#if HARDENING_PATCH_HASH_PROTECT
7806+ unsigned int canary;
7807+#endif
7808 uint nTableSize;
7809 uint nTableMask;
7810 uint nNumOfElements;
7811diff -Nura php-4.4.4/Zend/zend_ini.c hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c
7812--- php-4.4.4/Zend/zend_ini.c 2005-09-02 23:09:03.000000000 +0200
7813+++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:37.000000000 +0200
7814@@ -256,7 +256,8 @@
7815 zend_ini_entry *ini_entry;
7816 TSRMLS_FETCH();
7817
7818- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) {
7819+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE ||
7820+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifyable & ZEND_INI_USER) == 0)) {
7821 return FAILURE;
7822 }
7823
7824diff -Nura php-4.4.4/Zend/zend_ini.h hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h
7825--- php-4.4.4/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7826+++ hardening-patch-4.4.4-0.4.15/Zend/zend_ini.h 2006-09-05 20:30:51.000000000 +0200
7827@@ -174,6 +174,7 @@
7828 /* Standard message handlers */
7829 BEGIN_EXTERN_C()
7830 ZEND_API ZEND_INI_MH(OnUpdateBool);
7831+#define OnUpdateLong OnUpdateInt
7832 ZEND_API ZEND_INI_MH(OnUpdateInt);
7833 ZEND_API ZEND_INI_MH(OnUpdateReal);
7834 ZEND_API ZEND_INI_MH(OnUpdateString);
7835diff -Nura php-4.4.4/Zend/zend_language_scanner.l hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l
7836--- php-4.4.4/Zend/zend_language_scanner.l 2006-04-13 15:52:24.000000000 +0200
7837+++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:30:51.000000000 +0200
7838@@ -393,6 +393,13 @@
7839 compilation_successful=0;
7840 } else {
7841 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7842+#if HARDENING_PATCH
7843+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7844+ op_array->created_by_eval = 1;
7845+ } else {
7846+ op_array->created_by_eval = 0;
7847+ }
7848+#endif
7849 CG(in_compilation) = 1;
7850 CG(active_op_array) = op_array;
7851 compiler_result = zendparse(TSRMLS_C);
7852diff -Nura php-4.4.4/Zend/zend_language_scanner.c hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c
7853--- php-4.4.4/Zend/zend_language_scanner.c 2006-08-15 14:01:21.000000000 +0200
7854+++ hardening-patch-4.4.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:30:51.000000000 +0200
7855@@ -3036,6 +3036,13 @@
7856 compilation_successful=0;
7857 } else {
7858 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7859+#if HARDENING_PATCH
7860+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7861+ op_array->created_by_eval = 1;
7862+ } else {
7863+ op_array->created_by_eval = 0;
7864+ }
7865+#endif
7866 CG(in_compilation) = 1;
7867 CG(active_op_array) = op_array;
7868 compiler_result = zendparse(TSRMLS_C);
7869diff -Nura php-4.4.4/Zend/zend_llist.c hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c
7870--- php-4.4.4/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100
7871+++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:30:51.000000000 +0200
7872@@ -21,9 +21,49 @@
7873 #include "zend.h"
7874 #include "zend_llist.h"
7875 #include "zend_qsort.h"
7876+#include "zend_globals.h"
7877+
7878+#if HARDENING_PATCH_LL_PROTECT
7879+ unsigned int zend_llist_canary_1 = 0x1234567;
7880+ unsigned int zend_llist_canary_2 = 0x1553425;
7881+ zend_bool zend_llist_canary_inited = 0;
7882+#endif
7883+
7884+#define CHECK_LIST_CANARY(list) \
7885+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7886+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7887+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7888+ exit(1); \
7889+ }
7890+
7891+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7892+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7893+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7894+ exit(1); \
7895+ }
7896+
7897
7898 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7899 {
7900+#if HARDENING_PATCH_LL_PROTECT
7901+ TSRMLS_FETCH();
7902+
7903+ if (persistent) {
7904+ if (!zend_llist_canary_inited) {
7905+ /* do not change order to ensure thread safety */
7906+ zend_llist_canary_1 = zend_canary();
7907+ zend_llist_canary_2 = zend_canary();
7908+ zend_llist_canary_inited = 1;
7909+ }
7910+ } else
7911+ if (!HG(ll_canary_inited)) {
7912+ HG(canary_3) = zend_canary();
7913+ HG(canary_4) = zend_canary();
7914+ HG(ll_canary_inited) = 1;
7915+ }
7916+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7917+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7918+#endif
7919 l->head = NULL;
7920 l->tail = NULL;
7921 l->count = 0;
7922@@ -37,6 +77,11 @@
7923 {
7924 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7925
7926+#if HARDENING_PATCH_LL_PROTECT
7927+ TSRMLS_FETCH();
7928+ CHECK_LIST_CANARY(l)
7929+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7930+#endif
7931 tmp->prev = l->tail;
7932 tmp->next = NULL;
7933 if (l->tail) {
7934@@ -55,6 +100,11 @@
7935 {
7936 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7937
7938+#if HARDENING_PATCH_LL_PROTECT
7939+ TSRMLS_FETCH();
7940+ CHECK_LIST_CANARY(l)
7941+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7942+#endif
7943 tmp->next = l->head;
7944 tmp->prev = NULL;
7945 if (l->head) {
7946@@ -91,10 +141,20 @@
7947 zend_llist_element *current=l->head;
7948 zend_llist_element *next;
7949
7950+#if HARDENING_PATCH_LL_PROTECT
7951+ TSRMLS_FETCH();
7952+ CHECK_LIST_CANARY(l)
7953+#endif
7954 while (current) {
7955+#if HARDENING_PATCH_LL_PROTECT
7956+ CHECK_LISTELEMENT_CANARY(current, l)
7957+#endif
7958 next = current->next;
7959 if (compare(current->data, element)) {
7960 DEL_LLIST_ELEMENT(current, l);
7961+#if HARDENING_PATCH_LL_PROTECT
7962+ current->canary = 0;
7963+#endif
7964 break;
7965 }
7966 current = next;
7967@@ -106,7 +166,14 @@
7968 {
7969 zend_llist_element *current=l->head, *next;
7970
7971+#if HARDENING_PATCH_LL_PROTECT
7972+ TSRMLS_FETCH();
7973+ CHECK_LIST_CANARY(l)
7974+#endif
7975 while (current) {
7976+#if HARDENING_PATCH_LL_PROTECT
7977+ CHECK_LISTELEMENT_CANARY(current, l)
7978+#endif
7979 next = current->next;
7980 if (l->dtor) {
7981 l->dtor(current->data);
7982@@ -131,7 +198,14 @@
7983 zend_llist_element *old_tail;
7984 void *data;
7985
7986+#if HARDENING_PATCH_LL_PROTECT
7987+ TSRMLS_FETCH();
7988+ CHECK_LIST_CANARY(l)
7989+#endif
7990 if ((old_tail = l->tail)) {
7991+#if HARDENING_PATCH_LL_PROTECT
7992+ CHECK_LISTELEMENT_CANARY(old_tail, l)
7993+#endif
7994 if (l->tail->prev) {
7995 l->tail->prev->next = NULL;
7996 }
7997@@ -157,9 +231,16 @@
7998 {
7999 zend_llist_element *ptr;
8000
8001+#if HARDENING_PATCH_LL_PROTECT
8002+ TSRMLS_FETCH();
8003+ CHECK_LIST_CANARY(src)
8004+#endif
8005 zend_llist_init(dst, src->size, src->dtor, src->persistent);
8006 ptr = src->head;
8007 while (ptr) {
8008+#if HARDENING_PATCH_LL_PROTECT
8009+ CHECK_LISTELEMENT_CANARY(ptr, src)
8010+#endif
8011 zend_llist_add_element(dst, ptr->data);
8012 ptr = ptr->next;
8013 }
8014@@ -170,11 +251,21 @@
8015 {
8016 zend_llist_element *element, *next;
8017
8018+#if HARDENING_PATCH_LL_PROTECT
8019+ TSRMLS_FETCH();
8020+ CHECK_LIST_CANARY(l)
8021+#endif
8022 element=l->head;
8023 while (element) {
8024+#if HARDENING_PATCH_LL_PROTECT
8025+ CHECK_LISTELEMENT_CANARY(element, l)
8026+#endif
8027 next = element->next;
8028 if (func(element->data)) {
8029 DEL_LLIST_ELEMENT(element, l);
8030+#if HARDENING_PATCH_LL_PROTECT
8031+ element->canary = 0;
8032+#endif
8033 }
8034 element = next;
8035 }
8036@@ -185,7 +276,13 @@
8037 {
8038 zend_llist_element *element;
8039
8040+#if HARDENING_PATCH_LL_PROTECT
8041+ CHECK_LIST_CANARY(l)
8042+#endif
8043 for (element=l->head; element; element=element->next) {
8044+#if HARDENING_PATCH_LL_PROTECT
8045+ CHECK_LISTELEMENT_CANARY(element, l)
8046+#endif
8047 func(element->data TSRMLS_CC);
8048 }
8049 }
8050@@ -197,6 +294,9 @@
8051 zend_llist_element **elements;
8052 zend_llist_element *element, **ptr;
8053
8054+#if HARDENING_PATCH_LL_PROTECT
8055+ CHECK_LIST_CANARY(l)
8056+#endif
8057 if (l->count <= 0) {
8058 return;
8059 }
8060@@ -206,6 +306,9 @@
8061 ptr = &elements[0];
8062
8063 for (element=l->head; element; element=element->next) {
8064+#if HARDENING_PATCH_LL_PROTECT
8065+ CHECK_LISTELEMENT_CANARY(element, l)
8066+#endif
8067 *ptr++ = element;
8068 }
8069
8070@@ -228,7 +331,13 @@
8071 {
8072 zend_llist_element *element;
8073
8074+#if HARDENING_PATCH_LL_PROTECT
8075+ CHECK_LIST_CANARY(l)
8076+#endif
8077 for (element=l->head; element; element=element->next) {
8078+#if HARDENING_PATCH_LL_PROTECT
8079+ CHECK_LISTELEMENT_CANARY(element, l)
8080+#endif
8081 func(element->data, arg TSRMLS_CC);
8082 }
8083 }
8084@@ -239,8 +348,14 @@
8085 zend_llist_element *element;
8086 va_list args;
8087
8088+#if HARDENING_PATCH_LL_PROTECT
8089+ CHECK_LIST_CANARY(l)
8090+#endif
8091 va_start(args, num_args);
8092 for (element=l->head; element; element=element->next) {
8093+#if HARDENING_PATCH_LL_PROTECT
8094+ CHECK_LISTELEMENT_CANARY(element, l)
8095+#endif
8096 func(element->data, num_args, args TSRMLS_CC);
8097 }
8098 va_end(args);
8099@@ -249,6 +364,10 @@
8100
8101 ZEND_API int zend_llist_count(zend_llist *l)
8102 {
8103+#if HARDENING_PATCH_LL_PROTECT
8104+ TSRMLS_FETCH();
8105+ CHECK_LIST_CANARY(l)
8106+#endif
8107 return l->count;
8108 }
8109
8110@@ -256,8 +375,15 @@
8111 {
8112 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8113
8114+#if HARDENING_PATCH_LL_PROTECT
8115+ TSRMLS_FETCH();
8116+ CHECK_LIST_CANARY(l)
8117+#endif
8118 *current = l->head;
8119 if (*current) {
8120+#if HARDENING_PATCH_LL_PROTECT
8121+ CHECK_LISTELEMENT_CANARY(*current, l)
8122+#endif
8123 return (*current)->data;
8124 } else {
8125 return NULL;
8126@@ -269,8 +395,15 @@
8127 {
8128 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8129
8130+#if HARDENING_PATCH_LL_PROTECT
8131+ TSRMLS_FETCH();
8132+ CHECK_LIST_CANARY(l)
8133+#endif
8134 *current = l->tail;
8135 if (*current) {
8136+#if HARDENING_PATCH_LL_PROTECT
8137+ CHECK_LISTELEMENT_CANARY(*current, l)
8138+#endif
8139 return (*current)->data;
8140 } else {
8141 return NULL;
8142@@ -282,9 +415,19 @@
8143 {
8144 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8145
8146+#if HARDENING_PATCH_LL_PROTECT
8147+ TSRMLS_FETCH();
8148+ CHECK_LIST_CANARY(l)
8149+#endif
8150 if (*current) {
8151+#if HARDENING_PATCH_LL_PROTECT
8152+ CHECK_LISTELEMENT_CANARY(*current, l)
8153+#endif
8154 *current = (*current)->next;
8155 if (*current) {
8156+#if HARDENING_PATCH_LL_PROTECT
8157+ CHECK_LISTELEMENT_CANARY(*current, l)
8158+#endif
8159 return (*current)->data;
8160 }
8161 }
8162@@ -296,9 +439,19 @@
8163 {
8164 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8165
8166+#if HARDENING_PATCH_LL_PROTECT
8167+ TSRMLS_FETCH();
8168+ CHECK_LIST_CANARY(l)
8169+#endif
8170 if (*current) {
8171+#if HARDENING_PATCH_LL_PROTECT
8172+ CHECK_LISTELEMENT_CANARY(*current, l)
8173+#endif
8174 *current = (*current)->prev;
8175 if (*current) {
8176+#if HARDENING_PATCH_LL_PROTECT
8177+ CHECK_LISTELEMENT_CANARY(*current, l)
8178+#endif
8179 return (*current)->data;
8180 }
8181 }
8182diff -Nura php-4.4.4/Zend/zend_llist.h hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h
8183--- php-4.4.4/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100
8184+++ hardening-patch-4.4.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:30:51.000000000 +0200
8185@@ -24,6 +24,9 @@
8186 #include <stdlib.h>
8187
8188 typedef struct _zend_llist_element {
8189+#if HARDENING_PATCH_LL_PROTECT
8190+ unsigned int canary, padding;
8191+#endif
8192 struct _zend_llist_element *next;
8193 struct _zend_llist_element *prev;
8194 char data[1]; /* Needs to always be last in the struct */
8195@@ -36,6 +39,9 @@
8196 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
8197
8198 typedef struct _zend_llist {
8199+#if HARDENING_PATCH_LL_PROTECT
8200+ unsigned int canary_h; /* head */
8201+#endif
8202 zend_llist_element *head;
8203 zend_llist_element *tail;
8204 size_t size;
8205@@ -43,6 +49,9 @@
8206 llist_dtor_func_t dtor;
8207 unsigned char persistent;
8208 zend_llist_element *traverse_ptr;
8209+#if HARDENING_PATCH_LL_PROTECT
8210+ unsigned int canary_t; /* tail */
8211+#endif
8212 } zend_llist;
8213
8214 typedef zend_llist_element* zend_llist_position;
8215diff -Nura php-4.4.4/Zend/zend_modules.h hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h
8216--- php-4.4.4/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100
8217+++ hardening-patch-4.4.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:30:51.000000000 +0200
8218@@ -34,6 +34,7 @@
8219 ZEND_API extern unsigned char second_arg_force_ref[];
8220 ZEND_API extern unsigned char third_arg_force_ref[];
8221
8222+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8223 #define ZEND_MODULE_API_NO 20020429
8224 #ifdef ZTS
8225 #define USING_ZTS 1
8226@@ -41,9 +42,9 @@
8227 #define USING_ZTS 0
8228 #endif
8229
8230-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8231+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8232
8233-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8234+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8235
8236 #define STANDARD_MODULE_PROPERTIES \
8237 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8238@@ -75,6 +76,7 @@
8239 unsigned char type;
8240 void *handle;
8241 int module_number;
8242+ unsigned int real_zend_api;
8243 };
8244
8245
8246diff -Nura php-4.4.4/Zend/zend_opcode.c hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c
8247--- php-4.4.4/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100
8248+++ hardening-patch-4.4.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:30:51.000000000 +0200
8249@@ -88,6 +88,9 @@
8250 op_array->done_pass_two = 0;
8251
8252 op_array->start_op = NULL;
8253+#if HARDENING_PATCH
8254+ op_array->created_by_eval = 0;
8255+#endif
8256
8257 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8258 }
8259diff -Nura php-4.4.4/Zend/zend_operators.c hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c
8260--- php-4.4.4/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100
8261+++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.c 2006-09-05 20:30:51.000000000 +0200
8262@@ -1604,6 +1604,20 @@
8263 return (op->value.lval ? 1 : 0);
8264 }
8265
8266+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8267+{
8268+ register unsigned char *str = (unsigned char*)source;
8269+ register unsigned char *result = (unsigned char*)dest;
8270+ register unsigned char *end = str + length;
8271+
8272+ while (str < end) {
8273+ *result++ = tolower((int)*str++);
8274+ }
8275+ *result = *end;
8276+
8277+ return dest;
8278+}
8279+
8280 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8281 {
8282 register char *p=str, *end=p+length;
8283diff -Nura php-4.4.4/Zend/zend_operators.h hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h
8284--- php-4.4.4/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100
8285+++ hardening-patch-4.4.4-0.4.15/Zend/zend_operators.h 2006-09-05 20:30:51.000000000 +0200
8286@@ -174,6 +174,14 @@
8287 #endif
8288
8289 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8290+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8291+
8292+static inline char *
8293+zend_str_tolower_dup(const char *source, unsigned int length)
8294+{
8295+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8296+}
8297+
8298 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8299 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8300 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);