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