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