summaryrefslogtreecommitdiff
path: root/0.4.15/hardening-patch-5.1.4-0.4.15.patch
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:35:39 +0200
committerjvoisin2019-10-13 12:35:39 +0200
commitd24fe97bf9a1614acf4e7431d17b762a73642e15 (patch)
treeee5a13f40e468ef5ab99e2a4e5d6b601f000fae1 /0.4.15/hardening-patch-5.1.4-0.4.15.patch
parentd3dd0beb0549fbfa1541d3d4e310c861c5a5a53f (diff)
Rename
Diffstat (limited to '0.4.15/hardening-patch-5.1.4-0.4.15.patch')
-rw-r--r--0.4.15/hardening-patch-5.1.4-0.4.15.patch9802
1 files changed, 9802 insertions, 0 deletions
diff --git a/0.4.15/hardening-patch-5.1.4-0.4.15.patch b/0.4.15/hardening-patch-5.1.4-0.4.15.patch
new file mode 100644
index 0000000..6b2eba0
--- /dev/null
+++ b/0.4.15/hardening-patch-5.1.4-0.4.15.patch
@@ -0,0 +1,9802 @@
1diff -Nura php-5.1.4/Changelog.hphp hardening-patch-5.1.4-0.4.15/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.15/Changelog.hphp 2006-09-07 19:32:29.000000000 +0200
4@@ -0,0 +1,61 @@
5+Changelog of the Hardening-Patch
6+--------------------------------
7+
8+0.4.15 - 07. September 2006
9+
10+ PHP4:
11+ [+] Fix for potential DOS in handling of include blacklists
12+
13+ PHP4+5:
14+ [+] Backported a fix for open_basedir problems with insanse PHP scripts
15+ [+] Added a fix for ini_restore() PHP security vulnerability
16+
17+0.4.14 - 11. August 2006
18+
19+ PHP4:
20+ [+] Remove unecessary call to AC_BROKEN_REALPATH
21+
22+ PHP5:
23+ [+] Fix Remote URL Include Protection - Thanks to: Bart Vanbrabant
24+
25+ PHP4+5:
26+ [+] Added a few PHP security fixes / see changelog.secfix for details
27+ [+] Fixed the memory_limit protection for systems with different perdir memory_limits
28+ [+] Fixed a possible memory corruption when foreach() is used with wrong arguments
29+
30+0.4.13 - 07. August 2006
31+
32+ PHP4+5:
33+ [+] Added a fix for a compile problem on solaris due to missing strcasestr()
34+
35+0.4.12 - 19. July 2006
36+
37+ PHP4:
38+ [+] Added fixes from sf4 security patch / see changelog.secfix for details
39+
40+ PHP5:
41+ [+] Added fixes from sf5 security patch / see changelog.secfix for details
42+
43+ PHP4+5:
44+ [+] Added anti mail spam feature
45+ [+] Speedup of zend_hash canary (clear/destroy)
46+ [+] Added a fix for a DOS in the handling of URL blacklists
47+
48+0.4.11 - 13. May 2006
49+
50+ PHP5:
51+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache
52+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4
53+
54+ PHP4+5:
55+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories
56+
57+
58+0.4.10 - 11. May 2006
59+
60+ PHP4:
61+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
62+
63+ PHP4+5:
64+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
65+
66diff -Nura php-5.1.4/Changelog.secfix hardening-patch-5.1.4-0.4.15/Changelog.secfix
67--- php-5.1.4/Changelog.secfix 1970-01-01 01:00:00.000000000 +0100
68+++ hardening-patch-5.1.4-0.4.15/Changelog.secfix 2006-09-05 20:31:02.000000000 +0200
69@@ -0,0 +1,40 @@
70+Changelog of PHP 5.1.4 Security Fixes
71+
72+Release 6 - 11. August 2006
73+
74+ [+] Added IMAP open_basedir/safe_mode check
75+ [+] Added a fix for previous ext/session fixes
76+ [+] Added upstream fix to ext/socket
77+ [+] Added sscanf() security fix
78+ [+] Added fixes for handling of corrupt .gif files to gdlib
79+
80+Release 5 - 13. July 2006
81+
82+ [+] Fixed compilation of Security-Patch Release 4 in ZTS mode
83+
84+Release 4 - 13. July 2006
85+
86+ [+] Added a recursive array printing fix to the phpinfo() XSS fix
87+ [+] Added a fix for stat() on non existing files in safe_mode
88+
89+Release 3 - 07. July 2006
90+
91+ [+] Added a fix for an integer overflow in str_repeat()
92+ [+] Added a *working* wordwrap() fix
93+ [+] Added code to make memory_limit work on 64bit systems
94+ [+] Added a fix for the error_log() safe_mode/open_basedir vulnerability
95+ [+] Added a fix for overlong tempfilename
96+ [+] Added multiple fixes for new safe_mode/open_basedir problems in ext/curl
97+ [+] Added a high characters fix to ext/wddx
98+
99+Release 2 - 16. May 2006
100+
101+ [+] Remove install-pear-nozlib.phar from the patchfile, because the official PHP
102+ tarball got updated
103+
104+Release 1 - 13. May 2006
105+
106+ [+] Bundle install-pear-nozlib.phar which was missing in the official PHP tarball
107+ and is downloaded when make install is called (usually as root -> security risk)
108+ [+] Fixed open_basedir/safe_mode bypass via the realpath() cache
109+
110diff -Nura php-5.1.4/configure hardening-patch-5.1.4-0.4.15/configure
111--- php-5.1.4/configure 2006-05-12 16:41:10.000000000 +0200
112+++ hardening-patch-5.1.4-0.4.15/configure 2006-09-05 20:31:02.000000000 +0200
113@@ -942,6 +942,16 @@
114 ac_help="$ac_help
115 --with-libdir=NAME Look for libraries in .../NAME rather than .../lib"
116 ac_help="$ac_help
117+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
118+ac_help="$ac_help
119+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
120+ac_help="$ac_help
121+ --disable-hardening-patch-inc-protect Disable include/require protection."
122+ac_help="$ac_help
123+ --disable-hardening-patch-fmt-protect Disable format string protection."
124+ac_help="$ac_help
125+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
126+ac_help="$ac_help
127
128 SAPI modules:
129 "
130@@ -1410,6 +1420,8 @@
131 ac_help="$ac_help
132 --enable-wddx Enable WDDX support"
133 ac_help="$ac_help
134+ --disable-varfilter Disable Hardening-Patch's variable filter"
135+ac_help="$ac_help
136 --disable-xml Disable XML support"
137 ac_help="$ac_help
138 --with-libxml-dir=DIR XML: libxml2 install prefix"
139@@ -3618,6 +3630,157 @@
140
141
142
143+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
144+if test "${enable_hardening_patch_mm_protect+set}" = set; then
145+ enableval="$enable_hardening_patch_mm_protect"
146+
147+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
148+
149+else
150+
151+ DO_HARDENING_PATCH_MM_PROTECT=yes
152+
153+fi
154+
155+
156+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
157+if test "${enable_hardening_patch_ll_protect+set}" = set; then
158+ enableval="$enable_hardening_patch_ll_protect"
159+
160+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
161+
162+else
163+
164+ DO_HARDENING_PATCH_LL_PROTECT=yes
165+
166+fi
167+
168+
169+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
170+if test "${enable_hardening_patch_inc_protect+set}" = set; then
171+ enableval="$enable_hardening_patch_inc_protect"
172+
173+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
174+
175+else
176+
177+ DO_HARDENING_PATCH_INC_PROTECT=yes
178+
179+fi
180+
181+
182+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
183+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
184+ enableval="$enable_hardening_patch_fmt_protect"
185+
186+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
187+
188+else
189+
190+ DO_HARDENING_PATCH_FMT_PROTECT=yes
191+
192+fi
193+
194+
195+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
196+if test "${enable_hardening_patch_hash_protect+set}" = set; then
197+ enableval="$enable_hardening_patch_hash_protect"
198+
199+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
200+
201+else
202+
203+ DO_HARDENING_PATCH_HASH_PROTECT=yes
204+
205+fi
206+
207+
208+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
209+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
210+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
211+
212+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
213+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
214+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
215+
216+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
217+echo "configure:2733: checking whether to protect include/require statements" >&5
218+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
219+
220+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
221+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
222+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
223+
224+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
225+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
226+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
227+
228+
229+cat >> confdefs.h <<\EOF
230+#define HARDENING_PATCH 1
231+EOF
232+
233+
234+
235+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
236+ cat >> confdefs.h <<\EOF
237+#define HARDENING_PATCH_MM_PROTECT 1
238+EOF
239+
240+else
241+ cat >> confdefs.h <<\EOF
242+#define HARDENING_PATCH_MM_PROTECT 0
243+EOF
244+
245+fi
246+
247+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
248+ cat >> confdefs.h <<\EOF
249+#define HARDENING_PATCH_LL_PROTECT 1
250+EOF
251+
252+else
253+ cat >> confdefs.h <<\EOF
254+#define HARDENING_PATCH_LL_PROTECT 0
255+EOF
256+
257+fi
258+
259+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
260+ cat >> confdefs.h <<\EOF
261+#define HARDENING_PATCH_INC_PROTECT 1
262+EOF
263+
264+else
265+ cat >> confdefs.h <<\EOF
266+#define HARDENING_PATCH_INC_PROTECT 0
267+EOF
268+
269+fi
270+
271+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
272+ cat >> confdefs.h <<\EOF
273+#define HARDENING_PATCH_FMT_PROTECT 1
274+EOF
275+
276+else
277+ cat >> confdefs.h <<\EOF
278+#define HARDENING_PATCH_FMT_PROTECT 0
279+EOF
280+
281+fi
282+
283+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
284+ cat >> confdefs.h <<\EOF
285+#define HARDENING_PATCH_HASH_PROTECT 1
286+EOF
287+
288+else
289+ cat >> confdefs.h <<\EOF
290+#define HARDENING_PATCH_HASH_PROTECT 0
291+EOF
292+
293+fi
294
295
296
297@@ -18607,6 +18770,62 @@
298 fi
299
300
301+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
302+echo "configure:14928: checking whether realpath is broken" >&5
303+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
304+ echo $ac_n "(cached) $ac_c" 1>&6
305+else
306+
307+ if test "$cross_compiling" = yes; then
308+
309+ ac_cv_broken_realpath=no
310+
311+else
312+ cat > conftest.$ac_ext <<EOF
313+#line 14939 "configure"
314+#include "confdefs.h"
315+
316+main() {
317+ char buf[4096+1];
318+ buf[0] = 0;
319+ realpath("/etc/hosts/../passwd", buf);
320+ exit(strcmp(buf, "/etc/passwd")==0);
321+}
322+
323+EOF
324+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
325+then
326+
327+ ac_cv_broken_realpath=no
328+
329+else
330+ echo "configure: failed program was:" >&5
331+ cat conftest.$ac_ext >&5
332+ rm -fr conftest*
333+
334+ ac_cv_broken_realpath=yes
335+
336+fi
337+rm -fr conftest*
338+fi
339+
340+
341+fi
342+
343+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
344+ if test "$ac_cv_broken_realpath" = "yes"; then
345+ cat >> confdefs.h <<\EOF
346+#define PHP_BROKEN_REALPATH 1
347+EOF
348+
349+ else
350+ cat >> confdefs.h <<\EOF
351+#define PHP_BROKEN_REALPATH 0
352+EOF
353+
354+ fi
355+
356+
357 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
358 echo "configure:18612: checking for declared timezone" >&5
359 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
360@@ -89422,7 +89641,7 @@
361 if test "$ac_cv_crypt_blowfish" = "yes"; then
362 ac_result=1
363 else
364- ac_result=0
365+ ac_result=1
366 fi
367 cat >> confdefs.h <<EOF
368 #define PHP_BLOWFISH_CRYPT $ac_result
369@@ -92022,7 +92241,7 @@
370 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
371 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
372 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
373- filters.c proc_open.c streamsfuncs.c http.c; do
374+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
375
376 IFS=.
377 set $ac_src
378@@ -92081,7 +92300,7 @@
379 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
380 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
381 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
382- filters.c proc_open.c streamsfuncs.c http.c; do
383+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
384
385 IFS=.
386 set $ac_src
387@@ -92211,7 +92430,7 @@
388 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
389 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
390 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
391- filters.c proc_open.c streamsfuncs.c http.c; do
392+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
393
394 IFS=.
395 set $ac_src
396@@ -92266,7 +92485,7 @@
397 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
398 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
399 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
400- filters.c proc_open.c streamsfuncs.c http.c; do
401+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
402
403 IFS=.
404 set $ac_src
405@@ -96101,6 +96320,265 @@
406 fi
407
408
409+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
410+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
411+# Check whether --enable-varfilter or --disable-varfilter was given.
412+if test "${enable_varfilter+set}" = set; then
413+ enableval="$enable_varfilter"
414+ PHP_VARFILTER=$enableval
415+else
416+
417+ PHP_VARFILTER=yes
418+
419+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
420+ PHP_VARFILTER=$PHP_ENABLE_ALL
421+ fi
422+
423+fi
424+
425+
426+
427+ext_output="yes, shared"
428+ext_shared=yes
429+case $PHP_VARFILTER in
430+shared,*)
431+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
432+ ;;
433+shared)
434+ PHP_VARFILTER=yes
435+ ;;
436+no)
437+ ext_output=no
438+ ext_shared=no
439+ ;;
440+*)
441+ ext_output=yes
442+ ext_shared=no
443+ ;;
444+esac
445+
446+
447+
448+echo "$ac_t""$ext_output" 1>&6
449+
450+
451+
452+
453+if test "$PHP_VARFILTER" != "no"; then
454+ cat >> confdefs.h <<\EOF
455+#define HAVE_VARFILTER 1
456+EOF
457+
458+
459+ ext_builddir=ext/varfilter
460+ ext_srcdir=$abs_srcdir/ext/varfilter
461+
462+ ac_extra=
463+
464+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
465+
466+
467+
468+ case ext/varfilter in
469+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
470+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
471+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
472+ esac
473+
474+
475+
476+ b_c_pre=$php_c_pre
477+ b_cxx_pre=$php_cxx_pre
478+ b_c_meta=$php_c_meta
479+ b_cxx_meta=$php_cxx_meta
480+ b_c_post=$php_c_post
481+ b_cxx_post=$php_cxx_post
482+ b_lo=$php_lo
483+
484+
485+ old_IFS=$IFS
486+ for ac_src in varfilter.c; do
487+
488+ IFS=.
489+ set $ac_src
490+ ac_obj=$1
491+ IFS=$old_IFS
492+
493+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
494+
495+ case $ac_src in
496+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
497+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
498+ esac
499+
500+ cat >>Makefile.objects<<EOF
501+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
502+ $ac_comp
503+EOF
504+ done
505+
506+
507+ EXT_STATIC="$EXT_STATIC varfilter"
508+ if test "$ext_shared" != "nocli"; then
509+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
510+ fi
511+ else
512+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
513+
514+ case ext/varfilter in
515+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
516+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
517+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
518+ esac
519+
520+
521+
522+ b_c_pre=$shared_c_pre
523+ b_cxx_pre=$shared_cxx_pre
524+ b_c_meta=$shared_c_meta
525+ b_cxx_meta=$shared_cxx_meta
526+ b_c_post=$shared_c_post
527+ b_cxx_post=$shared_cxx_post
528+ b_lo=$shared_lo
529+
530+
531+ old_IFS=$IFS
532+ for ac_src in varfilter.c; do
533+
534+ IFS=.
535+ set $ac_src
536+ ac_obj=$1
537+ IFS=$old_IFS
538+
539+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
540+
541+ case $ac_src in
542+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
543+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
544+ esac
545+
546+ cat >>Makefile.objects<<EOF
547+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
548+ $ac_comp
549+EOF
550+ done
551+
552+
553+ install_modules="install-modules"
554+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
555+
556+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
557+
558+ cat >>Makefile.objects<<EOF
559+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
560+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
561+
562+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
563+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
564+
565+EOF
566+
567+ cat >> confdefs.h <<EOF
568+#define COMPILE_DL_VARFILTER 1
569+EOF
570+
571+ fi
572+ fi
573+
574+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
575+ if test "$PHP_SAPI" = "cgi"; then
576+
577+
578+ case ext/varfilter in
579+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
580+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
581+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
582+ esac
583+
584+
585+
586+ b_c_pre=$php_c_pre
587+ b_cxx_pre=$php_cxx_pre
588+ b_c_meta=$php_c_meta
589+ b_cxx_meta=$php_cxx_meta
590+ b_c_post=$php_c_post
591+ b_cxx_post=$php_cxx_post
592+ b_lo=$php_lo
593+
594+
595+ old_IFS=$IFS
596+ for ac_src in varfilter.c; do
597+
598+ IFS=.
599+ set $ac_src
600+ ac_obj=$1
601+ IFS=$old_IFS
602+
603+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
604+
605+ case $ac_src in
606+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
607+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
608+ esac
609+
610+ cat >>Makefile.objects<<EOF
611+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
612+ $ac_comp
613+EOF
614+ done
615+
616+
617+ EXT_STATIC="$EXT_STATIC varfilter"
618+ else
619+
620+
621+ case ext/varfilter in
622+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
623+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
624+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
625+ esac
626+
627+
628+
629+ b_c_pre=$php_c_pre
630+ b_cxx_pre=$php_cxx_pre
631+ b_c_meta=$php_c_meta
632+ b_cxx_meta=$php_cxx_meta
633+ b_c_post=$php_c_post
634+ b_cxx_post=$php_cxx_post
635+ b_lo=$php_lo
636+
637+
638+ old_IFS=$IFS
639+ for ac_src in varfilter.c; do
640+
641+ IFS=.
642+ set $ac_src
643+ ac_obj=$1
644+ IFS=$old_IFS
645+
646+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
647+
648+ case $ac_src in
649+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
650+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
651+ esac
652+
653+ cat >>Makefile.objects<<EOF
654+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
655+ $ac_comp
656+EOF
657+ done
658+
659+
660+ fi
661+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
662+ fi
663+
664+ BUILD_DIR="$BUILD_DIR $ext_builddir"
665+
666+
667+fi
668
669
670 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
671@@ -112351,7 +112829,7 @@
672 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
673 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
674 network.c php_open_temporary_file.c php_logos.c \
675- output.c ; do
676+ output.c hardening_patch.c ; do
677
678 IFS=.
679 set $ac_src
680@@ -112596,7 +113074,7 @@
681 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
682 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
683 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
684- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
685+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
686
687 IFS=.
688 set $ac_src
689diff -Nura php-5.1.4/configure.in hardening-patch-5.1.4-0.4.15/configure.in
690--- php-5.1.4/configure.in 2006-05-04 01:30:02.000000000 +0200
691+++ hardening-patch-5.1.4-0.4.15/configure.in 2006-09-05 20:31:02.000000000 +0200
692@@ -209,7 +209,7 @@
693
694 sinclude(Zend/Zend.m4)
695 sinclude(TSRM/tsrm.m4)
696-
697+sinclude(main/hardening_patch.m4)
698
699 divert(2)
700
701@@ -1275,7 +1275,7 @@
702 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
703 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
704 network.c php_open_temporary_file.c php_logos.c \
705- output.c )
706+ output.c hardening_patch.c )
707
708 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
709 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
710@@ -1302,7 +1302,7 @@
711 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
712 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
713 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
714- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
715+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
716
717 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
718 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
719diff -Nura php-5.1.4/ext/curl/interface.c hardening-patch-5.1.4-0.4.15/ext/curl/interface.c
720--- php-5.1.4/ext/curl/interface.c 2006-04-13 13:26:10.000000000 +0200
721+++ hardening-patch-5.1.4-0.4.15/ext/curl/interface.c 2006-09-05 20:31:02.000000000 +0200
722@@ -167,6 +167,11 @@
723 RETURN_FALSE; \
724 } \
725 \
726+ if (php_memnstr(str, tmp_url->path, strlen(tmp_url->path), str + len)) { \
727+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Url '%s' contains unencoded control characters.", str); \
728+ RETURN_FALSE; \
729+ } \
730+ \
731 if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
732 (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
733 ) { \
734@@ -1065,7 +1070,6 @@
735 case CURLOPT_FTPLISTONLY:
736 case CURLOPT_FTPAPPEND:
737 case CURLOPT_NETRC:
738- case CURLOPT_FOLLOWLOCATION:
739 case CURLOPT_PUT:
740 #if CURLOPT_MUTE != 0
741 case CURLOPT_MUTE:
742@@ -1116,6 +1120,16 @@
743 convert_to_long_ex(zvalue);
744 error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
745 break;
746+ case CURLOPT_FOLLOWLOCATION:
747+ convert_to_long_ex(zvalue);
748+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
749+ if (Z_LVAL_PP(zvalue) != 0) {
750+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set");
751+ RETURN_FALSE;
752+ }
753+ }
754+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
755+ break;
756 case CURLOPT_URL:
757 case CURLOPT_PROXY:
758 case CURLOPT_USERPWD:
759diff -Nura php-5.1.4/ext/curl/streams.c hardening-patch-5.1.4-0.4.15/ext/curl/streams.c
760--- php-5.1.4/ext/curl/streams.c 2006-01-01 13:50:01.000000000 +0100
761+++ hardening-patch-5.1.4-0.4.15/ext/curl/streams.c 2006-09-05 20:31:02.000000000 +0200
762@@ -289,7 +289,11 @@
763 curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream);
764
765 /* currently buggy (bug is in curl) */
766- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
767+ if ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) {
768+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0);
769+ } else {
770+ curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
771+ }
772
773 curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr);
774 curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0);
775diff -Nura php-5.1.4/ext/fbsql/php_fbsql.c hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c
776--- php-5.1.4/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100
777+++ hardening-patch-5.1.4-0.4.15/ext/fbsql/php_fbsql.c 2006-09-05 20:31:02.000000000 +0200
778@@ -1925,8 +1925,24 @@
779 }
780 else if (fbcmdErrorsFound(md))
781 {
782+#if HARDENING_PATCH
783+ char* query_copy;
784+ int i;
785+#endif
786 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
787 char* emg = fbcemdAllErrorMessages(emd);
788+#if HARDENING_PATCH
789+ query_copy=estrdup(query_copy);
790+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
791+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
792+ efree(query_copy);
793+ if (HG(hphp_sql_bailout_on_error)) {
794+ free(emg);
795+ fbcemdRelease(emd);
796+ result = 0;
797+ zend_bailout();
798+ }
799+#endif
800 if (FB_SQL_G(generateWarnings))
801 {
802 if (emg)
803diff -Nura php-5.1.4/ext/gd/libgd/gd.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c
804--- php-5.1.4/ext/gd/libgd/gd.c 2005-09-30 22:48:05.000000000 +0200
805+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd.c 2006-09-05 20:31:02.000000000 +0200
806@@ -2161,7 +2161,7 @@
807 for (x = 0; (x < w); x++) {
808 int c = gdImageGetPixel (src, srcX + x, srcY + y);
809 if (c != src->transparent) {
810- gdImageSetPixel (dst, dstX + x, dstY + y, gdTrueColor(src->red[c], src->green[c], src->blue[c]));
811+ gdImageSetPixel(dst, dstX + x, dstY + y, gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]));
812 }
813 }
814 }
815diff -Nura php-5.1.4/ext/gd/libgd/gd_gd2.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c
816--- php-5.1.4/ext/gd/libgd/gd_gd2.c 2005-08-18 14:54:43.000000000 +0200
817+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gd2.c 2006-09-05 20:31:02.000000000 +0200
818@@ -430,6 +430,10 @@
819
820 gdImagePtr im;
821
822+ if (w<1 || h <1) {
823+ return 0;
824+ }
825+
826 /* The next few lines are basically copied from gd2CreateFromFile
827 * we change the file size, so don't want to use the code directly.
828 * but we do need to know the file size.
829diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_in.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c
830--- php-5.1.4/ext/gd/libgd/gd_gif_in.c 2005-09-24 16:39:16.000000000 +0200
831+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_in.c 2006-09-05 20:31:02.000000000 +0200
832@@ -44,7 +44,7 @@
833 #define LOCALCOLORMAP 0x80
834 #define BitSet(byte, bit) (((byte) & (bit)) == (bit))
835
836-#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
837+#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) > 0)
838
839 #define LM_to_uint(a,b) (((b)<<8)|(a))
840
841@@ -147,6 +147,9 @@
842 Background = buf[5];
843 AspectRatio = buf[6];
844
845+ imw = LM_to_uint(buf[0],buf[1]);
846+ imh = LM_to_uint(buf[2],buf[3]);
847+
848 if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
849 if (ReadColorMap(fd, BitPixel, ColorMap)) {
850 return 0;
851@@ -182,14 +185,13 @@
852
853 bitPixel = 1<<((buf[8]&0x07)+1);
854
855- imw = LM_to_uint(buf[4],buf[5]);
856- imh = LM_to_uint(buf[6],buf[7]);
857- if (!(im = gdImageCreate(imw, imh))) {
858- return 0;
859- }
860+ if (!(im = gdImageCreate(imw, imh))) {
861+ return 0;
862+ }
863+
864 im->interlace = BitSet(buf[8], INTERLACE);
865 if (! useGlobalColormap) {
866- if (ReadColorMap(fd, bitPixel, localColorMap)) {
867+ if (ReadColorMap(fd, bitPixel, localColorMap)) {
868 return 0;
869 }
870 ReadImage(im, fd, imw, imh, localColorMap,
871@@ -212,6 +214,10 @@
872 if (!im) {
873 return 0;
874 }
875+ if (!im->colorsTotal) {
876+ gdImageDestroy(im);
877+ return 0;
878+ }
879 /* Check for open colors at the end, so
880 we can reduce colorsTotal and ultimately
881 BitsPerPixel */
882@@ -502,6 +508,18 @@
883 int v;
884 int xpos = 0, ypos = 0, pass = 0;
885 int i;
886+
887+ /*
888+ ** Initialize the Compression routines
889+ */
890+ if (! ReadOK(fd,&c,1)) {
891+ return;
892+ }
893+
894+ if (c > MAX_LWZ_BITS) {
895+ return;
896+ }
897+
898 /* Stash the color map into the image */
899 for (i=0; (i<gdMaxColors); i++) {
900 im->red[i] = cmap[CM_RED][i];
901@@ -511,12 +529,7 @@
902 }
903 /* Many (perhaps most) of these colors will remain marked open. */
904 im->colorsTotal = gdMaxColors;
905- /*
906- ** Initialize the Compression routines
907- */
908- if (! ReadOK(fd,&c,1)) {
909- return;
910- }
911+
912 if (LWZReadByte(fd, TRUE, c) < 0) {
913 return;
914 }
915diff -Nura php-5.1.4/ext/gd/libgd/gd_gif_out.c hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c
916--- php-5.1.4/ext/gd/libgd/gd_gif_out.c 2006-03-13 22:56:38.000000000 +0100
917+++ hardening-patch-5.1.4-0.4.15/ext/gd/libgd/gd_gif_out.c 2006-09-05 20:31:02.000000000 +0200
918@@ -265,9 +265,11 @@
919 int InitCodeSize;
920 int i;
921 GifCtx ctx;
922+
923+ memset(&ctx, 0, sizeof(ctx));
924 ctx.Interlace = GInterlace;
925 ctx.in_count = 1;
926- memset(&ctx, 0, sizeof(ctx));
927+
928 ColorMapSize = 1 << BitsPerPixel;
929
930 RWidth = ctx.Width = GWidth;
931diff -Nura php-5.1.4/ext/gd/tests/bug37346.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif
932--- php-5.1.4/ext/gd/tests/bug37346.gif 1970-01-01 01:00:00.000000000 +0100
933+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.gif 2006-09-05 20:31:02.000000000 +0200
934@@ -0,0 +1,4 @@
935+GIF89a
936+<
937+
938+¿´°É, ÎÒ¶¼Ëµ¹ýÂ˲»ÑÏÁË
939\ Kein Zeilenumbruch am Dateiende.
940diff -Nura php-5.1.4/ext/gd/tests/bug37346.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt
941--- php-5.1.4/ext/gd/tests/bug37346.phpt 1970-01-01 01:00:00.000000000 +0100
942+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37346.phpt 2006-09-05 20:31:02.000000000 +0200
943@@ -0,0 +1,13 @@
944+--TEST--
945+Bug #37346 (gdimagecreatefromgif, bad colormap)
946+--SKIPIF--
947+<?php
948+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
949+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
950+?>
951+--FILE--
952+<?php
953+$im = imagecreatefromgif(dirname(__FILE__) . '/bug37346.gif');
954+?>
955+--EXPECTF--
956+Warning: imagecreatefromgif(): '%sbug37346.gif' is not a valid GIF file in %sbug37346.php on line %d
957diff -Nura php-5.1.4/ext/gd/tests/bug37360.gif hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif
958--- php-5.1.4/ext/gd/tests/bug37360.gif 1970-01-01 01:00:00.000000000 +0100
959+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.gif 2006-09-05 20:31:02.000000000 +0200
960@@ -0,0 +1,469 @@
961+GIF89aK÷ÿ
962+J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ nøìÙàÈN̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ
963+'…®u/ <cN2 $ƒæ£A¢#E¥–ÂYÈ+™¦åJ
964+笊 Ö«Ö¾ò#4é
965+ IŸîj9м`]±SÊ¢ÃÙ>š"¿»ö0Â7
966+]•:<R°ïle‘ úƒR[uÍ8/
967+Ù²»0Ã=Õ4ª$s44:\r‰'|_2€' I¹–€ŽÎâSÍ¡
968+ä$(3Â%™x"ø%e2@æ}{ι럙Íß¾@úT/H! 4EÂRûçìÌ0ƒ*™Iùà?HA{¤Þ:<ÎïQá1Àа ìž) ÕlOä
969+Ø0A ÊWÞõà_3lÊ TQ$  Ò`Öè
970+!t!6(‚Ø€
971+Hlà…?Xc¸¶'BE0¥HYÂ(¬Xˆ5Ä@3pŠO H€
972+H.Ù€FÁH]Ê^0©DàiHÄ 2JUªjU»˜AÆ.ѱø1¬K©Åð‰gÄ@*°ƒ
973+ÚŠÓ? @ˆ‡š·®Tb~xMÊ7ö ˆI8A£ À&¡QœÂa Àü óÐCAÉ0²HñGžÑ
974+#té€ì17ØB
975+@X¤¦Ìf X#ÿ ¶B–qòŒ$4ø h3üÁ`‚fž€- ÐäÙ¶5¿ÝÕ°Ò 7ØhÎ1ù†vP˜ ¤
976+Ì8f‹èÌ n3NÀ@:Ò`.ŒRà LßC¶À³™à;P5°
977+k×Ú d8$nær8
978+9X¹øílÃCdézÆÓ)
979+Ð m§9ÿøí1ŽÞk½
980+J…J(°
981+‰Tc L0X@ð‚Ö\4¨“F,oúFTàƒ BØ ‘ º@0—g¨u’
982+}°m0py @,€ÖqmЂð‡€ÃÀ÷„Mg€
983+@à kà`H,-P‰’H×l•viP{ùV
984+mè kP{1׌A"¸ˆ€‡' DÇqŸV
985+p‹YWÌ Œ@Tà 
986+ýØv€9àæâwpþÐzó3¹)ƒµ¶0pmÒÈ¢€°u°À N@v€ œ€”Zç
987+„Ð’-0„€ öVHà lé ÞÐŒ4× 9P
988+-¹‹ànÐt ׫qÝpšµFSç Œ)ÿ@´p
989+ ³ ¹i~000•æ8 ÅP
990+9~QÀy@~ÐrÖ
991+S
992+“ž'0™GŸÁO _Йh° Ÿ¨ƒŠè Þ 5{Ö’ 0iQ†ØS€]&{åÀ 9Àk™oþX{?ø“¨€]0 ™•5Yw}X¢Tˆ ÿPLÐÁ0’Cà ³0sùLÐ yp@tÄò 
993+3iiÎÐ Ѐj؉=øšŽ–P› À‹P Þf~¯¸‘òù2(à ã¦Y"0-pšø‹è T€Ð’÷§œÀ ±™`qÈ–œ°Ú‰öIu -
994+¡iÀݾ
995+V-ð  pšÜ@œ0«Z
996+逕EÿpP
997+æRš—æ`} õ Ið·ß°x`q×Ö‰ —་ëZ €gm
998+¬ÕYh°³ÿ°›Pž³I.à à‹°{ær±µæ @
999+)Ug6* —¶ßY¼À¸¦„»°÷ËqV°4à
1000+”†³š…
1001+Q Ðm»†ð
1002+‚¼–„LX@DÐ¥ÿ@ë Žø5`}z ¾XŒMŠñ à·ÿà•¤ Ë–àG 0,4qÀ°‹€°ÝàùªZ°€Ý@žQ ÕËÄf†È>hš)@L ë`’@g{
1003+Ñ §àW³Ó&¬
1004+ˆÇ 
1005+ÌŒO° Üq@›ÐtÖ¢–ÿÊ ¤L:§§-PgŠš<HÑz«o‹øûH°ïüÑð\mÄ`ŽÕõ]ÒØDÊöP±-É¿Z
1006+7 7AP‰Ä~‰Ý°à Œ¡p·®1Pfu÷À"jyÂj¢‘0§à`0[ Åúq
1007+×’5lmn¹BsÌ`-;íœð¢à×€]¨¤=‚
1008+0u6m÷Pƒ°“×
1009+P¾Ÿýió=‹O Èm½®Mð!U`lëhËû¤ÀÂ}šÝP
1010+Ԫꃞ¯p†®sàQˆ‘°í¬âÁÙâ¤ÝE
1011+`‚%`õ ñ ‹ æ¢Õ›ï  €7btÏ€¬©¤\ymUkáèM¾¿ÐûJM¯¥ÿ ß²Nhg`-}ù n-ÙÊùÆ ÷ë$<  ¥é ÓÎ ¢þvi½•rüäKšx°RÎàA„ &´IIˆQLøWñ_
1012+4øcBE!E†üváÙI”R8cÙ²%–
1013+⎴hÂ×°¡:@Â,DMÔ„dÖVc¢1U´–üf÷ÿ½X¸íusóaàÁ…'NüÛ,T¸½å ²Ô ,KiÜŒ`$M¨¬³ÒÝ»$+ E—“àtˆ'±ˆì¢¢F8ü%¥Øî7")R0)Ð{ocŠp@ 4°"#¸x¦g9‚–8Éa¥ª(XÊ…5žl…;rXƒ
1014+´Xƒ ˜8ÇðÄ[H}žˆH‰O(bÏ=ø¹"À¡˜©Í.Üœ!
1015+RDȈ‰è‰
1016+ž«Ë°*Âxï5y]­÷Tc–;ÖØ`ƒ 1xa€  “$†KBY»– ÿ¸ÙRÖ·A  ùk°5„qò‚iLaz*Ó ¡á7ÃôhÚ-‘W@y è‰WŽ3|ŠV» )qFÀÃóGÛžqàêÞ¸Á`)«
1017+$lÎ;GÅL‡† Ér=¥åHà ðâfθۆ ž‰!#yÕÕÝõ…&
1018+J馱¬<—~úàx
1019+!mLD`$ibnn‰/ÉàG*†‡À$,Š0$À,¸gñ@iIP¨
1020+µ %U\°!ñ†-j[±¥‰?á…BL耕\ð#
1021+5 Œ?޹IY)ÿZ°Ð8æVÌ2ê½@EÉôâ pÊy Ázh œÀ¯
1022+€ƒ Lq;«2Œ¦;9…
1023+ìÀ'Ã<ƒ ÈsAO7¦iµ„
1024+'Ìlq Ô<à:#Xˆ 4Õ@lvQØÎ c°
1025+¨aZ°[Û,¡*kPh¦˜ð©Cõ]›o‡ƒcÚ1«5ð#!]}CµÂKC
1026+,,Ý™@™:¡$ {˜gÜTbW*ÅRQ
1027+ŒexJLôp‘ÓŠZô³ÿÀ@˜Bþ")ið«
1028+°›Rݱ
1029+@N+qˆ˜¢
1030+êhd8 ÅEÍMH¬á
1031+Š?* [Ö¸i/l—0âœÞ(
1032+Å‚@H?lƒŒ?z°wB?y†YØÈ‡p:—ð-À’—83NH"»?¡š¨
1033+€œœK.ÿìq N@»éI€ ’):X-Ýy¡lªá
1034+Xƒ°‹ & =—h„#è
1035+ˆŒ‹
1036+˜>Î9;
1037+# (GÂË&É£°«Š(XDFôœ ¨@ {
1038+J`M›g°‡y³ +¸°…ª¶J#J§üš{¨
1039+À„ ,¡µ–{ ¡gÀ0
1040+t¹€–-Uì &hÆ9MRfH
1041+xÌ›„A°Y ­íÄ\F,µ(ÚÏ]Ý]PVê!»¥6hɦ)é
1042+XQ I¦>òS
1043+f–@„î1T1†kÄ^L¤+_oÒ-É%s˜ècÀ6. :šÛS*PÐ<f
1044+xŒù¾Ç6.S7™NÖ PXºÿ ´ÏþìÌŠix·Ñí&dÑj|vÚÑAgתoÐÿ¿ª›ª$ˆ!íSÄ
1045+ă["Wn
1046+J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€ L¸°áÈ>K̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ
1047+Ï¢6}#
1048+XLÀ kDq Î4â Ð’ éÄYÑ77@:Á%8@#Ã7njÄ/pµm/Bä\…ØJ
1049+„¼´3œø1ˆ`  ݼm…ÓZÿIîDVûè+ PóÌ2B’ë»HL1Vq$ª<TñjtÏœú¶3¡…(ÎÀ žs’wÈ
1050+;·ÃŒÎ
1051+FPàyÖãœ$J&§<PAp| †q<ƒHÇü„¸$¡/bÕðžSîÑ‹SÁïQ¦ŠCtÈ@„üq®HA7(°otc¥ÐŸ (0 Xh ÿºÁ‰ Ô¡!y臠†GdŠƒœ0`Á¸ A*ÏàÁÀNø $dïP¡sžQ…¼åÏXC8ÂA*`¡Èaþºá-DA .ÀŸœæ
1052+£l¥7ꘃ ¤ I+ÀÄx
1053+)iŒ'0À‹>£_Bd–“9F¸ TÐBÞ°@ƒRœ†.…8ÏX€# ¢-#riW @ à©'²Ñ0X¼HFF•QQË TõÔ¨J½Ä´¨8‚¤<Ã[DÕ$ÑRh!
1054+5òÔ
1055+ª@†T-Á¯Ü@nc›4F`€ |CB9
1056+4åéW´QÈtÇJ‘ntãÐÞÄB\à *è¸Þ¤ã!W@F½;d@
1057+Ø0V±ŠT£0Dµz”CT 
1058+²{€¿
1059+Ò>TM.€
1060+¨\Û,OQJX‹û›=æÄVÀ± 1
1061+v„ƒÀøóN0 †Ð?À
1062+YÐ v °{ßÀ ±H Yà ÂÇ&P ™
1063+GàBäÔ1 À9J³ÿP
1064+3ð
1065+†‘Q@@߀ïDƒ(—êB¥@z­¤j4 dæ'Rk ~á°´E“±õÞ”ÀhÔÿ)ZÝÀ €
1066+û˜d×
1067+Ëÿ÷(
1068
1069+Úp”«ã¨°œc‰@C“œ@xœ
1070+ƒÖ†up4¶E¹Ê 3›¤
1071+ÐTàßÀ
1072+kyÛz
1073+Ï 
1074+}Ç B¤R uà9PwT
1075+FDþ°•6‡°npOW
1076+þP]ôÎåà
1077+‹
1078+?íRUV,ëÜk°žïB‰ÌìSvDß10Pi=Z@PÜ!ÿÃVU_;TÊÂ"n„Fn<K Bq€‚a
1079+þ ÞVà}`ëÔï}Ï
1080+åAÜ]x‰‘Ý@BIJ†‰Îμ­É‘"·;-žaI…J¯Q¥N¥ZÕêU¬YµnåÚÕëW°a·¶H²4O&QjzËAåbžuÛ
1081+þQ¨Ù­dàX8å(Pó`‡æ]`ölÂY,9ìêåÞÝûwðáõB¨.é,D9\¥«…tžAL/z&žj5ïÿÛÆÊºÂ
1082+耓µ(8‚4glàϨ°Ñ>&›tòI'Ÿ©n pvŠÂ¥Õ(Øà½øD¡‚(™@?þø»Ç:4°G ÃV±Á†LøÀ„h#@ ]ÜH-°¸hf´h
1083+¤Œhèp.jÿ„ŠÙ¢ŠƒŠA醊@¤á‚p“(Gµ`ñ(ÿ¡¥C=x†Šõ‚
1084+‡‚œ‚B(Ró¨ÀˆgÚ8Ëú ÔuW^{µŠ‡ož!¤nhˆ$‰6ð¢pŽ " ¶s’‡ &(s¿ žy†ÿ ‚‘@…PPE\ì |áB”n0ø1!,`xƒ
1085+ Ò¸8â ÜœádɨüAõ!N.¨/ªoÜpë  *SM°ë7H=‹ ¾ñgƒwj¤-–í1
1086+žhábÛ³ØÁW˜c–ù» yÆŠó$½À½Õ¨ˆ§+™@W=™À¯kËiãÌmk£ I\a꩟ÿ¦ÎÅî, *ê€ %á ´àæ¢(x f
1087+‚ €|UÚ¨HñÔ4‰Ö€gΠÑgF$ ‹Z¸1‡âø
1088+ %ot* €‰—§z&ˆ 8Ƀ‰¼¢ÂØmˆ`X!*Z0pîý]e$
1089+0Å
1090+BÀ3p–nt@q£c`aö"‰'¥DÈ6V€A¬9Ø
1091+ˈȩ
1092+òe…5Œo*ߨCܬâ²âsß8P\`EQH Àó‘n dMYBîÁ
1093+(`ÂÀ´¦Ó–$ú# *„à ( Ú ÀÊ0¾ˆÀ]ꀗ•Ï¥¨”üA
1094+0Âj“Ê=hq8\ Bd×¼
1095+ÔÕ€? `
1096+ ÖÜ0eDõ‘â|f-éH•8h‘IߨÀO\@¹Ýƒv«)žQ·—HäܰYn†À
1097+€3‚@
1098+Dâ\
1099+“°Ê=.
1100+(QNÁ¸Yi¨U^ùé
1101+àõ<ÞˆBX;bóJÁ"Ây°ÀÖŠZh„7”³NA†*ÿ¨A7*|-HMxUšTS™3ø¢9&°$©¼ágÄ*0ìJ«A
1102+j•3:ïD4· Á/k s ‹´î"ñ„)?A TyÆhí$‚+ˆxÔWy”7RÀÄ Ž±>ÓÖ=u*©‰TbØÓÏ&áé9Ç=äÜ„}ÅŒoH@¶@Ä"ÜPk§•ãâUÂLQS¨ ŒAöLm^/‚ á@co›ÒÄá<¨Âÿ8•…á[áaÙÁ>°} ‚„0ðƒâ3°°Å¬P @än?€Á”Û‚ÐR}àƒ(3„"pàÆ£þXúí= °G ÕAuzì™ Í 'úVÜa³Öoˆè:!>$`i).à‘Æ
1103+ZÀuÕ>ð%øAØS
1104+ŠQ¡ë&Š%œ£˜€$Ëä€ut
1105+|対?C
1106+HÈYl0àm¾Ç¾áÏ3BJq„‹tc —3ÿHˆÂ:²î4nâ~˜¬>Bð‰Éó€*¨Ðï¯{AÏwYDª ²Ž
1107+|D5{ôÿÃïµ—HT‡«™C XAð+Db O»ÖÓÀ "`
1108+‰¦›K¨
1109+f€œ(‡C°…o¨‚Cx6¡Ø€
1110+B¾ãx
1111+*À ãHŸ™é„qˆ¤rà„'ã.
1112+c•uë$”ŠI8…g8;ÿÆP;€BªX‚> )àÖC p595ZQ.¡Èe¢€íó=8‚7ÚþK¥Y*`pb(¸·hrÃÅ€ƒëûC©•€Qƒ8¨
1113+€ŽiÅiƒ Ó9DÈYB
1114+ðÃ^Á‚7Pƒ]LšF|š3œš&PùaÃc\ „ºÞûà ìŒ03°'¸»a
1115+(€¡ÓÆG»‡²
1116+‚Ì!Á<Xƒ è¶ZÊ:¡
1117+ý‡.0¨Å ƒ1€KêÐg ƒ*ÈOôȹ¨2v½#£½ÿ–¡€þt <`Õ]t
1118+óY(+9‘¨<
1119+T8…ÈZ9„1°‡CHŽ
1120+1%„2yýË0  …1Bµ
1121+°3pNà„2vÿ"ð.‚šHU8ÊõŠà
1122+ø€(“~]NF¯‡Ö/—&-øÄcG»Šgƒ°»ˆ€¥fài9üÈ-g€ßj«ìƒ0È*¸ægh€NƲ
1123+SH¶Ã°``¶á Èažø’¾¦N°€Â.g°2ì_C
1124+N?ý…Ãø9Oê)¶ÿ6éC€yI9‚È·}|ó(Èýù¦âÖjê1N
1125+üƒ „
1126+2lèð!Ĉ'R¬hñâÃg89Ã
1127+øºÐ§@4±
1128+
1129+±±J¯¼Šê,¶ÙJdJÒ5 ’&ŒÁ( †õL¥ÚªëÑ"˜† E y&@úºëê{(ÝÔ€ q@¯í{0³]ø;P‰Ø0î§&¸‰0Å´
1130+ žLX ¯Ø`IÅ!£j
1131+JPÇ"`¨"»lÿ¨)î´J½À‚/ë\gš:uF²øÂ;½äª2%Xó‹Ú°åÑQygeg" ',€,5×-RíÔ™"èÊÆ[w}ö„9SWîR/ÔhË >å*ÁEp07ßú•ù³šdmvß…_÷ ¢•%fEþønψ±¶‹!Dzk¾›•-M° ùm>zl“¯öG¡ìrÀœ¤»þX*ØMGê6ˆö:î‘a‡Ý‰ ¬ ¹ ß&%;•È9¿|^òhä2?}[ßÔ}|òÔkÏVâ2ÑqEÛ‹ÿÕ×±‹)ã«?Õ
1132+Èþþ¸’¸«0f¨À“D€*HÄ9À‚{-°‚1NÀØÁ«ÈŸG’.ñM
1133+8
1134+J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK×è³guóêe‰w¯ß¿€ L¸°áÈ+^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãü„¨ ßäƒ~¤‚þ!
1135+áN èø]B0È@ÎDr„5A`1Ž –ò
1136+4´@Ù3þ$ÁŒ;‘DU$D’ÙÊà)8ÃHp‚E8)01HœÔÙÆ æANGä@‹d÷$ÁÃ=#~ÓôÿÒ‚™Ô}«Ï@ê 9lÐ ›»bAEtÃM
1137+ÈîêÌ `ÐË„‹QE#f¸¬Iì_tÏ@Æ] Dê4üÊ&X€
1138+DáB8À^‰Á ~,íaÏðÀCµ "±xÞDIHøöܵ„3)tÃDÀî
1139+Ã\PÀ-G|°Ü
1140+XÀ0ˆ WYtLtÓÍ•TÖÐÑÀ†SJkÐ@
1141+bÏTÑä]÷´ìØXHÂÀËÏ 1)¸B¬±ˆ;ÛgDˆÏ8)4ÿ
1142+:@êË @Þ
1143+Öà‚s­¡
1144+·Ì§N]a¬èQ¿Ô⯱ùq#‹.оU-•uÈéômžñÈ\I’G
1145+Ëx?H°€д¦&D‡Þ¨Ó[Î`D¹‡
1146+Ð.¶˜ÎÀ @/,\À„­Ö庑
1147+,¢´@¤ ÂEÅ@…@¯j¡’ «”Òš…Öa‰š%È4qQ˜#òî ‘ â> üJ Ø IHRX}.t»‘T–’Õ8‚
1148+÷ZK%ã'ßHB2YG4,P€ðµ2#P
1149+tÅO¨Lå•(
1150+$|S:Ösa5°ÞðAé:8¶²O |:û&ùÚ—åņ¬F¡q™¾²°rP
1151+\ÙP/Y±¼чy Ý€lK paJ“aÏH°,ŒÀsç"HŽ#,Ôu€y–cͲ€)@,V ¯ Ï
1152+0uÆ}$Pö}3PG3Q"Ë5„p c§~ñ Z€Fç:ð0˜pÀ ¢Dàpp£A ¢+»BkàzlB€×TR=ÇZk@VÎt%pÝ/TâzXà§çx°°
1153+ ð
1154+² °P†°$epBe
1155+fB‡
1156+3`ó`>ìp ì0
1157+¼`
1158+ãè €# ]0 ó>e°M Ê>ª Ø`c°
1159+«P3P ¢:C&ÑÓò†ÉÓ7ŒI¨ô5pVé× œPK÷GûF£7äÌ ”w)v‚'K€û’;°/S¹o§jŸ©i‡ÌÈ&1œÐEÉsªøæ@ÌR.L04 ? ¦ó`Ö@ÌÀ Ó ¹
1160+
1161+@
1162+…OKF –L(è@…§™´È˜tˆ`[¥Ð¨Ž7£’ë žÔu.œ@H.ÈRZr„l—‘b@NË“¨¤®³‡ü©gi RšcE¤k#)lç
1163+P¼ P» w ²u«¼|{·S
1164+ P¼Å›
1165+QÀ@å ‚S¹ÿxcóW
1166+\`{ÌÅ0D€j
1167+½pçÀ=ødT-€ Û@
1168+s
1169+#
1170+™ÐFßÎ!0d°™BYÁäÊÚš ‡3;¾T𢠣ÊÃÔ:tId%ê©ÓÔ ÷€º»² ß&U-»P?y°)âë19° †Ð–›5 IŠôuÈx%±H=0ðA [‰°©€(º`PÇÆë≰·ÕÐJti`¯ *;© œÐÞAMPÞ6aWƒmE-P ;©ÃÑStB®ÛÙ‚ûÖbÆèö€6‘T^¢`Yí° ‰ØÕè:ºì *2ŽóàQp¾úL´
1171+
1172+ã"`Û 
1173+)ÿDÓ·Ä qµ\«ã
1174+ïðG"¿¿Ô Óôd
1175+ ÿÅ Ø8€@
1176+äI
1177+hù§-ºÁâHa"¯L«{žq"atQAÂðâ
1178+(l¸BÖþ¨qV è æ‡ˆ¤ùÍ£%(@ -
1179+jIbÏt
1180+H–A,)  xš  €ª °ð"@Žˆ‹H@B–  r‰ÊŠ:y£«ß8“7Bµ÷^|Ù"Qï(ø`™ä\ A²q³Â‚‰zÿ©ãK7$óßN:jÀ @$qÀ™bT
1181+“VJ!ô
1182+,±(E:_²Ë”À=½‹äƒ¬ib$1ýÉÁà4ÐM NV0ÒQA Ê)g‚
1183+THÄ:ùxq°&‡B®)Њ–+À…˜[n©€æ(¸<ó”lra½(°úÖ™(±N:
1184+ŒWТ˜’tJQ‡‹´
1185+0%ËL%Ê´’RT`3É3‘Ž´ på°‚
1186+à°B"'aº&XÒŒ¸Cž>6æi@‘9$%ëÂÃlU`w=h·ˆø„®n9ìÄ!Àp‚C¡ð€ E$" a°
1187+(I̼á7܃úÜLJ³@À ú“I
1188+ˆ€‘{¸A((רþ±Ñ™p"2ö¼
1189+UR:o\À2 c nÁ„ãNu
1190+F¹™öžø^*E)Õ©õÄé|~1’–p¢žHqC{R
1191+’R–}M×€Á NI
1192+Ýî!âÁ"3Nò[î„ޤåŽ.\@@•0ÂRÁ£eR€!Ç»žôˆÄå%‡Z@ CüɘgÐ@È>äYüAƒFhêÊ9ü†#ìã
1193+UžXnÑjQÇ[3
1194+HÖ+ß B’@Þ•½-ß0‚½ÏD¾PaÁ”ÂàYQŠlÂÛdëÂnR+ vhœü‘8Ø$‚5c88P&ha…JA6¼Á„??- §^@õŒCô"áúÐ/P
1195+¦Œ[|`sƒF“sÃŽ^á·ûþx'!-ñÊrh±¤òÇ …ãðÇ®¯Î¾rà
1196+KÊoô¡ô§§l¬°fô¦YŒÍD ‚°?è¬ÙC
1197+y¡•ƒÄ•Kh è7rÛ„+tn(.5S°À5ús
1198+
1199+MO)ÄR€Ø7àµ7ˆJÊ’„5Xl@n=‹Cà
1200+¨¦ƒY¿g@’ qŽ
1201+û`Ǽµx ˜4ed†o°2`€[è
1202+x ®Ã6Xu¸VI€Ç­ Ÿ‹0Ùghã„8ƒUØc>N Z–С‚²pw8Ý ô¾I¦Ó[„¬C½`’4I%h5¸T
1203+ñÝg.P5 ‹IÑ`εWuL%èŒè‚q
1204+Xf` –틨ƒ 8ÖR€7ä¿­þa5ã'ˆ¾f¼í á.x½D`؇çN‹C FÔ-…¸o¡[¸n*ÒVÈ¥‚€õjŸ–Ç'
1205+¸r,É/òOí4´€Ã† S䮃M>ó>ùX5—70¨&àmR>äbæÏTvño8 7gFî8°5àoß@ŸòU°
1206+F&'ð{(c/’ÔNöèé; 4à‚g÷tèZÐÞƒ´8˜©æŒä½oð´wQÓ„°yP©°‚ w_pè€ßö}ì‚Ó+Xçÿ~fðO+
1207+(t‹©Ýu€öÍìUA8ò³`½××`¯qÃŒøÐ¥xˆz ¸,ƒu)
1208+2lèð!Ĉ'R¬hñ"Æ…´*0 ð,#È"G’,iòdFº(h©à"lyÖ€€Ëœ Î)Ò'â·> ú`',¢lêô©Ó7U4´€jõ*Ö¬Z+žH”3QÌ™Bžå,«
1209+8Ø0åãÖ¼z›’º“ïÞÀ‚þK—pdÿÚ0BÖlKwU…XEE
1210++°SWLáТ>óx4êÔª)b² !'Æ<ø@Ž,A‰¢O„«ðTš&L`Zmü8òäÊ­~“ØvRP¨j+
1211+Óàƒžóú÷óïŸu’k9` ¦¸YC ÀBeuF"ø7!…Z8Qï¹D ÌÙ¸1eQpÐà…)ª¸"y®×Àö|hc
1212+}dP[""@¡›E÷œ`&hê¹'ŸßÈõ•sµÑQÄ E !Ÿ‰*:¥öå”!‚øRÅ¢•ZZ)ºdÁ@ ²`É¥¡ŠzfW* v¬™1&ä9*¬±òèbK肘Y±y1¢¬½úÚŸ?¸žjA ¯é4Düº,³çA:l€e1†²ÍZ{­q}¨ÀRë’d6b;.¹…U¡ªÝ®) EpP.¼ñj… ¯Ip
1213+¯dË=jiØB|oÓ97ß¡F`‡-6µ¬
1214+rp^ÑrIˆæÔÁb@TÀÔ
1215+EÂ>Å^8¡È”Ä¢D%'Œ“ €@Ã’äB‚ÍLp8ñ"ß°Àz`bXà~E|¢D|¸ž!ŒÁ°Á˜ñ*(r‘!ÏXWK†à‹ˆ€ ؃º¨F…ô¡,CØ… D0“+àfok,"
1216+`³ÄI¦%–$b2I°D`Q&2ÙEÉ> Êm, ° Æ Gl‘ÿ0Ï
1217+ÐOáƒÃ5ÿ¸‹‰R4_ ZDp
1218+.’aö|VJLH‰ÓÎf–R
1219+¦`‚!’vz€‚ì
1220+J´¨Ñ£H“*úŒ (K£JJuáf*$!âYÕ¯`Ã
1221+ÁãÙ³oq˜1òM¬Û·pa>cæÏ¬Ùo ìñh·¯ß¿!T°K˜ÌZ¯€+^Üp‡
1222+uk?«PÂ?BT¼­kÑ‚G’«‹kß΂½8ÊŸÿ¨Ðâ_ 
1223+X a ôM/e6©æJßBX`Q! A%3HÖÆ3ßÐ'˜Kf„;¬Šέ©èH÷œÇ˜:ƒi¥VZ›cÏ
1224+Ú€²gèaD—3g<Ì,pF)Ö'@×|£ãÖµˆ­nPÁ}9ÄÎ…®0A&›È`‹°§$´ 
1225+0úÿA…€•Ð2hD
1226+70˜#$X
1227+`hÄø8†½CÁh‹Ž•„ÜÜ‹X(€•ú“oì  ƒ&`4ŽVÔ¢‘Ä‚úOÅÜc·
1228+ƒ^,T4 üúY¢>›øc‹ˆ@ÔTR¨ÃSoò”#Œ&@Qfµ_ÞpAü€³í@à~EWY9sÙ¥À
1229+‘‚Ý xȹºä Œªš ’ Vbÿ
1230+Ånpb QÐ ä*ôk‚ó«€Z–‚äÿ¤æä”T
1231+®u˜°R"¿ÖmÃ8̲@ìÒ6ø&•V{`Ôl™I€h¼™oWÂŽ{#D ×Jékô†
1232+
1233+U°`E·yýç ïçLpwZ€w4€J(<ÔGˆ
1234+(<TÀ3ÜW
1235+9@ÞÐt©¶F«÷I`†„qÄ"'kàüFšz˜‰ÊÕ ÞP$xw@a©L
1236+„`H+‰è!"ñ ƒ±L5)Qp8(Ø/Ÿ'ƒüIÿ¹þ‰9P˜ËQ0˜GpÂÈDÙR<؉>XP+è¹  ñ KžÝ€#ß·”yiæËÑvÀ )až³Äˆà¥sX
1237+½YúñQÙ‘Ei°þvšL ÷²1+‡@gPÄ\îx•X”馬@×0
1238+• Fà ˆªG°–R«cÑÇ  —¢ÂX
1239+2€8a›±p]‰Zš‰ò”‰('ðW„#—w%8šáÀaЏA2÷Š.€@òÇ/0€K€´à°
1240+œ
1241+X-<C!¬|N—„:¥ç‹‰í…±š¿$p4Ø-]ðñuð :
1242+•x¾Ð¦¾
1243+‘Ä0Ü»P¬^™íÕŸLp·ÑËð V ìp ?ì¼—0
1244+ÈЄü·8yh;ÌÈ&áÀ/.0ZE¬e≖ó
1245+ËËì¼èà  L½† Æ+¡ïf9¥€Êȉ>ëwtûR
1246+ #v±
1247+² :°
1248+½Ð†±1ÓQyÊÿœÓ`F,Ÿw€÷Ó@m€ u.°je€H:@ áìÃ-ÇS=Ì7XúœfÁ
1249+(pJGpýÙ5qÈ}¥À wØÕÆ·õÉ1)
1250+Ô@ÐÍMÇÒ‹ÇF<‹ì÷` xÝu‘¥ÐÌ8©œf–ÁX‰•ˆ¥SŠÅæ &ÔƒŒï­ß0C’¢€Þ‚€jð
1251+ÐP ¼ßÀ Âì߆€
1252+!Ñd#Ûu&ËNj­À  ¹‡Ào’Bœ°#
1253+Š`’`§–([ÈÖp;Î~¢\D ²€—- NNžP*=
1254+˜‹“~ÐÐ ?
1255+”ò÷Á»DVšôñG‡ŽÅSšôH¢@¿ü¸¤®ñ/NÜ ¼0Î$ âKŽ2@ðð¶Aüe
1256+#@ô @ 2pù Üæp˶eP c ԋ󠬑0XžZ«¾à³MÛX< _ŸXŸPÒâùÇü\. 3ïöªÀ3  
1257+ø€_P îón;
1258+ž®
1259+Õðó
1260+äI°FoÊ®1Æ@ñƒÍL.3ÂJ˜0&§ÐŒ=ª=û×ÑãG ¿%ò̤I"´äqÖÒåK˜1eÎŒ‰ #&TH} ÙÓçO A…%ZÔèQ¤I•.eÚ´h
1261+çdค£š]_¾œ  Àkƒ4,®ˆ@€@´iÙˆ +"KŒ ùK
1262+A@œ“&=D¡âæ_À2mbáæF
1263+Ǽ:éÒ¨ Á+4eǰ8%Ë6°WË)RÄÐì="# ï3´è€“F€s† &
1264+( „¡ÁRD ĨÐ µØ
1265+K!o ED2Ë4óL3 ) \Àà #ž¹Cf1OT°äi(¡¤BvQM>˜–¸0*ÿ䡞ᡤ“Ô€!Š ˜l28,ºé¦â2µISM9% o8Ñ¢64SUuUVzs
1266+Üh#q+¶øâã¸`áF4
1267+À¢%q€
1268+Æ|üxä“ÿ‚ áÆ™Fé„0-åDJVà YˆfU2¹D
1269+e12þ» }æ` ÁçKmr¦ï¾oð6×S,ò€¡xåP€Ádç N0#èJì
1270+8`Çþ%ÿˆŽ '¹‡(p„
1271+Ôá‹{d/}Ù!œù' ø€#
1272+*°Âåhtxàt(Àp€&À ¨€"h ¢?Ùh .dá¨Ôìâ×)œ’ª\Ô
1273+)ç‚à-T Ò
1274+kVf„Áz_¡yË[šÏ™À VÍiqœA…Ex¿žî…pˆg8à¿m
1275+€Äi[|äŸÞ!N3ÿþ¯4Á߸k(¡6%
1276+ æv·»À"4°é"YÌ?eÆ$ËäÂZÁbp”]j`¬LĶ {“sRøã¹sŸ÷Z…oHÍÿu
1277+P®ÐkǨ]àÁ™·ÍÇ ÕVà7 ”ð€‡
1278+lÀ
1279+ô¤Èd+hA ×ø8Pðí‚«%çù 5q
1280+'pÄ#q+€£J˜ùƇQ‚('BWÀDÏ­>CTzÛÀÆ"^Ø6¬ƒ`&É7›Ú % 
1281+#”„\ ˆ´¯}ã~ðG 2‰`¬ÂÈu§<ƾÁ T€L4š­°ŽbØ‚F ‚À±¡x?!ã@”  ˆ+X¢ò³o\0×
1282+VØ6ØÏ‹¦³Ý@ëKóúw—_ÿß2&¬—ˆà¿5ȸøÓ8è„x»®‰;Ø?\•Sð?°ø€R`¿mû£Ô¸@…hûóñ‹@4“*Є“±
1283+L8… ‚²³' ?¼87 „ ˜
1284+S°!(«+ºö+¬X‡H`:Žó²Sx†(°ƒÿ€ÌÈŸ
1285+¸‡ÝKH&ƒ­’Ú€ø£Aè„«ÈÒ€P|Éè‚þÉös€n€¿Ô[½Ž˜„þbD‘<˜ J2pw¤É0ÔA$†{èˆoˆ1Ÿ$Ç+Є „É€
1286+hLnSºûNˆL&ÛDb ¹'pK¨
1287+½P©œÖýó/@ó(¸€d5dV`Tf Ð.x<Ó`5DWýû/ÀAE€
1288+°¾nUSõFHíJÐ"¨A-¿>øUÿKE
1289+^¸NØÝ®ù°=¶‚<Ä4Š€ahÓ¾º{87S
1290+°Û¦¼X·8ûQ ~&î‚Q$Š€s\âºëR7£ƒ(î4€Ò¢x
1291+Tà
1292+%Vcº‹
1293+ˆ€8ö0Èb¢xÓ4èW=¾:Mxß¼€ ð§•‚õÔK×Eö–oð©ä©‚ ~Y¯I„"€Í£0…±ÍäoYå±.
1294+ffÚÎ ±˜f+Œ
1295+€
1296+ÓþìôƵÕuæ´ei~ï›((Ú×+ °o…ó(p3ÛRöokƒ
1297+G²ç%çâP°
1298+srŲƒH¶+`ƒª¶süÂsÅò ÷‘" r@Ÿ®.@é<a¦ÇñD§.f æè³
1299+‚ÝMŸ.1äU€
1300+2õ½*r´] ÐnVw'¼íÚ…1qH¯õ¯’q´…+° uo_輻 ö!&vÐôcÿ)Æ}u
1301+”pègÿ¥çÕeæ=
1302+÷`ßs_ðvwGwo+dÛs îzï¨m«Ã Gí~o§*€å.‚P8
1303+wø^"ƒ{N9 w‹g§ \‰ïòŽo§ÿîŸyŽú÷ö…:FywöÒàe~wyvJ¬ûƒƒf§yw²ùó Z×ùÚñó¸‚<z_ZtMR»6ú_ª
1304+J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãÊK·®Ý»xóêÝË·¯ß¿€S}öL°áà #^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺuC®cïT,»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóã}áP‹AìÐ÷À¦eÏÜÓB @à ? €Ð‚F$´ÈØ3þÄa †¢?AA2¶ƒ
1305+{²…'4ü@ÍÕ”J1-k¸ñÆxòP?9BPEb.¥ô3ã´ u ÷`õÕ5ã³@REϼÿjdÌà˜£?I@™T->öÈÓo' IÜtÓmˆ(w¯û.ÀKÄj¶ @F‚P…'5Î5d»’Œ—4îø
1306+ÅÁ„1
1307+ÿ$¡&†. ?ÙC @„x<cq8ô$`BŽo›`‚7ª÷ÞÏHIˆƒOàŠ™Ã—¸aI€X€°v»â?´·g8£ôÓQ’¤Ä…
1308+¸c‡(]M–p &º¢É[c·.!…7Ž€Ví«ƒ !´1ƒF:„=¾Ñ!€âC5…^ÁgèàP…IXÐ,v?Кÿq ” Xàœ‘Ø„I1ã‹ÏøF@4˜¼¢5| ¡±JE^nŒÝø1Ë@€ØÙvùKµÀ-â; ¹lAãøß ÁÊÖ]"è‹\àQÍ<ã z›”ªÐÿ   —!ÚÁýbâŠd‚Pì–àΔ!aÀÈD¥ÀAY|P}´«ç@¡èÓHÌ
1309+¼D{ÿý‡;×¢o¬[
1310+@!ü8l21RXâHƒ5PìDPš
1311+Ù ²‡yxÂ8 P‡m|@D'¸"LñŒ/P‚¹ÈB¶Œ
1312+²‡ô
1313+;= ÐG—çÕL9Ò ‚3rÛ—q "ý¢#bómS"UPoVPö‡ f@q†€ Ë0€
1314+’VÛ
1315+up@à @
1316+p"`6 2ð4‰%€=¤‰q9yPI†‚'£˜ŒFbFø <ð„–À|`pa`Wl` &p
1317+("ß81Pt
1318+ U`X8P3±ã
1319+ÄÈY€°V
1320+ ^p
1321+L@°œp€pØÙ ½
1322+
1323+pI` @` H‡PÛÀÀ Ì`]8òV3G€àÿ 3a
1324+rÏÀ©å``Úh‰ *
1325+ †¬àð… `ÀúÚˆ*@
1326+®öc2³¹˜ ‘,âÙD ¢šµ†ôð¯vJEÀªG¦ã'
1327+Ž R ³{b\Ûµ 0’ÆÛ6ÅÀ>+D®lû¶  p*·åà
1328+œu¼J0@ÂÀö ƒ:&4L` €ÃÅk=8{±mp¼¥lÌÆO
1329+r!0ñ -
1330+* †CPð÷Ð 4Àp½!’}ÉèBÀ Lz&ÇOá6 þ± õ&Aë2$$ÓÅ%M$òLd@«< Š 5÷9(]šÀ =-(àB]Í
1331+àcˆ=¾V
1332+ÔÿŠ-àk`&ÈøŽøÂfNÿë&K)£] ÜV×F"6ð€Ì(L¶Ê² L.oLФW fí½ÑÁ&Â-5 9;¾ÇÛ— ÍÝÆ~  q
1333+¢ª
1334+rÚKøÂ
1335+s¯¬#ß@LºÅúÛcAx% âÂBÀ(l;ÐÚS2‘¶p³ÑÑ`Žp’9|º0ÍnÌa —Ý‚l°
1336+ÅßÀ‰ýá%›g@
1337+¨“`íÈŒ-Po.ŽèÉxßWkÎw0 4]®IsÆþ7 ÇT|°ˆŽ@¶ðÒàçpÍ¡<ʦ`¦
1338+PÕ­¾r¢ UòR22è×}L±@à­üKôðˆ$ ïÂQûàa`’PV€‹°}ºÔÞÐðOPGÞ`0‹c(FÞ‡¨ÿþÐ PÎ’ŒÂoKï­½`ÞNÿŽ"µº1° K`à’@DPÆ.ÀÔLMÄØLÄ`d
1339+N°Cà íþ
1340+q m°@@ðõ‹ë¿ð ~P !ÀÐHl qgÏЂðónO
1341+kàåÿ\» ]aÄä 82\ …Ì ‡ÀéÐú.’Û‰¤·ŠÖAn;`#6Rÿø/̸|¶
1342+Kž %ZÔèQ¤ÏxØãá/©QAcÆL€‘COµnÝzïP!Uª0ã!$H÷¾ ¥8³žqåÎ¥[×.Å. 
1343+@
1344+$"—ëK8$É6+
1345+ŠÂ=.‚á‚ [l¢’"CNçÓ‚C‚0¢Š$^ÃsW^ñtã ú\ñ°‹ý³/IôQT‰&bBåQqRà+xòð!xØ4Öùh#ðVö*×–S¹
1346+‚üŒ°¶Wzëî•CHv_¬(¥±–>a` gLTZj[°‚\ÝåÊ>w’hOÜ7s;dÝ·Ö8¶Cª0‚R{Cy¢üŒ_”Û "EŸè‡ .Æ#G:ä˜ÑÎgŒ
1347+È57 ùàÖ¼]w*ÀÔnÐíu¦½ýZ9„
1348+*ué‚
1349+ x@:ƒX` шnt tÁ-`PŠR 
1350+ÔAç b
1351+È'‰`ƒ ö1²o$¡
1352+±Ñ=S Ån4Âb¤Â¡7 Å7ެ“²å$÷äŠ]çYÓ,úT†Ü#@tŽ´°C—"¤}" ËЩ‚L¢JÄ X
1353+Ñù”CT€ }elBÔ@…r>‡ÿã{B,º¹¯CŒ1D4â?¾q‚øáä¾0ÅÓ&€Ã"A÷äF#°à&P
1354+ù,Á²L'€¢^B>Æ]æ3üaöØsH!CÉ^‹öÎV¬`…È*g|ë‹QáþÑ
1355+çÁƒ—ZùŒCü(ÃP]‚üû7~9 ‰"ð¢Ap€¬ß9e÷Ž2â¹÷™V ÂZ¾9[498‡
1356+‰@ŽÑéÒ*\ä#çÐ7¼£ùQ[S¨Á``…‚³e€‚?b „vq`0É}þóâXWZ‰ 6ØÀhaÌ
1357+â'ÿa}ÊK?šh?i!8ƒÈ;ˆCà
1358+TB0œ3që<ô³!B¬A_¸¼‡˜ÿ»û
1359+øÀ4¬¶‰NæL
1360+x†î켇c OñDa
1361+®` ¾` Î` Þ`î`þ`aa.a>aFÛ€
1362+J´¨Ñ£H“*]Ê´©Ó§P£JJµªÕ«X³jÝʵ«×¯`ÊK¶¬Ù³hÓª]˶­Û·pãf|öL®Ý»5éâÝË·¯ß¿€ L¸°áÈ+^̸±ãÇ#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ
1363+<Ë<" 4ÖxI™ˆH¢£,Áâ^ø@ ɨÂNHâ8Àl ,#øø£\ðPaÎ àpd’\B"Å=< f5RNé<ý˜Ã@–\ry ,[x2€˜bö‹f¶uÃ2Ï|Ãf›I^2gLÒ)&<y®õŠt%#Ë€&‰Ì’†Öù‰¢…Ä5é<CM2:@)’ÈxRi£dz?¤<3Ž+¢üÿ9jPh¥…ˆ¢*YjÜ@]à0+’ex"…©§öê®b½Ò*]¢@£å°4ãÉ·Vj¦Ì‚å믨"Ë¢Îêe¶•"Ú­W |ûŒ ,àJ2[R‹Ž§Ö9ͺ^ÝȯHPcN¸õR ²§þP ¿[=Ãè¯ã<£ƒ°Ô
1364+K¾¨Ë0VKÀó+ÔðMÁ“€ÎœÉî»1VüðŠ?’ Å%# ºô0+_åJ? ÔòL¼#×( °„ièµôlÕ :@3Á+$P 0F“pã%ÖžzƒÓUÁ#:Kã%R °õ
1365+š»*©X3‡‘™HÏ4ªdr #Àd@¢z¡ã^†0”ìÚç”9ÄqPŬA
1366+ªAF vdB_0 °Q ÌcÀ8ÖÅ ¥1.4+Ãp
1367+
1368+x*%ÕPZ$PANJÜ! ýT@Ò Œ,d¡vPDÙà‡k–ê™PthRÌáƒôÀš@ÄP
1369+T
1370+Â`‡ŒR68À$ yà ÏܳúÔ!€B<0‚ €*$ jCT«—‰€À<ðÇ@¾!„$ÄáAÂ?¾‘„¤6 Ì€@ja8¨6¾©…€=4qYœÚáZlÀ¢+ºâpóPE¾ø‘¨g@  ø®;Ì^îÖ7„EHk„$7 ,NBxpˆÕ*½€
1371+m8G0pL#`Oz¬a€/Üb6Â+„8æLþ÷’Ñ‹T @¦ËŒý „ɦ¶5þoÊË=óšO  .(
1372+¸¤ðGêÿÑ ðBð{9¬ŒÄ•³ˆO:\9 ‰úx8BBq§}øš9¿B‚k{a̾¼ÿj9_^FW "î°ŒÓÃ\ D9°Ð,Ü¢
1373+5`v%³`yÏÀ k—Kp¬7X€Î
1374+ß` }ð 8|Ì`vpS*°\
1375+¦ˆíØŽ@ð€äYc¿âU°À ·P
1376+Ѓê¦-Б·;ÿP“-à:6æd.–kå`ŠòÖoª& sè àHGà÷¶þ
1377+k)šÐPyÙÝÑ'™—d°®™‰êXXמ«˜˜€WÀ ,Ú¢é
1378+ŸGðRÚ}
1379+ŽŒpn0“éáaA ¡ÿØ…d`}Zbð¥)€¢(!}w•hª¦¥j€mЭ’À!®áŠ%@€ÔScp
1380+Ñg–jH@¬HÝà Þ
1381+éºÖç< ƒ’ªl÷vi†åp˜Þ°˜­²UPÌ@o×¢ð+GØŽ’ O ®!ð mߤAjßÐ
1382+—«.€·YiU `
1383+N@º€DKœÝÿzÁ`_­
1384+0Y
1385+Ú«
1386+x¨J‚‹±JPùu5'Ù‡
1387+ Œ7!
1388+BÀs
1389+a að ¿[,u¼i†©i¹QPZpÄ8½Ÿêv °’ð‹°Õ|•¿àÑO€ €ë
1390+Ä
1391+Ø¡’ÏP-à
1392+L;®à,:måÎ¥
1393+’‰ŸmðæLÎæmþw÷,¸O@¡ “uå
1394+
1395+µ¦éC@µÁn™Ä¹)
1396+p»ÀàÑ
1397+šj®¥“;é P— ä'Kiy¹QÄ
1398+I°F@IŒÀ‹ž•áÊ®gìå Z0ÅOÿ +ûUðŽc åánØ…#ÚàP
1399+MZ¡ d ê.ZçpìÆ~Í2OzpSP­óaj>I°¾
1400+¡…ÁNcòʼnώ-àÐð-
1401+õâú‚`È]`ˆ›>]9¾—Ì=Ä0 ½àéëÒ€â’
1402+þµõ¿ì«L Ð÷x +PÍGQþê!
1403+"!ع/~ ̿Z
1404+ÓŒ¨uT›0#FL‚ÀD*!ºê„ CD&gǨÀ ‡„èIF,³ÔRFJð"-ÁQdzXmBò0é1fS`&±îvhòÎq&À¢,
1405+ € haÀ- 5ôÐÌPaÿ"J˜eÆ$³6~9s­'\;©¹BúƒK®£³ï3‚!ÜÙaPù–jÏF\ðs 7!Q\sÕ•)]ðUîЂ‘Òtœh<òÔ²¥>™Ž+ªÀîf`š¯>Z¢—
1406+˜I"‰ XõI6„r®güÄ€˜vu÷]]™ ãE~-áŽHœið;Q‹µ'ô1¥*œ]±ÓíΙ ø°Š^„hÁÚ™&pÆÜ¡öLwƒ ܹ^Cv
1407+%È~ÂÜ[ ëÍ@cm Ô+Dîû¶2Pïëw¾@ƒRøŽ²p\ð›²Ýã—¥*
1408+pB}ëÃB7Pƒì­PŒƒû†ˆ8›ÄýŠƒÊ
1409+h€zŒ8iÈ@€[L*X7ˆÏ'
1410+ƒªÞl@€Äÿá,Ñ£T`
1411+æŽ
1412+ü˜3ÊÚùÜÃ&×–†®
1413+Hée<_Æ#Õüƒ xe†¢a }J$p‚éŠ>›Ð‚3šƒf,Hb ò!CŒð%ЀÁ&øg*ϣΊ)Ny” €6êøëT
1414+Ø•(i^sÃ&
1415+=‘}b†­H}ì«`‚ʳi
1416+/Av»¥ò 0´v
1417+À†$ }hcQé Í¨TÛ¨˜ß7êàÈ<ÍP¸O0Aƒ50˜„XÀºlqœ É~nJƒŠÔÐ?ì7*ßÐEWpäZåBa9J‘ƒ2HÁ@”s¬ÃæÔ‰è~ß´ BEÄ
1418+ºXF:@bJ»h:#s4Nx)* <¦½¿QƒN94NÊ<£Ã:X„#p¼âs†ãS©Œñ†Rˆ‚ÆS¹Œq H4$±¿RC˸P¡«¼8¨-x½ƒ+€¼nˆ„ÿƒ¾õ¹€CXA(ã“
1419+°Ç (Ê1b;H‚…b1à:’‰¤–¬ÜÉŒÙBwˆ €•äʪH‚Pº7àĉ 8-C´¤$#ð „$€Ëê/øQb¨?°²›+Æ:p¾¬F/ÚCø
1420+…1È€¢:ƒèÄOØÒDK˜Ð™à;ÄR„1Ø¿ÍÀvÜÉnÀ
1421+q}=ª8 Ut½6ø»H…€MHSœ:
1422+¸Õx•ŽË;£¨×s•%9ПËTS-Š
1423+hØ™N™ à€ U::¥Ð|Õ%:ÈØ)
1424+*ÈÂÅMªžP\&<
1425+á 4:’*6`Øo`¿<ÈÂm^«ÖX Á²]È×dõÕØ
1426+
1427+4_ÀYØÞЉ¾
1428+T@`‘ƒPØ(ˆavŠ®k¨!ð…P8
1429+4vãõ-£êI„Ü¥ã""†J8c=>á®; ø˜ã@nÞ°ƒ4H°ƒFaÞD.]1°€E怨ò¾I>á.ð‚°d @Þäüõ1Ð…
1430\ Kein Zeilenumbruch am Dateiende.
1431diff -Nura php-5.1.4/ext/gd/tests/bug37360.phpt hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt
1432--- php-5.1.4/ext/gd/tests/bug37360.phpt 1970-01-01 01:00:00.000000000 +0100
1433+++ hardening-patch-5.1.4-0.4.15/ext/gd/tests/bug37360.phpt 2006-09-05 20:31:02.000000000 +0200
1434@@ -0,0 +1,14 @@
1435+--TEST--
1436+Bug #37360 (gdimagecreatefromgif, bad image sizes)
1437+--SKIPIF--
1438+<?php
1439+ if (!extension_loaded('gd')) die("skip gd extension not available\n");
1440+ if (!GD_BUNDLED) die('skip external GD libraries always fail');
1441+?>
1442+--FILE--
1443+<?php
1444+$im = imagecreatefromgif(dirname(__FILE__) . '/bug37360.gif');
1445+var_dump($im);
1446+?>
1447+--EXPECTF--
1448+resource(%d) of type (gd)
1449diff -Nura php-5.1.4/ext/imap/php_imap.c hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c
1450--- php-5.1.4/ext/imap/php_imap.c 2006-01-28 09:07:20.000000000 +0100
1451+++ hardening-patch-5.1.4-0.4.15/ext/imap/php_imap.c 2006-09-05 20:31:02.000000000 +0200
1452@@ -26,7 +26,7 @@
1453 | PHP 4.0 updates: Zeev Suraski <zeev@zend.com> |
1454 +----------------------------------------------------------------------+
1455 */
1456-/* $Id: php_imap.c,v 1.208.2.7 2006/01/28 08:07:20 mike Exp $ */
1457+/* $Id: php_imap.c,v 1.208.2.8 2006/08/04 20:31:41 iliaa Exp $ */
1458
1459 #define IMAP41
1460
1461@@ -761,6 +761,13 @@
1462 efree(IMAPG(imap_password));
1463 }
1464
1465+ /* local filename, need to perform open_basedir and safe_mode checks */
1466+ if (Z_STRVAL_PP(mailbox)[0] != '{' &&
1467+ (php_check_open_basedir(Z_STRVAL_PP(mailbox) TSRMLS_CC) ||
1468+ (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(mailbox), NULL, CHECKUID_CHECK_FILE_AND_DIR)))) {
1469+ RETURN_FALSE;
1470+ }
1471+
1472 IMAPG(imap_user) = estrndup(Z_STRVAL_PP(user), Z_STRLEN_PP(user));
1473 IMAPG(imap_password) = estrndup(Z_STRVAL_PP(passwd), Z_STRLEN_PP(passwd));
1474
1475diff -Nura php-5.1.4/ext/mysql/php_mysql.c hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c
1476--- php-5.1.4/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100
1477+++ hardening-patch-5.1.4-0.4.15/ext/mysql/php_mysql.c 2006-09-05 20:31:02.000000000 +0200
1478@@ -1231,6 +1231,8 @@
1479 {
1480 php_mysql_conn *mysql;
1481 MYSQL_RES *mysql_result;
1482+ char *copy_query;
1483+ int i;
1484
1485 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
1486
1487@@ -1281,6 +1283,13 @@
1488 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
1489 }
1490 }
1491+ copy_query = estrdup(Z_STRVAL_PP(query));
1492+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
1493+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
1494+ efree(copy_query);
1495+ if (HG(hphp_sql_bailout_on_error)) {
1496+ zend_bailout();
1497+ }
1498 RETURN_FALSE;
1499 }
1500 #else
1501@@ -1291,6 +1300,13 @@
1502 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
1503 }
1504 }
1505+ copy_query = estrdup(Z_STRVAL_PP(query));
1506+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
1507+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
1508+ efree(copy_query);
1509+ if (HG(hphp_sql_bailout_on_error)) {
1510+ zend_bailout();
1511+ }
1512 RETURN_FALSE;
1513 }
1514 #endif
1515diff -Nura php-5.1.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c
1516--- php-5.1.4/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100
1517+++ hardening-patch-5.1.4-0.4.15/ext/mysqli/mysqli_nonapi.c 2006-09-05 20:31:02.000000000 +0200
1518@@ -184,6 +184,17 @@
1519 if (mysql_real_query(mysql->mysql, query, query_len)) {
1520 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
1521 unsigned int s_errno;
1522+#if HARDENING_PATCH
1523+ char *query_copy = estrdup(query);
1524+ int i;
1525+
1526+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1527+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
1528+ efree(query_copy);
1529+ if (HG(hphp_sql_bailout_on_error)) {
1530+ zend_bailout();
1531+ }
1532+#endif
1533 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1534
1535 /* we have to save error information, cause
1536@@ -234,6 +245,17 @@
1537 MYSQLI_DISABLE_MQ;
1538
1539 if (mysql_real_query(mysql->mysql, query, query_len)) {
1540+#if HARDENING_PATCH
1541+ char *query_copy = estrdup(query);
1542+ int i;
1543+
1544+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1545+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
1546+ efree(query_copy);
1547+ if (HG(hphp_sql_bailout_on_error)) {
1548+ zend_bailout();
1549+ }
1550+#endif
1551 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
1552 RETURN_FALSE;
1553 }
1554diff -Nura php-5.1.4/ext/pgsql/pgsql.c hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c
1555--- php-5.1.4/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200
1556+++ hardening-patch-5.1.4-0.4.15/ext/pgsql/pgsql.c 2006-09-05 20:31:04.000000000 +0200
1557@@ -1152,10 +1152,28 @@
1558 case PGRES_EMPTY_QUERY:
1559 case PGRES_BAD_RESPONSE:
1560 case PGRES_NONFATAL_ERROR:
1561- case PGRES_FATAL_ERROR:
1562- PHP_PQ_ERROR("Query failed: %s", pgsql);
1563- PQclear(pgsql_result);
1564- RETURN_FALSE;
1565+ case PGRES_FATAL_ERROR:
1566+ {
1567+#if HARDENING_PATCH
1568+ int i;
1569+ char *query_copy;
1570+#endif
1571+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
1572+ PQclear(pgsql_result);
1573+#if HARDENING_PATCH
1574+ query_copy = estrdup(Z_STRVAL_PP(query));
1575+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1576+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
1577+ efree(query_copy);
1578+ if (HG(hphp_sql_bailout_on_error)) {
1579+ efree(msgbuf);
1580+ zend_bailout();
1581+ }
1582+#endif
1583+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
1584+ efree(msgbuf);
1585+ RETURN_FALSE;
1586+ }
1587 break;
1588 case PGRES_COMMAND_OK: /* successful command that did not return rows */
1589 default:
1590diff -Nura php-5.1.4/ext/session/mod_files.c hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c
1591--- php-5.1.4/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200
1592+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_files.c 2006-09-05 20:31:04.000000000 +0200
1593@@ -152,6 +152,7 @@
1594
1595 if (!ps_files_valid_key(key)) {
1596 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'");
1597+ PS(invalid_session_id) = 1;
1598 return;
1599 }
1600 if (!ps_files_path_create(buf, sizeof(buf), data, key))
1601@@ -401,7 +402,12 @@
1602 ps_files_close(data);
1603
1604 if (VCWD_UNLINK(buf) == -1) {
1605- return FAILURE;
1606+ /* This is a little safety check for instances when we are dealing with a regenerated session
1607+ * that was not yet written to disk
1608+ */
1609+ if (!VCWD_ACCESS(buf, F_OK)) {
1610+ return FAILURE;
1611+ }
1612 }
1613 }
1614
1615@@ -422,6 +428,35 @@
1616 return SUCCESS;
1617 }
1618
1619+PS_VALIDATE_SID_FUNC(files)
1620+{
1621+ char buf[MAXPATHLEN];
1622+ int fd;
1623+ PS_FILES_DATA;
1624+
1625+ if (!ps_files_valid_key(key)) {
1626+ return FAILURE;
1627+ }
1628+
1629+ if (!PS(use_strict_mode)) {
1630+ return SUCCESS;
1631+ }
1632+
1633+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
1634+ return FAILURE;
1635+ }
1636+
1637+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY,
1638+ data->filemode);
1639+
1640+ if (fd != -1) {
1641+ close(fd);
1642+ return SUCCESS;
1643+ }
1644+
1645+ return FAILURE;
1646+}
1647+
1648 /*
1649 * Local variables:
1650 * tab-width: 4
1651diff -Nura php-5.1.4/ext/session/mod_mm.c hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c
1652--- php-5.1.4/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100
1653+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_mm.c 2006-09-05 20:31:04.000000000 +0200
1654@@ -425,6 +425,42 @@
1655 return SUCCESS;
1656 }
1657
1658+PS_VALIDATE_SID_FUNC(mm)
1659+{
1660+ PS_MM_DATA;
1661+ ps_sd *sd;
1662+ const char *p;
1663+ char c;
1664+ int ret = SUCCESS;
1665+
1666+ for (p = key; (c = *p); p++) {
1667+ /* valid characters are a..z,A..Z,0..9 */
1668+ if (!((c >= 'a' && c <= 'z')
1669+ || (c >= 'A' && c <= 'Z')
1670+ || (c >= '0' && c <= '9')
1671+ || c == ','
1672+ || c == '-')) {
1673+ return FAILURE;
1674+ }
1675+ }
1676+
1677+ if (!PS(use_strict_mode)) {
1678+ return SUCCESS;
1679+ }
1680+
1681+ mm_lock(data->mm, MM_LOCK_RD);
1682+
1683+ sd = ps_sd_lookup(data, key, 0);
1684+ if (sd) {
1685+ mm_unlock(data->mm);
1686+ return SUCCESS;
1687+ }
1688+
1689+ mm_unlock(data->mm);
1690+
1691+ return FAILURE;
1692+}
1693+
1694 #endif
1695
1696 /*
1697diff -Nura php-5.1.4/ext/session/mod_user.c hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c
1698--- php-5.1.4/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100
1699+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.c 2006-09-05 20:31:04.000000000 +0200
1700@@ -23,7 +23,7 @@
1701 #include "mod_user.h"
1702
1703 ps_module ps_mod_user = {
1704- PS_MOD(user)
1705+ PS_MOD_SID(user)
1706 };
1707
1708 #define SESS_ZVAL_LONG(val, a) \
1709@@ -174,6 +174,83 @@
1710 FINISH;
1711 }
1712
1713+PS_CREATE_SID_FUNC(user)
1714+{
1715+ int i;
1716+ char *val = NULL;
1717+ zval *retval;
1718+ ps_user *mdata = PS_GET_MOD_DATA();
1719+
1720+ if (!mdata)
1721+ return estrndup("", 0);
1722+
1723+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
1724+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
1725+ }
1726+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
1727+
1728+ if (retval) {
1729+ if (Z_TYPE_P(retval) == IS_STRING) {
1730+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
1731+ } else {
1732+ val = estrndup("", 0);
1733+ }
1734+ zval_ptr_dtor(&retval);
1735+ } else {
1736+ val = estrndup("", 0);
1737+ }
1738+
1739+ return val;
1740+}
1741+
1742+static int ps_user_valid_key(const char *key TSRMLS_DC)
1743+{
1744+ size_t len;
1745+ const char *p;
1746+ char c;
1747+ int ret = SUCCESS;
1748+
1749+ for (p = key; (c = *p); p++) {
1750+ /* valid characters are a..z,A..Z,0..9 */
1751+ if (!((c >= 'a' && c <= 'z')
1752+ || (c >= 'A' && c <= 'Z')
1753+ || (c >= '0' && c <= '9')
1754+ || c == ','
1755+ || c == '-')) {
1756+ ret = FAILURE;
1757+ break;
1758+ }
1759+ }
1760+
1761+ len = p - key;
1762+
1763+ if (len == 0)
1764+ ret = FAILURE;
1765+
1766+ return ret;
1767+}
1768+
1769+PS_VALIDATE_SID_FUNC(user)
1770+{
1771+ zval *args[1];
1772+ STDVARS;
1773+
1774+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
1775+ return ps_user_valid_key(key TSRMLS_CC);
1776+ }
1777+ SESS_ZVAL_STRING(key, args[0]);
1778+
1779+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1780+
1781+ if (retval) {
1782+ convert_to_long(retval);
1783+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1784+ zval_ptr_dtor(&retval);
1785+ }
1786+
1787+ return ret;
1788+}
1789+
1790 /*
1791 * Local variables:
1792 * tab-width: 4
1793diff -Nura php-5.1.4/ext/session/mod_user.h hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h
1794--- php-5.1.4/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100
1795+++ hardening-patch-5.1.4-0.4.15/ext/session/mod_user.h 2006-09-05 20:31:04.000000000 +0200
1796@@ -22,7 +22,7 @@
1797 #define MOD_USER_H
1798
1799 typedef union {
1800- zval *names[6];
1801+ zval *names[8];
1802 struct {
1803 zval *ps_open;
1804 zval *ps_close;
1805@@ -30,6 +30,8 @@
1806 zval *ps_write;
1807 zval *ps_destroy;
1808 zval *ps_gc;
1809+ zval *ps_create;
1810+ zval *ps_validate;
1811 } name;
1812 } ps_user;
1813
1814diff -Nura php-5.1.4/ext/session/php_session.h hardening-patch-5.1.4-0.4.15/ext/session/php_session.h
1815--- php-5.1.4/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100
1816+++ hardening-patch-5.1.4-0.4.15/ext/session/php_session.h 2006-09-05 20:31:04.000000000 +0200
1817@@ -23,7 +23,7 @@
1818
1819 #include "ext/standard/php_var.h"
1820
1821-#define PHP_SESSION_API 20020330
1822+#define PHP_SESSION_API 20051121
1823
1824 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1825 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1826@@ -32,6 +32,7 @@
1827 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1828 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1829 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1830+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1831
1832 /* default create id function */
1833 PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
1834@@ -45,6 +46,7 @@
1835 int (*s_destroy)(PS_DESTROY_ARGS);
1836 int (*s_gc)(PS_GC_ARGS);
1837 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1838+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1839 } ps_module;
1840
1841 #define PS_GET_MOD_DATA() *mod_data
1842@@ -57,6 +59,7 @@
1843 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1844 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1845 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1846+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1847
1848 #define PS_FUNCS(x) \
1849 PS_OPEN_FUNC(x); \
1850@@ -65,11 +68,12 @@
1851 PS_WRITE_FUNC(x); \
1852 PS_DESTROY_FUNC(x); \
1853 PS_GC_FUNC(x); \
1854- PS_CREATE_SID_FUNC(x)
1855+ PS_CREATE_SID_FUNC(x); \
1856+ PS_VALIDATE_SID_FUNC(x)
1857
1858 #define PS_MOD(x) \
1859 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1860- ps_delete_##x, ps_gc_##x, php_session_create_id
1861+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1862
1863 /* SID enabled module handler definitions */
1864 #define PS_FUNCS_SID(x) \
1865@@ -79,11 +83,12 @@
1866 PS_WRITE_FUNC(x); \
1867 PS_DESTROY_FUNC(x); \
1868 PS_GC_FUNC(x); \
1869- PS_CREATE_SID_FUNC(x)
1870+ PS_CREATE_SID_FUNC(x); \
1871+ PS_VALIDATE_SID(x)
1872
1873 #define PS_MOD_SID(x) \
1874 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1875- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1876+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1877
1878 typedef enum {
1879 php_session_disabled,
1880@@ -120,11 +125,13 @@
1881 zend_bool use_only_cookies;
1882 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1883 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1884+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1885
1886 long hash_func;
1887 long hash_bits_per_character;
1888 int send_cookie;
1889 int define_sid;
1890+ zend_bool invalid_session_id; /* allows the driver to report about an invalid session id and request id regeneration */
1891 } php_ps_globals;
1892
1893 typedef php_ps_globals zend_ps_globals;
1894diff -Nura php-5.1.4/ext/session/session.c hardening-patch-5.1.4-0.4.15/ext/session/session.c
1895--- php-5.1.4/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100
1896+++ hardening-patch-5.1.4-0.4.15/ext/session/session.c 2006-09-05 20:31:04.000000000 +0200
1897@@ -166,6 +166,7 @@
1898 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1899 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1900 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1901+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1902 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1903 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1904 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals)
1905@@ -280,9 +281,13 @@
1906 PHPAPI void php_add_session_var(char *name, size_t namelen TSRMLS_DC)
1907 {
1908 zval **sym_track = NULL;
1909-
1910- zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1,
1911- (void *) &sym_track);
1912+
1913+ IF_SESSION_VARS() {
1914+ zend_hash_find(Z_ARRVAL_P(PS(http_session_vars)), name, namelen + 1,
1915+ (void *) &sym_track);
1916+ } else {
1917+ return;
1918+ }
1919
1920 /*
1921 * Set up a proper reference between $_SESSION["x"] and $x.
1922@@ -758,9 +763,23 @@
1923 return;
1924 }
1925
1926+ /* If there is an ID, use session module to verify it */
1927+ if (PS(id)) {
1928+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1929+ efree(PS(id));
1930+ PS(id) = NULL;
1931+ PS(send_cookie) = 1;
1932+ }
1933+ }
1934+
1935 /* If there is no ID, use session module to create one */
1936- if (!PS(id))
1937+ if (!PS(id)) {
1938+new_session:
1939 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1940+ if (PS(use_cookies)) {
1941+ PS(send_cookie) = 1;
1942+ }
1943+ }
1944
1945 /* Read data */
1946 /* Question: if you create a SID here, should you also try to read data?
1947@@ -769,9 +788,14 @@
1948 * session information
1949 */
1950 php_session_track_init(TSRMLS_C);
1951+ PS(invalid_session_id) = 0;
1952 if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
1953 php_session_decode(val, vallen TSRMLS_CC);
1954 efree(val);
1955+ } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */
1956+ PS(invalid_session_id) = 0;
1957+ efree(PS(id));
1958+ goto new_session;
1959 }
1960 }
1961
1962@@ -1377,22 +1401,29 @@
1963 }
1964 /* }}} */
1965
1966-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1967+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1968 Sets user-level functions */
1969 PHP_FUNCTION(session_set_save_handler)
1970 {
1971- zval **args[6];
1972- int i;
1973+ zval **args[8];
1974+ int i, numargs;
1975 ps_user *mdata;
1976 char *name;
1977
1978- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1979+ numargs = ZEND_NUM_ARGS();
1980+ args[6] = NULL;
1981+ args[7] = NULL;
1982+
1983+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1984 WRONG_PARAM_COUNT;
1985
1986 if (PS(session_status) != php_session_none)
1987 RETURN_FALSE;
1988
1989- for (i = 0; i < 6; i++) {
1990+ for (i = 0; i < 8; i++) {
1991+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1992+ continue;
1993+ }
1994 if (!zend_is_callable(*args[i], 0, &name)) {
1995 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1996 efree(name);
1997@@ -1405,7 +1436,11 @@
1998
1999 mdata = emalloc(sizeof(*mdata));
2000
2001- for (i = 0; i < 6; i++) {
2002+ for (i = 0; i < 8; i++) {
2003+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
2004+ mdata->names[i] = NULL;
2005+ continue;
2006+ }
2007 ZVAL_ADDREF(*args[i]);
2008 mdata->names[i] = *args[i];
2009 }
2010@@ -1475,6 +1510,11 @@
2011 WRONG_PARAM_COUNT;
2012 }
2013
2014+ if (SG(headers_sent)) {
2015+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
2016+ RETURN_FALSE;
2017+ }
2018+
2019 if (PS(session_status) == php_session_active) {
2020 if (PS(id)) {
2021 if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
2022@@ -1531,8 +1571,8 @@
2023 WRONG_PARAM_COUNT;
2024
2025 if (ac == 1) {
2026- convert_to_long_ex(p_cache_expire);
2027- PS(cache_expire) = Z_LVAL_PP(p_cache_expire);
2028+ convert_to_string_ex(p_cache_expire);
2029+ zend_alter_ini_entry("session.cache_expire", sizeof("session.cache_expire"), Z_STRVAL_PP(p_cache_expire), Z_STRLEN_PP(p_cache_expire), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
2030 }
2031
2032 RETVAL_LONG(old);
2033diff -Nura php-5.1.4/ext/session/tests/014.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt
2034--- php-5.1.4/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200
2035+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/014.phpt 2006-09-05 20:31:04.000000000 +0200
2036@@ -5,6 +5,7 @@
2037 --INI--
2038 session.use_trans_sid=1
2039 session.use_cookies=0
2040+session.use_strict_mode=0
2041 session.cache_limiter=
2042 register_globals=1
2043 session.bug_compat_42=1
2044diff -Nura php-5.1.4/ext/session/tests/015.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt
2045--- php-5.1.4/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200
2046+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/015.phpt 2006-09-05 20:31:04.000000000 +0200
2047@@ -5,6 +5,7 @@
2048 --INI--
2049 session.use_trans_sid=1
2050 session.use_cookies=0
2051+session.use_strict_mode=0
2052 session.cache_limiter=
2053 arg_separator.output=&
2054 session.name=PHPSESSID
2055diff -Nura php-5.1.4/ext/session/tests/018.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt
2056--- php-5.1.4/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200
2057+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/018.phpt 2006-09-05 20:31:04.000000000 +0200
2058@@ -4,6 +4,7 @@
2059 <?php include('skipif.inc'); ?>
2060 --INI--
2061 session.use_cookies=0
2062+session.use_strict_mode=0
2063 session.cache_limiter=
2064 session.use_trans_sid=1
2065 session.name=PHPSESSID
2066diff -Nura php-5.1.4/ext/session/tests/019.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt
2067--- php-5.1.4/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200
2068+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/019.phpt 2006-09-05 20:31:04.000000000 +0200
2069@@ -4,6 +4,7 @@
2070 <?php include('skipif.inc'); ?>
2071 --INI--
2072 session.use_cookies=0
2073+session.use_strict_mode=0
2074 session.cache_limiter=
2075 register_globals=1
2076 session.serialize_handler=php
2077diff -Nura php-5.1.4/ext/session/tests/020.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt
2078--- php-5.1.4/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200
2079+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/020.phpt 2006-09-05 20:31:04.000000000 +0200
2080@@ -4,6 +4,7 @@
2081 <?php include('skipif.inc'); ?>
2082 --INI--
2083 session.use_cookies=0
2084+session.use_strict_mode=0
2085 session.cache_limiter=
2086 session.use_trans_sid=1
2087 arg_separator.output=&amp;
2088diff -Nura php-5.1.4/ext/session/tests/021.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt
2089--- php-5.1.4/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200
2090+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/021.phpt 2006-09-05 20:31:04.000000000 +0200
2091@@ -4,6 +4,7 @@
2092 <?php include('skipif.inc'); ?>
2093 --INI--
2094 session.use_cookies=0
2095+session.use_strict_mode=0
2096 session.cache_limiter=
2097 session.use_trans_sid=1
2098 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
2099diff -Nura php-5.1.4/ext/session/tests/bug38377.phpt hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt
2100--- php-5.1.4/ext/session/tests/bug38377.phpt 1970-01-01 01:00:00.000000000 +0100
2101+++ hardening-patch-5.1.4-0.4.15/ext/session/tests/bug38377.phpt 2006-09-05 20:31:04.000000000 +0200
2102@@ -0,0 +1,13 @@
2103+--TEST--
2104+bug #38377 (session_destroy() gives warning after session_regenerate_id())
2105+--SKIPIF--
2106+<?php include('skipif.inc'); ?>
2107+--FILE--
2108+<?php
2109+session_start();
2110+session_regenerate_id();
2111+session_destroy();
2112+echo "Done\n";
2113+?>
2114+--EXPECT--
2115+Done
2116diff -Nura php-5.1.4/ext/sockets/sockets.c hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c
2117--- php-5.1.4/ext/sockets/sockets.c 2006-04-07 16:04:36.000000000 +0200
2118+++ hardening-patch-5.1.4-0.4.15/ext/sockets/sockets.c 2006-09-05 20:31:04.000000000 +0200
2119@@ -533,6 +533,7 @@
2120 {
2121 zval **element;
2122 php_socket *php_sock;
2123+ int num = 0;
2124
2125 if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0;
2126
2127@@ -547,9 +548,10 @@
2128 if (php_sock->bsd_socket > *max_fd) {
2129 *max_fd = php_sock->bsd_socket;
2130 }
2131+ num++;
2132 }
2133
2134- return 1;
2135+ return num ? 1 : 0;
2136 }
2137
2138 static int php_sock_array_from_fd_set(zval *sock_array, fd_set *fds TSRMLS_DC)
2139@@ -558,6 +560,7 @@
2140 zval **dest_element;
2141 php_socket *php_sock;
2142 HashTable *new_hash;
2143+ int num = 0;
2144
2145 if (Z_TYPE_P(sock_array) != IS_ARRAY) return 0;
2146
2147@@ -575,6 +578,7 @@
2148 zend_hash_next_index_insert(new_hash, (void *)element, sizeof(zval *), (void **)&dest_element);
2149 if (dest_element) zval_add_ref(dest_element);
2150 }
2151+ num++;
2152 }
2153
2154 /* Destroy old array, add new one */
2155@@ -584,7 +588,7 @@
2156 zend_hash_internal_pointer_reset(new_hash);
2157 Z_ARRVAL_P(sock_array) = new_hash;
2158
2159- return 1;
2160+ return num ? 1 : 0;
2161 }
2162
2163 /* {{{ proto int socket_select(array &read_fds, array &write_fds, &array except_fds, int tv_sec[, int tv_usec])
2164diff -Nura php-5.1.4/ext/sqlite/sess_sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c
2165--- php-5.1.4/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100
2166+++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sess_sqlite.c 2006-09-05 20:31:04.000000000 +0200
2167@@ -185,6 +185,76 @@
2168 return SQLITE_RETVAL(rv);
2169 }
2170
2171+PS_VALIDATE_SID_FUNC(sqlite)
2172+{
2173+ PS_SQLITE_DATA;
2174+ char *query;
2175+ const char *tail;
2176+ sqlite_vm *vm;
2177+ int colcount, result;
2178+ const char **rowdata, **colnames;
2179+ char *error;
2180+ size_t len;
2181+ const char *p;
2182+ char c;
2183+ int ret = FAILURE;
2184+
2185+ for (p = key; (c = *p); p++) {
2186+ /* valid characters are a..z,A..Z,0..9 */
2187+ if (!((c >= 'a' && c <= 'z')
2188+ || (c >= 'A' && c <= 'Z')
2189+ || (c >= '0' && c <= '9')
2190+ || c == ','
2191+ || c == '-')) {
2192+ return FAILURE;
2193+ break;
2194+ }
2195+ }
2196+
2197+ len = p - key;
2198+
2199+ if (len == 0)
2200+ return FAILURE;
2201+
2202+ if (!PS(use_strict_mode)) {
2203+ return SUCCESS;
2204+ }
2205+
2206+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
2207+ if (query == NULL) {
2208+ /* no memory */
2209+ return FAILURE;
2210+ }
2211+
2212+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
2213+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error);
2214+ sqlite_freemem(error);
2215+ sqlite_freemem(query);
2216+ return FAILURE;
2217+ }
2218+
2219+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
2220+ case SQLITE_ROW:
2221+ if (rowdata[0] != NULL) {
2222+ ret = SUCCESS;
2223+ }
2224+ break;
2225+ default:
2226+ sqlite_freemem(error);
2227+ error = NULL;
2228+ }
2229+
2230+ if (SQLITE_OK != sqlite_finalize(vm, &error)) {
2231+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error);
2232+ sqlite_freemem(error);
2233+ error = NULL;
2234+ }
2235+
2236+ sqlite_freemem(query);
2237+
2238+ return ret;
2239+}
2240+
2241 #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
2242
2243 /*
2244diff -Nura php-5.1.4/ext/sqlite/sqlite.c hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c
2245--- php-5.1.4/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200
2246+++ hardening-patch-5.1.4-0.4.15/ext/sqlite/sqlite.c 2006-09-05 20:31:04.000000000 +0200
2247@@ -1530,6 +1530,19 @@
2248 db->last_err_code = ret;
2249
2250 if (ret != SQLITE_OK) {
2251+#if HARDENING_PATCH
2252+ char *query_copy;
2253+ int i;
2254+
2255+ query_copy = estrdup(sql);
2256+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
2257+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
2258+ efree(query_copy);
2259+ if (HG(hphp_sql_bailout_on_error)) {
2260+ sqlite_freemem(errtext);
2261+ zend_bailout();
2262+ }
2263+#endif
2264 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
2265 if (errmsg) {
2266 ZVAL_STRING(errmsg, errtext, 1);
2267diff -Nura php-5.1.4/ext/standard/array.c hardening-patch-5.1.4-0.4.15/ext/standard/array.c
2268--- php-5.1.4/ext/standard/array.c 2006-04-12 21:30:52.000000000 +0200
2269+++ hardening-patch-5.1.4-0.4.15/ext/standard/array.c 2006-09-05 20:31:04.000000000 +0200
2270@@ -92,6 +92,8 @@
2271
2272 #define DOUBLE_DRIFT_FIX 0.000000000000001
2273
2274+ZEND_DECLARE_MODULE_GLOBALS(array)
2275+
2276 /* {{{ php_array_init_globals
2277 */
2278 static void php_array_init_globals(zend_array_globals *array_globals)
2279@@ -1295,6 +1297,32 @@
2280 }
2281 }
2282 }
2283+
2284+ if (var_name[0] == 'H') {
2285+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
2286+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
2287+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
2288+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
2289+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
2290+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
2291+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
2292+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
2293+ return 0;
2294+ }
2295+ } else if (var_name[0] == '_') {
2296+ if ((strcmp(var_name, "_COOKIE")==0)||
2297+ (strcmp(var_name, "_ENV")==0)||
2298+ (strcmp(var_name, "_FILES")==0)||
2299+ (strcmp(var_name, "_GET")==0)||
2300+ (strcmp(var_name, "_POST")==0)||
2301+ (strcmp(var_name, "_REQUEST")==0)||
2302+ (strcmp(var_name, "_SESSION")==0)||
2303+ (strcmp(var_name, "_SERVER")==0)) {
2304+ return 0;
2305+ }
2306+ } else if (strcmp(var_name, "GLOBALS")==0) {
2307+ return 0;
2308+ }
2309
2310 return 1;
2311 }
2312diff -Nura php-5.1.4/ext/standard/basic_functions.c hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c
2313--- php-5.1.4/ext/standard/basic_functions.c 2006-04-03 15:46:11.000000000 +0200
2314+++ hardening-patch-5.1.4-0.4.15/ext/standard/basic_functions.c 2006-09-07 19:34:44.000000000 +0200
2315@@ -151,12 +151,14 @@
2316 typedef struct _php_shutdown_function_entry {
2317 zval **arguments;
2318 int arg_count;
2319+ zend_bool created_by_eval;
2320 } php_shutdown_function_entry;
2321
2322 typedef struct _user_tick_function_entry {
2323 zval **arguments;
2324 int arg_count;
2325 int calling;
2326+ zend_bool created_by_eval;
2327 } user_tick_function_entry;
2328
2329 /* some prototypes for local functions */
2330@@ -188,6 +190,8 @@
2331 PHP_FE(get_html_translation_table, NULL)
2332 PHP_FE(sha1, NULL)
2333 PHP_FE(sha1_file, NULL)
2334+ PHP_FE(sha256, NULL)
2335+ PHP_FE(sha256_file, NULL)
2336 PHP_NAMED_FE(md5,php_if_md5, NULL)
2337 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
2338 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
2339@@ -632,7 +636,7 @@
2340 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
2341
2342 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2343- PHP_FE(realpath, NULL)
2344+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
2345 #endif
2346
2347 #ifdef HAVE_FNMATCH
2348@@ -2034,7 +2038,7 @@
2349 break;
2350
2351 case 3: /*save to a file */
2352- stream = php_stream_open_wrapper(opt, "a", IGNORE_URL | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
2353+ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL);
2354 if (!stream)
2355 return FAILURE;
2356 php_stream_write(stream, message, strlen(message));
2357@@ -2279,6 +2283,13 @@
2358 {
2359 zval retval;
2360 char *function_name = NULL;
2361+#if HARDENING_PATCH
2362+ zend_uint orig_code_type = EG(in_code_type);
2363+
2364+ if (shutdown_function_entry->created_by_eval) {
2365+ EG(in_code_type) = ZEND_EVAL_CODE;
2366+ }
2367+#endif
2368
2369 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
2370 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
2371@@ -2294,6 +2305,9 @@
2372 if (function_name) {
2373 efree(function_name);
2374 }
2375+#if HARDENING_PATCH
2376+ EG(in_code_type) = orig_code_type;
2377+#endif
2378 return 0;
2379 }
2380
2381@@ -2301,6 +2315,13 @@
2382 {
2383 zval retval;
2384 zval *function = tick_fe->arguments[0];
2385+#if HARDENING_PATCH
2386+ zend_uint orig_code_type = EG(in_code_type);
2387+
2388+ if (tick_fe->created_by_eval) {
2389+ EG(in_code_type) = ZEND_EVAL_CODE;
2390+ }
2391+#endif
2392
2393 /* Prevent reentrant calls to the same user ticks function */
2394 if (! tick_fe->calling) {
2395@@ -2332,6 +2353,9 @@
2396
2397 tick_fe->calling = 0;
2398 }
2399+#if HARDENING_PATCH
2400+ EG(in_code_type) = orig_code_type;
2401+#endif
2402 }
2403
2404 static void run_user_tick_functions(int tick_count)
2405@@ -2395,6 +2419,13 @@
2406 }
2407
2408 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
2409+#if HARDENING_PATCH
2410+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
2411+ shutdown_function_entry.created_by_eval = 1;
2412+ } else {
2413+ shutdown_function_entry.created_by_eval = 0;
2414+ }
2415+#endif
2416
2417 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
2418 efree(shutdown_function_entry.arguments);
2419@@ -2722,6 +2753,15 @@
2420
2421 convert_to_string_ex(varname);
2422
2423+ /* checks that ensure the user does not overwrite certain ini settings when safe_mode is enabled */
2424+ if (PG(safe_mode)) {
2425+ if (!strncmp("max_execution_time", Z_STRVAL_PP(varname), sizeof("max_execution_time")) ||
2426+ !strncmp("memory_limit", Z_STRVAL_PP(varname), sizeof("memory_limit")) ||
2427+ !strncmp("child_terminate", Z_STRVAL_PP(varname), sizeof("child_terminate"))) {
2428+ RETURN_FALSE;
2429+ }
2430+ }
2431+
2432 zend_restore_ini_entry(Z_STRVAL_PP(varname), Z_STRLEN_PP(varname)+1, PHP_INI_STAGE_RUNTIME);
2433 }
2434 /* }}} */
2435@@ -2979,6 +3019,13 @@
2436 }
2437
2438 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
2439+#if HARDENING_PATCH
2440+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
2441+ tick_fe.created_by_eval = 1;
2442+ } else {
2443+ tick_fe.created_by_eval = 0;
2444+ }
2445+#endif
2446
2447 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
2448 efree(tick_fe.arguments);
2449@@ -3282,6 +3329,35 @@
2450 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
2451 }
2452
2453+ if (new_key[0] == 'H') {
2454+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
2455+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
2456+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
2457+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
2458+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
2459+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
2460+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
2461+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
2462+ efree(new_key);
2463+ return 0;
2464+ }
2465+ } else if (new_key[0] == '_') {
2466+ if ((strcmp(new_key, "_COOKIE")==0)||
2467+ (strcmp(new_key, "_ENV")==0)||
2468+ (strcmp(new_key, "_FILES")==0)||
2469+ (strcmp(new_key, "_GET")==0)||
2470+ (strcmp(new_key, "_POST")==0)||
2471+ (strcmp(new_key, "_REQUEST")==0)||
2472+ (strcmp(new_key, "_SESSION")==0)||
2473+ (strcmp(new_key, "_SERVER")==0)) {
2474+ efree(new_key);
2475+ return 0;
2476+ }
2477+ } else if (strcmp(new_key, "GLOBALS")==0) {
2478+ efree(new_key);
2479+ return 0;
2480+ }
2481+
2482 zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC);
2483 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
2484
2485diff -Nura php-5.1.4/ext/standard/config.m4 hardening-patch-5.1.4-0.4.15/ext/standard/config.m4
2486--- php-5.1.4/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100
2487+++ hardening-patch-5.1.4-0.4.15/ext/standard/config.m4 2006-09-05 20:31:04.000000000 +0200
2488@@ -203,7 +203,7 @@
2489 if test "$ac_cv_crypt_blowfish" = "yes"; then
2490 ac_result=1
2491 else
2492- ac_result=0
2493+ ac_result=1
2494 fi
2495 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
2496 ])
2497@@ -489,7 +489,7 @@
2498 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
2499 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
2500 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
2501- filters.c proc_open.c streamsfuncs.c http.c)
2502+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
2503
2504 PHP_ADD_MAKEFILE_FRAGMENT
2505
2506diff -Nura php-5.1.4/ext/standard/config.w32 hardening-patch-5.1.4-0.4.15/ext/standard/config.w32
2507--- php-5.1.4/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100
2508+++ hardening-patch-5.1.4-0.4.15/ext/standard/config.w32 2006-09-05 20:31:04.000000000 +0200
2509@@ -16,5 +16,5 @@
2510 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
2511 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
2512 user_filters.c uuencode.c filters.c proc_open.c \
2513- streamsfuncs.c http.c", false /* never shared */);
2514+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
2515
2516diff -Nura php-5.1.4/ext/standard/crypt_blowfish.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c
2517--- php-5.1.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
2518+++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt_blowfish.c 2006-09-05 20:31:04.000000000 +0200
2519@@ -0,0 +1,748 @@
2520+/*
2521+ * This code comes from John the Ripper password cracker, with reentrant
2522+ * and crypt(3) interfaces added, but optimizations specific to password
2523+ * cracking removed.
2524+ *
2525+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
2526+ * placed in the public domain.
2527+ *
2528+ * There's absolutely no warranty.
2529+ *
2530+ * It is my intent that you should be able to use this on your system,
2531+ * as a part of a software package, or anywhere else to improve security,
2532+ * ensure compatibility, or for any other purpose. I would appreciate
2533+ * it if you give credit where it is due and keep your modifications in
2534+ * the public domain as well, but I don't require that in order to let
2535+ * you place this code and any modifications you make under a license
2536+ * of your choice.
2537+ *
2538+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
2539+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
2540+ * ideas. The password hashing algorithm was designed by David Mazieres
2541+ * <dm at lcs.mit.edu>.
2542+ *
2543+ * There's a paper on the algorithm that explains its design decisions:
2544+ *
2545+ * http://www.usenix.org/events/usenix99/provos.html
2546+ *
2547+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
2548+ * Blowfish library (I can't be sure if I would think of something if I
2549+ * hadn't seen his code).
2550+ */
2551+
2552+#include <string.h>
2553+
2554+#include <errno.h>
2555+#ifndef __set_errno
2556+#define __set_errno(val) errno = (val)
2557+#endif
2558+
2559+#undef __CONST
2560+#ifdef __GNUC__
2561+#define __CONST __const
2562+#else
2563+#define __CONST
2564+#endif
2565+
2566+#ifdef __i386__
2567+#define BF_ASM 0
2568+#define BF_SCALE 1
2569+#elif defined(__alpha__) || defined(__hppa__)
2570+#define BF_ASM 0
2571+#define BF_SCALE 1
2572+#else
2573+#define BF_ASM 0
2574+#define BF_SCALE 0
2575+#endif
2576+
2577+typedef unsigned int BF_word;
2578+
2579+/* Number of Blowfish rounds, this is also hardcoded into a few places */
2580+#define BF_N 16
2581+
2582+typedef BF_word BF_key[BF_N + 2];
2583+
2584+typedef struct {
2585+ BF_word S[4][0x100];
2586+ BF_key P;
2587+} BF_ctx;
2588+
2589+/*
2590+ * Magic IV for 64 Blowfish encryptions that we do at the end.
2591+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
2592+ */
2593+static BF_word BF_magic_w[6] = {
2594+ 0x4F727068, 0x65616E42, 0x65686F6C,
2595+ 0x64657253, 0x63727944, 0x6F756274
2596+};
2597+
2598+/*
2599+ * P-box and S-box tables initialized with digits of Pi.
2600+ */
2601+static BF_ctx BF_init_state = {
2602+ {
2603+ {
2604+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
2605+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
2606+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
2607+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
2608+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
2609+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
2610+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
2611+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
2612+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
2613+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
2614+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
2615+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
2616+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
2617+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
2618+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
2619+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
2620+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
2621+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
2622+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
2623+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
2624+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
2625+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
2626+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
2627+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
2628+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
2629+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
2630+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
2631+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
2632+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
2633+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
2634+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
2635+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
2636+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
2637+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
2638+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
2639+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
2640+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
2641+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
2642+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
2643+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
2644+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
2645+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
2646+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
2647+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
2648+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
2649+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
2650+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
2651+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
2652+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
2653+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
2654+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
2655+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
2656+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
2657+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
2658+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
2659+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
2660+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
2661+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
2662+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
2663+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
2664+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
2665+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
2666+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
2667+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
2668+ }, {
2669+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
2670+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
2671+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
2672+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
2673+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
2674+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
2675+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
2676+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
2677+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
2678+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
2679+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
2680+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
2681+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
2682+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
2683+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
2684+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
2685+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
2686+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
2687+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
2688+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
2689+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
2690+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
2691+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
2692+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
2693+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
2694+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
2695+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
2696+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
2697+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
2698+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
2699+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
2700+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
2701+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
2702+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
2703+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
2704+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
2705+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
2706+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
2707+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
2708+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
2709+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
2710+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
2711+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
2712+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
2713+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
2714+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
2715+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
2716+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
2717+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
2718+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
2719+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
2720+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
2721+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
2722+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
2723+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
2724+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
2725+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
2726+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
2727+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
2728+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
2729+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
2730+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
2731+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
2732+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
2733+ }, {
2734+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
2735+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
2736+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
2737+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
2738+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
2739+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
2740+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
2741+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
2742+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
2743+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
2744+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
2745+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
2746+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
2747+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
2748+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
2749+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
2750+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
2751+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
2752+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
2753+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
2754+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
2755+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
2756+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
2757+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
2758+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
2759+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
2760+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
2761+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
2762+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
2763+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
2764+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
2765+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
2766+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
2767+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
2768+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
2769+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
2770+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
2771+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
2772+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
2773+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
2774+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
2775+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
2776+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
2777+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
2778+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
2779+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
2780+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
2781+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
2782+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
2783+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
2784+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
2785+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
2786+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
2787+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
2788+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
2789+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
2790+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
2791+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
2792+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
2793+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
2794+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
2795+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
2796+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
2797+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
2798+ }, {
2799+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
2800+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
2801+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
2802+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
2803+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
2804+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
2805+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
2806+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
2807+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
2808+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
2809+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
2810+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
2811+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
2812+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
2813+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
2814+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
2815+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
2816+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
2817+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
2818+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
2819+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
2820+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
2821+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
2822+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
2823+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
2824+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
2825+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
2826+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
2827+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
2828+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
2829+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
2830+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
2831+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
2832+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
2833+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
2834+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
2835+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
2836+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
2837+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
2838+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
2839+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
2840+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
2841+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
2842+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
2843+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
2844+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
2845+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
2846+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
2847+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
2848+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
2849+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
2850+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
2851+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
2852+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
2853+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
2854+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
2855+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
2856+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
2857+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
2858+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
2859+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
2860+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
2861+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
2862+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
2863+ }
2864+ }, {
2865+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
2866+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
2867+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
2868+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
2869+ 0x9216d5d9, 0x8979fb1b
2870+ }
2871+};
2872+
2873+static unsigned char BF_itoa64[64 + 1] =
2874+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
2875+
2876+static unsigned char BF_atoi64[0x60] = {
2877+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
2878+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
2879+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
2880+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
2881+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
2882+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
2883+};
2884+
2885+/*
2886+ * This may be optimized out if built with function inlining and no BF_ASM.
2887+ */
2888+static void clean(void *data, int size)
2889+{
2890+#if BF_ASM
2891+ extern void _BF_clean(void *data);
2892+#endif
2893+ memset(data, 0, size);
2894+#if BF_ASM
2895+ _BF_clean(data);
2896+#endif
2897+}
2898+
2899+#define BF_safe_atoi64(dst, src) \
2900+{ \
2901+ tmp = (unsigned char)(src); \
2902+ if (tmp == '$') break; \
2903+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
2904+ tmp = BF_atoi64[tmp]; \
2905+ if (tmp > 63) return -1; \
2906+ (dst) = tmp; \
2907+}
2908+
2909+static int BF_decode(BF_word *dst, __CONST char *src, int size)
2910+{
2911+ unsigned char *dptr = (unsigned char *)dst;
2912+ unsigned char *end = dptr + size;
2913+ unsigned char *sptr = (unsigned char *)src;
2914+ unsigned int tmp, c1, c2, c3, c4;
2915+
2916+ do {
2917+ BF_safe_atoi64(c1, *sptr++);
2918+ BF_safe_atoi64(c2, *sptr++);
2919+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
2920+ if (dptr >= end) break;
2921+
2922+ BF_safe_atoi64(c3, *sptr++);
2923+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
2924+ if (dptr >= end) break;
2925+
2926+ BF_safe_atoi64(c4, *sptr++);
2927+ *dptr++ = ((c3 & 0x03) << 6) | c4;
2928+ } while (dptr < end);
2929+
2930+ while (dptr < end)
2931+ *dptr++ = 0;
2932+
2933+ return 0;
2934+}
2935+
2936+static void BF_encode(char *dst, __CONST BF_word *src, int size)
2937+{
2938+ unsigned char *sptr = (unsigned char *)src;
2939+ unsigned char *end = sptr + size;
2940+ unsigned char *dptr = (unsigned char *)dst;
2941+ unsigned int c1, c2;
2942+
2943+ do {
2944+ c1 = *sptr++;
2945+ *dptr++ = BF_itoa64[c1 >> 2];
2946+ c1 = (c1 & 0x03) << 4;
2947+ if (sptr >= end) {
2948+ *dptr++ = BF_itoa64[c1];
2949+ break;
2950+ }
2951+
2952+ c2 = *sptr++;
2953+ c1 |= c2 >> 4;
2954+ *dptr++ = BF_itoa64[c1];
2955+ c1 = (c2 & 0x0f) << 2;
2956+ if (sptr >= end) {
2957+ *dptr++ = BF_itoa64[c1];
2958+ break;
2959+ }
2960+
2961+ c2 = *sptr++;
2962+ c1 |= c2 >> 6;
2963+ *dptr++ = BF_itoa64[c1];
2964+ *dptr++ = BF_itoa64[c2 & 0x3f];
2965+ } while (sptr < end);
2966+}
2967+
2968+static void BF_swap(BF_word *x, int count)
2969+{
2970+ static int endianness_check = 1;
2971+ char *is_little_endian = (char *)&endianness_check;
2972+ BF_word tmp;
2973+
2974+ if (*is_little_endian)
2975+ do {
2976+ tmp = *x;
2977+ tmp = (tmp << 16) | (tmp >> 16);
2978+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
2979+ } while (--count);
2980+}
2981+
2982+#if BF_SCALE
2983+/* Architectures which can shift addresses left by 2 bits with no extra cost */
2984+#define BF_ROUND(L, R, N) \
2985+ tmp1 = L & 0xFF; \
2986+ tmp2 = L >> 8; \
2987+ tmp2 &= 0xFF; \
2988+ tmp3 = L >> 16; \
2989+ tmp3 &= 0xFF; \
2990+ tmp4 = L >> 24; \
2991+ tmp1 = data.ctx.S[3][tmp1]; \
2992+ tmp2 = data.ctx.S[2][tmp2]; \
2993+ tmp3 = data.ctx.S[1][tmp3]; \
2994+ tmp3 += data.ctx.S[0][tmp4]; \
2995+ tmp3 ^= tmp2; \
2996+ R ^= data.ctx.P[N + 1]; \
2997+ tmp3 += tmp1; \
2998+ R ^= tmp3;
2999+#else
3000+/* Architectures with no complicated addressing modes supported */
3001+#define BF_INDEX(S, i) \
3002+ (*((BF_word *)(((unsigned char *)S) + (i))))
3003+#define BF_ROUND(L, R, N) \
3004+ tmp1 = L & 0xFF; \
3005+ tmp1 <<= 2; \
3006+ tmp2 = L >> 6; \
3007+ tmp2 &= 0x3FC; \
3008+ tmp3 = L >> 14; \
3009+ tmp3 &= 0x3FC; \
3010+ tmp4 = L >> 22; \
3011+ tmp4 &= 0x3FC; \
3012+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
3013+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
3014+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
3015+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
3016+ tmp3 ^= tmp2; \
3017+ R ^= data.ctx.P[N + 1]; \
3018+ tmp3 += tmp1; \
3019+ R ^= tmp3;
3020+#endif
3021+
3022+/*
3023+ * Encrypt one block, BF_N is hardcoded here.
3024+ */
3025+#define BF_ENCRYPT \
3026+ L ^= data.ctx.P[0]; \
3027+ BF_ROUND(L, R, 0); \
3028+ BF_ROUND(R, L, 1); \
3029+ BF_ROUND(L, R, 2); \
3030+ BF_ROUND(R, L, 3); \
3031+ BF_ROUND(L, R, 4); \
3032+ BF_ROUND(R, L, 5); \
3033+ BF_ROUND(L, R, 6); \
3034+ BF_ROUND(R, L, 7); \
3035+ BF_ROUND(L, R, 8); \
3036+ BF_ROUND(R, L, 9); \
3037+ BF_ROUND(L, R, 10); \
3038+ BF_ROUND(R, L, 11); \
3039+ BF_ROUND(L, R, 12); \
3040+ BF_ROUND(R, L, 13); \
3041+ BF_ROUND(L, R, 14); \
3042+ BF_ROUND(R, L, 15); \
3043+ tmp4 = R; \
3044+ R = L; \
3045+ L = tmp4 ^ data.ctx.P[BF_N + 1];
3046+
3047+#if BF_ASM
3048+#define BF_body() \
3049+ _BF_body_r(&data.ctx);
3050+#else
3051+#define BF_body() \
3052+ L = R = 0; \
3053+ ptr = data.ctx.P; \
3054+ do { \
3055+ ptr += 2; \
3056+ BF_ENCRYPT; \
3057+ *(ptr - 2) = L; \
3058+ *(ptr - 1) = R; \
3059+ } while (ptr < &data.ctx.P[BF_N + 2]); \
3060+\
3061+ ptr = data.ctx.S[0]; \
3062+ do { \
3063+ ptr += 2; \
3064+ BF_ENCRYPT; \
3065+ *(ptr - 2) = L; \
3066+ *(ptr - 1) = R; \
3067+ } while (ptr < &data.ctx.S[3][0xFF]);
3068+#endif
3069+
3070+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
3071+{
3072+ __CONST char *ptr = key;
3073+ int i, j;
3074+ BF_word tmp;
3075+
3076+ for (i = 0; i < BF_N + 2; i++) {
3077+ tmp = 0;
3078+ for (j = 0; j < 4; j++) {
3079+ tmp <<= 8;
3080+ tmp |= *ptr;
3081+
3082+ if (!*ptr) ptr = key; else ptr++;
3083+ }
3084+
3085+ expanded[i] = tmp;
3086+ initial[i] = BF_init_state.P[i] ^ tmp;
3087+ }
3088+}
3089+
3090+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
3091+ char *output, int size)
3092+{
3093+#if BF_ASM
3094+ extern void _BF_body_r(BF_ctx *ctx);
3095+#endif
3096+ struct {
3097+ BF_ctx ctx;
3098+ BF_key expanded_key;
3099+ union {
3100+ BF_word salt[4];
3101+ BF_word output[6];
3102+ } binary;
3103+ } data;
3104+ BF_word L, R;
3105+ BF_word tmp1, tmp2, tmp3, tmp4;
3106+ BF_word *ptr;
3107+ BF_word count;
3108+ int i;
3109+
3110+ if (size < 7 + 22 + 31 + 1) {
3111+ __set_errno(ERANGE);
3112+ return NULL;
3113+ }
3114+
3115+ if (setting[0] != '$' ||
3116+ setting[1] != '2' ||
3117+ setting[2] != 'a' ||
3118+ setting[3] != '$' ||
3119+ setting[4] < '0' || setting[4] > '3' ||
3120+ setting[5] < '0' || setting[5] > '9' ||
3121+ setting[6] != '$') {
3122+ __set_errno(EINVAL);
3123+ return NULL;
3124+ }
3125+
3126+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
3127+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
3128+ clean(data.binary.salt, sizeof(data.binary.salt));
3129+ __set_errno(EINVAL);
3130+ return NULL;
3131+ }
3132+
3133+ BF_swap(data.binary.salt, 4);
3134+
3135+ BF_set_key(key, data.expanded_key, data.ctx.P);
3136+
3137+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
3138+
3139+ L = R = 0;
3140+ for (i = 0; i < BF_N + 2; i += 2) {
3141+ L ^= data.binary.salt[i & 2];
3142+ R ^= data.binary.salt[(i & 2) + 1];
3143+ BF_ENCRYPT;
3144+ data.ctx.P[i] = L;
3145+ data.ctx.P[i + 1] = R;
3146+ }
3147+
3148+ ptr = data.ctx.S[0];
3149+ do {
3150+ ptr += 4;
3151+ L ^= data.binary.salt[(BF_N + 2) & 3];
3152+ R ^= data.binary.salt[(BF_N + 3) & 3];
3153+ BF_ENCRYPT;
3154+ *(ptr - 4) = L;
3155+ *(ptr - 3) = R;
3156+
3157+ L ^= data.binary.salt[(BF_N + 4) & 3];
3158+ R ^= data.binary.salt[(BF_N + 5) & 3];
3159+ BF_ENCRYPT;
3160+ *(ptr - 2) = L;
3161+ *(ptr - 1) = R;
3162+ } while (ptr < &data.ctx.S[3][0xFF]);
3163+
3164+ do {
3165+ data.ctx.P[0] ^= data.expanded_key[0];
3166+ data.ctx.P[1] ^= data.expanded_key[1];
3167+ data.ctx.P[2] ^= data.expanded_key[2];
3168+ data.ctx.P[3] ^= data.expanded_key[3];
3169+ data.ctx.P[4] ^= data.expanded_key[4];
3170+ data.ctx.P[5] ^= data.expanded_key[5];
3171+ data.ctx.P[6] ^= data.expanded_key[6];
3172+ data.ctx.P[7] ^= data.expanded_key[7];
3173+ data.ctx.P[8] ^= data.expanded_key[8];
3174+ data.ctx.P[9] ^= data.expanded_key[9];
3175+ data.ctx.P[10] ^= data.expanded_key[10];
3176+ data.ctx.P[11] ^= data.expanded_key[11];
3177+ data.ctx.P[12] ^= data.expanded_key[12];
3178+ data.ctx.P[13] ^= data.expanded_key[13];
3179+ data.ctx.P[14] ^= data.expanded_key[14];
3180+ data.ctx.P[15] ^= data.expanded_key[15];
3181+ data.ctx.P[16] ^= data.expanded_key[16];
3182+ data.ctx.P[17] ^= data.expanded_key[17];
3183+
3184+ BF_body();
3185+
3186+ tmp1 = data.binary.salt[0];
3187+ tmp2 = data.binary.salt[1];
3188+ tmp3 = data.binary.salt[2];
3189+ tmp4 = data.binary.salt[3];
3190+ data.ctx.P[0] ^= tmp1;
3191+ data.ctx.P[1] ^= tmp2;
3192+ data.ctx.P[2] ^= tmp3;
3193+ data.ctx.P[3] ^= tmp4;
3194+ data.ctx.P[4] ^= tmp1;
3195+ data.ctx.P[5] ^= tmp2;
3196+ data.ctx.P[6] ^= tmp3;
3197+ data.ctx.P[7] ^= tmp4;
3198+ data.ctx.P[8] ^= tmp1;
3199+ data.ctx.P[9] ^= tmp2;
3200+ data.ctx.P[10] ^= tmp3;
3201+ data.ctx.P[11] ^= tmp4;
3202+ data.ctx.P[12] ^= tmp1;
3203+ data.ctx.P[13] ^= tmp2;
3204+ data.ctx.P[14] ^= tmp3;
3205+ data.ctx.P[15] ^= tmp4;
3206+ data.ctx.P[16] ^= tmp1;
3207+ data.ctx.P[17] ^= tmp2;
3208+
3209+ BF_body();
3210+ } while (--count);
3211+
3212+ for (i = 0; i < 6; i += 2) {
3213+ L = BF_magic_w[i];
3214+ R = BF_magic_w[i + 1];
3215+
3216+ count = 64;
3217+ do {
3218+ BF_ENCRYPT;
3219+ } while (--count);
3220+
3221+ data.binary.output[i] = L;
3222+ data.binary.output[i + 1] = R;
3223+ }
3224+
3225+ memcpy(output, setting, 7 + 22 - 1);
3226+ output[7 + 22 - 1] = BF_itoa64[(int)
3227+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
3228+
3229+/* This has to be bug-compatible with the original implementation, so
3230+ * only encode 23 of the 24 bytes. :-) */
3231+ BF_swap(data.binary.output, 6);
3232+ BF_encode(&output[7 + 22], data.binary.output, 23);
3233+ output[7 + 22 + 31] = '\0';
3234+
3235+/* Overwrite the most obvious sensitive data we have on the stack. Note
3236+ * that this does not guarantee there's no sensitive data left on the
3237+ * stack and/or in registers; I'm not aware of portable code that does. */
3238+ clean(&data, sizeof(data));
3239+
3240+ return output;
3241+}
3242+
3243+char *_crypt_gensalt_blowfish_rn(unsigned long count,
3244+ __CONST char *input, int size, char *output, int output_size)
3245+{
3246+ if (size < 16 || output_size < 7 + 22 + 1 ||
3247+ (count && (count < 4 || count > 31))) {
3248+ if (output_size > 0) output[0] = '\0';
3249+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
3250+ return NULL;
3251+ }
3252+
3253+ if (!count) count = 5;
3254+
3255+ output[0] = '$';
3256+ output[1] = '2';
3257+ output[2] = 'a';
3258+ output[3] = '$';
3259+ output[4] = '0' + count / 10;
3260+ output[5] = '0' + count % 10;
3261+ output[6] = '$';
3262+
3263+ BF_encode(&output[7], (BF_word *)input, 16);
3264+ output[7 + 22] = '\0';
3265+
3266+ return output;
3267+}
3268diff -Nura php-5.1.4/ext/standard/crypt.c hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c
3269--- php-5.1.4/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100
3270+++ hardening-patch-5.1.4-0.4.15/ext/standard/crypt.c 2006-09-05 20:31:04.000000000 +0200
3271@@ -100,6 +100,8 @@
3272 return SUCCESS;
3273 }
3274
3275+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
3276+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
3277
3278 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
3279
3280@@ -135,7 +137,14 @@
3281
3282 /* The automatic salt generation only covers standard DES and md5-crypt */
3283 if(!*salt) {
3284-#if PHP_MD5_CRYPT
3285+#if PHP_BLOWFISH_CRYPT
3286+ char randat[16];
3287+ int i;
3288+
3289+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
3290+
3291+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
3292+#elif PHP_MD5_CRYPT
3293 strcpy(salt, "$1$");
3294 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
3295 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
3296@@ -145,8 +154,24 @@
3297 salt[2] = '\0';
3298 #endif
3299 }
3300-
3301- RETVAL_STRING(crypt(str, salt), 1);
3302+
3303+ if (salt[0] == '$' &&
3304+ salt[1] == '2' &&
3305+ salt[2] == 'a' &&
3306+ salt[3] == '$' &&
3307+ salt[4] >= '0' && salt[4] <= '3' &&
3308+ salt[5] >= '0' && salt[5] <= '9' &&
3309+ salt[6] == '$') {
3310+
3311+ char output[PHP_MAX_SALT_LEN+1];
3312+
3313+ output[0] = 0;
3314+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
3315+ RETVAL_STRING(output, 1);
3316+
3317+ } else {
3318+ RETVAL_STRING(crypt(str, salt), 1);
3319+ }
3320 }
3321 /* }}} */
3322 #endif
3323diff -Nura php-5.1.4/ext/standard/dl.c hardening-patch-5.1.4-0.4.15/ext/standard/dl.c
3324--- php-5.1.4/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100
3325+++ hardening-patch-5.1.4-0.4.15/ext/standard/dl.c 2006-09-05 20:31:04.000000000 +0200
3326@@ -164,8 +164,35 @@
3327 RETURN_FALSE;
3328 }
3329 module_entry = get_module();
3330+
3331+ /* check if Hardening-Patch is installed */
3332+ if (module_entry->zend_api < 1000000000) {
3333+ php_error_docref(NULL TSRMLS_CC, error_type,
3334+ "%s: Unable to initialize module\n"
3335+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
3336+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
3337+ "These options need to match\n",
3338+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
3339+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
3340+ DL_UNLOAD(handle);
3341+ RETURN_FALSE;
3342+ }
3343+
3344+ /* check if correct Hardening-Patch is installed */
3345+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
3346+ php_error_docref(NULL TSRMLS_CC, error_type,
3347+ "%s: Unable to initialize module\n"
3348+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
3349+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
3350+ "These options need to match\n",
3351+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
3352+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
3353+ DL_UNLOAD(handle);
3354+ RETURN_FALSE;
3355+ }
3356+
3357 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
3358- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
3359+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
3360 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
3361 struct pre_4_1_0_module_entry {
3362 char *name;
3363@@ -199,7 +226,7 @@
3364 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
3365 } else {
3366 name = module_entry->name;
3367- zend_api = module_entry->zend_api;
3368+ zend_api = module_entry->real_zend_api;
3369 zend_debug = module_entry->zend_debug;
3370 zts = module_entry->zts;
3371 }
3372diff -Nura php-5.1.4/ext/standard/file.c hardening-patch-5.1.4-0.4.15/ext/standard/file.c
3373--- php-5.1.4/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200
3374+++ hardening-patch-5.1.4-0.4.15/ext/standard/file.c 2006-09-05 20:31:04.000000000 +0200
3375@@ -2302,7 +2302,7 @@
3376 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
3377 /* {{{ proto string realpath(string path)
3378 Return the resolved path */
3379-PHP_FUNCTION(realpath)
3380+PHP_FUNCTION(real_path)
3381 {
3382 zval **path;
3383 char resolved_path_buff[MAXPATHLEN];
3384diff -Nura php-5.1.4/ext/standard/file.h hardening-patch-5.1.4-0.4.15/ext/standard/file.h
3385--- php-5.1.4/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100
3386+++ hardening-patch-5.1.4-0.4.15/ext/standard/file.h 2006-09-05 20:31:04.000000000 +0200
3387@@ -61,7 +61,7 @@
3388 PHP_FUNCTION(fd_set);
3389 PHP_FUNCTION(fd_isset);
3390 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
3391-PHP_FUNCTION(realpath);
3392+PHP_FUNCTION(real_path);
3393 PHP_FUNCTION(fnmatch);
3394 #endif
3395 PHP_NAMED_FUNCTION(php_if_ftruncate);
3396diff -Nura php-5.1.4/ext/standard/filestat.c hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c
3397--- php-5.1.4/ext/standard/filestat.c 2006-04-25 10:41:02.000000000 +0200
3398+++ hardening-patch-5.1.4-0.4.15/ext/standard/filestat.c 2006-09-05 20:31:04.000000000 +0200
3399@@ -16,7 +16,7 @@
3400 +----------------------------------------------------------------------+
3401 */
3402
3403-/* $Id: filestat.c,v 1.136.2.8 2006/04/25 08:41:02 tony2001 Exp $ */
3404+/* $Id: filestat.c,v 1.136.2.9 2006/08/10 21:30:23 iliaa Exp $ */
3405
3406 #include "php.h"
3407 #include "safe_mode.h"
3408@@ -634,7 +634,7 @@
3409 }
3410
3411 if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) {
3412- if (php_check_open_basedir(local TSRMLS_CC)) {
3413+ if (php_check_open_basedir(local TSRMLS_CC) || (PG(safe_mode) && !php_checkuid_ex(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS))) {
3414 RETURN_FALSE;
3415 }
3416 }
3417diff -Nura php-5.1.4/ext/standard/head.c hardening-patch-5.1.4-0.4.15/ext/standard/head.c
3418--- php-5.1.4/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100
3419+++ hardening-patch-5.1.4-0.4.15/ext/standard/head.c 2006-09-05 20:31:04.000000000 +0200
3420@@ -45,7 +45,7 @@
3421 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
3422 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
3423 return;
3424-
3425+
3426 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
3427 }
3428 /* }}} */
3429diff -Nura php-5.1.4/ext/standard/info.c hardening-patch-5.1.4-0.4.15/ext/standard/info.c
3430--- php-5.1.4/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200
3431+++ hardening-patch-5.1.4-0.4.15/ext/standard/info.c 2006-09-05 20:31:04.000000000 +0200
3432@@ -154,7 +154,7 @@
3433 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
3434 if (!sapi_module.phpinfo_as_text) {
3435 PUTS("<pre>");
3436- zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
3437+ zend_print_zval_r_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0 TSRMLS_CC);
3438 PUTS("</pre>");
3439 } else {
3440 zend_print_zval_r(*tmp, 0 TSRMLS_CC);
3441@@ -411,7 +411,7 @@
3442
3443 if (flag & PHP_INFO_GENERAL) {
3444 char *zend_version = get_zend_version();
3445- char temp_api[10];
3446+ char temp_api[11];
3447 char *logo_guid;
3448
3449 php_uname = php_get_uname('a');
3450@@ -434,11 +434,22 @@
3451 PUTS("\" alt=\"PHP Logo\" /></a>");
3452 }
3453
3454+#if HARDENING_PATCH
3455+ if (!sapi_module.phpinfo_as_text) {
3456+ 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);
3457+ } else {
3458+ char temp_ver[40];
3459+
3460+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
3461+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
3462+ }
3463+#else
3464 if (!sapi_module.phpinfo_as_text) {
3465 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
3466 } else {
3467 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
3468- }
3469+ }
3470+#endif
3471 php_info_print_box_end();
3472 php_info_print_table_start();
3473 php_info_print_table_row(2, "System", php_uname );
3474diff -Nura php-5.1.4/ext/standard/mail.c hardening-patch-5.1.4-0.4.15/ext/standard/mail.c
3475--- php-5.1.4/ext/standard/mail.c 2006-01-01 13:50:15.000000000 +0100
3476+++ hardening-patch-5.1.4-0.4.15/ext/standard/mail.c 2006-09-05 20:31:04.000000000 +0200
3477@@ -78,6 +78,25 @@
3478 }
3479 /* }}} */
3480
3481+/* {{{ hphp_strcasestr */
3482+char *hphp_strcasestr(char *haystack, char *needle)
3483+{
3484+ unsigned char *t, *h, *n;
3485+
3486+ h = (unsigned char *) haystack;
3487+conts:
3488+ while (*h) {
3489+ n = (unsigned char *) needle;
3490+ for (t=h++; *n && *h; t++, n++) {
3491+ if (toupper(*t) != toupper(*n)) goto conts;
3492+ }
3493+ return ((char*)h-1);
3494+ }
3495+
3496+ return (NULL);
3497+}
3498+/* }}} */
3499+
3500 /* {{{ proto int mail(string to, string subject, string message [, string additional_headers [, string additional_parameters]])
3501 Send an email message */
3502 PHP_FUNCTION(mail)
3503@@ -104,6 +123,44 @@
3504 return;
3505 }
3506
3507+ if (HG(hphp_mailprotect) > 0) {
3508+ if (headers_len > 0 && headers && (strstr(headers,"\n\n") || strstr(headers,"\r\n\r\n")) ) {
3509+ php_security_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped");
3510+ RETURN_FALSE;
3511+ }
3512+
3513+ /* check for spam attempts with buggy webforms */
3514+ if (to_len > 0 && to && (strchr(to, '\n') != NULL || strchr(to, '\r') != NULL)) {
3515+ php_security_log(S_MAIL, "mail() - newline in to header, possible injection, mail dropped");
3516+ RETURN_FALSE;
3517+ }
3518+
3519+ if (subject_len > 0 && subject && (strchr(subject, '\n') != NULL || strchr(subject, '\r') != NULL)) {
3520+ php_security_log(S_MAIL, "mail() - newline subject header, possible injection, mail dropped");
3521+ RETURN_FALSE;
3522+ }
3523+
3524+ if (HG(hphp_mailprotect) > 1) {
3525+ /* search for to, cc or bcc headers */
3526+ if (headers_len > 0 && headers != NULL) {
3527+ if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || hphp_strcasestr(headers, "\nto:")) {
3528+ php_security_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter.");
3529+ RETURN_FALSE;
3530+ }
3531+
3532+ if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || hphp_strcasestr(headers, "\ncc:")) {
3533+ php_security_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter.");
3534+ RETURN_FALSE;
3535+ }
3536+
3537+ if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || hphp_strcasestr(headers, "\nbcc:")) {
3538+ php_security_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter.");
3539+ RETURN_FALSE;
3540+ }
3541+ }
3542+ }
3543+ }
3544+
3545 if (to_len > 0) {
3546 to_r = estrndup(to, to_len);
3547 for (; to_len; to_len--) {
3548diff -Nura php-5.1.4/ext/standard/php_array.h hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h
3549--- php-5.1.4/ext/standard/php_array.h 2006-02-07 18:54:24.000000000 +0100
3550+++ hardening-patch-5.1.4-0.4.15/ext/standard/php_array.h 2006-09-05 20:31:04.000000000 +0200
3551@@ -19,7 +19,7 @@
3552 +----------------------------------------------------------------------+
3553 */
3554
3555-/* $Id: php_array.h,v 1.50.2.2 2006/02/07 17:54:24 andrei Exp $ */
3556+/* $Id: php_array.h,v 1.50.2.3 2006/06/03 18:59:55 andrei Exp $ */
3557
3558 #ifndef PHP_ARRAY_H
3559 #define PHP_ARRAY_H
3560@@ -108,8 +108,6 @@
3561 int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
3562 ZEND_END_MODULE_GLOBALS(array)
3563
3564-ZEND_DECLARE_MODULE_GLOBALS(array)
3565-
3566 #ifdef ZTS
3567 #define ARRAYG(v) TSRMG(array_globals_id, zend_array_globals *, v)
3568 #else
3569diff -Nura php-5.1.4/ext/standard/php_standard.h hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h
3570--- php-5.1.4/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100
3571+++ hardening-patch-5.1.4-0.4.15/ext/standard/php_standard.h 2006-09-05 20:31:04.000000000 +0200
3572@@ -28,6 +28,7 @@
3573 #include "php_mail.h"
3574 #include "md5.h"
3575 #include "sha1.h"
3576+#include "sha256.h"
3577 #include "html.h"
3578 #include "exec.h"
3579 #include "file.h"
3580diff -Nura php-5.1.4/ext/standard/scanf.c hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c
3581--- php-5.1.4/ext/standard/scanf.c 2006-01-01 13:50:15.000000000 +0100
3582+++ hardening-patch-5.1.4-0.4.15/ext/standard/scanf.c 2006-09-05 20:31:04.000000000 +0200
3583@@ -16,7 +16,7 @@
3584 +----------------------------------------------------------------------+
3585 */
3586
3587-/* $Id: scanf.c,v 1.31.2.2 2006/01/01 12:50:15 sniper Exp $ */
3588+/* $Id: scanf.c,v 1.31.2.3 2006/08/04 20:34:31 tony2001 Exp $ */
3589
3590 /*
3591 scanf.c --
3592@@ -732,7 +732,7 @@
3593 if (*end == '$') {
3594 format = end+1;
3595 ch = format++;
3596- objIndex = varStart + value;
3597+ objIndex = varStart + value - 1;
3598 }
3599 }
3600
3601@@ -762,7 +762,9 @@
3602 switch (*ch) {
3603 case 'n':
3604 if (!(flags & SCAN_SUPPRESS)) {
3605- if (numVars) {
3606+ if (numVars && objIndex >= argCount) {
3607+ break;
3608+ } else if (numVars) {
3609 zend_uint refcount;
3610
3611 current = args[objIndex++];
3612@@ -888,7 +890,9 @@
3613 }
3614 }
3615 if (!(flags & SCAN_SUPPRESS)) {
3616- if (numVars) {
3617+ if (numVars && objIndex >= argCount) {
3618+ break;
3619+ } else if (numVars) {
3620 zend_uint refcount;
3621
3622 current = args[objIndex++];
3623@@ -932,7 +936,9 @@
3624 goto done;
3625 }
3626 if (!(flags & SCAN_SUPPRESS)) {
3627- if (numVars) {
3628+ if (numVars && objIndex >= argCount) {
3629+ break;
3630+ } else if (numVars) {
3631 current = args[objIndex++];
3632 zval_dtor( *current );
3633 ZVAL_STRINGL( *current, string, end-string, 1);
3634@@ -1089,7 +1095,9 @@
3635 value = (int) (*fn)(buf, NULL, base);
3636 if ((flags & SCAN_UNSIGNED) && (value < 0)) {
3637 sprintf(buf, "%u", value); /* INTL: ISO digit */
3638- if (numVars) {
3639+ if (numVars && objIndex >= argCount) {
3640+ break;
3641+ } else if (numVars) {
3642 /* change passed value type to string */
3643 current = args[objIndex++];
3644 convert_to_string( *current );
3645@@ -1098,7 +1106,9 @@
3646 add_index_string(*return_value, objIndex++, buf, 1);
3647 }
3648 } else {
3649- if (numVars) {
3650+ if (numVars && objIndex >= argCount) {
3651+ break;
3652+ } else if (numVars) {
3653 current = args[objIndex++];
3654 convert_to_long( *current );
3655 Z_LVAL(**current) = value;
3656@@ -1206,7 +1216,9 @@
3657 double dvalue;
3658 *end = '\0';
3659 dvalue = zend_strtod(buf, NULL);
3660- if (numVars) {
3661+ if (numVars && objIndex >= argCount) {
3662+ break;
3663+ } else if (numVars) {
3664 current = args[objIndex++];
3665 convert_to_double( *current );
3666 Z_DVAL_PP( current ) = dvalue;
3667diff -Nura php-5.1.4/ext/standard/sha256.c hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c
3668--- php-5.1.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
3669+++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.c 2006-09-05 20:31:04.000000000 +0200
3670@@ -0,0 +1,388 @@
3671+/*
3672+ +----------------------------------------------------------------------+
3673+ | PHP Version 5 |
3674+ +----------------------------------------------------------------------+
3675+ | Copyright (c) 1997-2004 The PHP Group |
3676+ +----------------------------------------------------------------------+
3677+ | This source file is subject to version 3.0 of the PHP license, |
3678+ | that is bundled with this package in the file LICENSE, and is |
3679+ | available through the world-wide-web at the following url: |
3680+ | http://www.php.net/license/3_0.txt. |
3681+ | If you did not receive a copy of the PHP license and are unable to |
3682+ | obtain it through the world-wide-web, please send a note to |
3683+ | license@php.net so we can mail you a copy immediately. |
3684+ +----------------------------------------------------------------------+
3685+ | Author: Stefan Esser <sesser@php.net> |
3686+ +----------------------------------------------------------------------+
3687+*/
3688+
3689+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
3690+
3691+#include "php.h"
3692+
3693+/* This code is heavily based on the PHP md5/sha1 implementations */
3694+
3695+#include "sha256.h"
3696+
3697+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
3698+{
3699+ int i;
3700+
3701+ for (i = 0; i < 32; i++) {
3702+ sprintf(sha256str, "%02x", digest[i]);
3703+ sha256str += 2;
3704+ }
3705+
3706+ *sha256str = '\0';
3707+}
3708+
3709+/* {{{ proto string sha256(string str [, bool raw_output])
3710+ Calculate the sha256 hash of a string */
3711+PHP_FUNCTION(sha256)
3712+{
3713+ char *arg;
3714+ int arg_len;
3715+ zend_bool raw_output = 0;
3716+ char sha256str[65];
3717+ PHP_SHA256_CTX context;
3718+ unsigned char digest[32];
3719+
3720+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
3721+ return;
3722+ }
3723+
3724+ sha256str[0] = '\0';
3725+ PHP_SHA256Init(&context);
3726+ PHP_SHA256Update(&context, arg, arg_len);
3727+ PHP_SHA256Final(digest, &context);
3728+ if (raw_output) {
3729+ RETURN_STRINGL(digest, 32, 1);
3730+ } else {
3731+ make_sha256_digest(sha256str, digest);
3732+ RETVAL_STRING(sha256str, 1);
3733+ }
3734+
3735+}
3736+
3737+/* }}} */
3738+
3739+/* {{{ proto string sha256_file(string filename [, bool raw_output])
3740+ Calculate the sha256 hash of given filename */
3741+PHP_FUNCTION(sha256_file)
3742+{
3743+ char *arg;
3744+ int arg_len;
3745+ zend_bool raw_output = 0;
3746+ char sha256str[65];
3747+ unsigned char buf[1024];
3748+ unsigned char digest[32];
3749+ PHP_SHA256_CTX context;
3750+ int n;
3751+ php_stream *stream;
3752+
3753+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
3754+ return;
3755+ }
3756+
3757+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
3758+ if (!stream) {
3759+ RETURN_FALSE;
3760+ }
3761+
3762+ PHP_SHA256Init(&context);
3763+
3764+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
3765+ PHP_SHA256Update(&context, buf, n);
3766+ }
3767+
3768+ PHP_SHA256Final(digest, &context);
3769+
3770+ php_stream_close(stream);
3771+
3772+ if (n<0) {
3773+ RETURN_FALSE;
3774+ }
3775+
3776+ if (raw_output) {
3777+ RETURN_STRINGL(digest, 32, 1);
3778+ } else {
3779+ make_sha256_digest(sha256str, digest);
3780+ RETVAL_STRING(sha256str, 1);
3781+ }
3782+}
3783+/* }}} */
3784+
3785+
3786+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
3787+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
3788+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
3789+
3790+static unsigned char PADDING[64] =
3791+{
3792+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3793+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
3794+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3795+};
3796+
3797+/* F, G, H and I are basic SHA256 functions.
3798+ */
3799+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
3800+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
3801+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
3802+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
3803+
3804+/* ROTATE_RIGHT rotates x right n bits.
3805+ */
3806+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
3807+
3808+/* W[i]
3809+ */
3810+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
3811+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
3812+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
3813+
3814+/* ROUND function of sha256
3815+ */
3816+
3817+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
3818+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
3819+ (h) = F((a)) + G((a), (b), (c)) + t1; \
3820+ (d) += t1; \
3821+ }
3822+
3823+
3824+/* {{{ PHP_SHA256Init
3825+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
3826+ */
3827+static void PHP_SHA256Init(PHP_SHA256_CTX * context)
3828+{
3829+ context->count[0] = context->count[1] = 0;
3830+ /* Load magic initialization constants.
3831+ */
3832+ context->state[0] = 0x6a09e667;
3833+ context->state[1] = 0xbb67ae85;
3834+ context->state[2] = 0x3c6ef372;
3835+ context->state[3] = 0xa54ff53a;
3836+ context->state[4] = 0x510e527f;
3837+ context->state[5] = 0x9b05688c;
3838+ context->state[6] = 0x1f83d9ab;
3839+ context->state[7] = 0x5be0cd19;
3840+}
3841+/* }}} */
3842+
3843+/* {{{ PHP_SHA256Update
3844+ SHA256 block update operation. Continues an SHA256 message-digest
3845+ operation, processing another message block, and updating the
3846+ context.
3847+ */
3848+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
3849+ unsigned int inputLen)
3850+{
3851+ unsigned int i, index, partLen;
3852+
3853+ /* Compute number of bytes mod 64 */
3854+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
3855+
3856+ /* Update number of bits */
3857+ if ((context->count[0] += ((php_uint32) inputLen << 3))
3858+ < ((php_uint32) inputLen << 3))
3859+ context->count[1]++;
3860+ context->count[1] += ((php_uint32) inputLen >> 29);
3861+
3862+ partLen = 64 - index;
3863+
3864+ /* Transform as many times as possible.
3865+ */
3866+ if (inputLen >= partLen) {
3867+ memcpy
3868+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
3869+ SHA256Transform(context->state, context->buffer);
3870+
3871+ for (i = partLen; i + 63 < inputLen; i += 64)
3872+ SHA256Transform(context->state, &input[i]);
3873+
3874+ index = 0;
3875+ } else
3876+ i = 0;
3877+
3878+ /* Buffer remaining input */
3879+ memcpy
3880+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
3881+ inputLen - i);
3882+}
3883+/* }}} */
3884+
3885+/* {{{ PHP_SHA256Final
3886+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
3887+ the message digest and zeroizing the context.
3888+ */
3889+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
3890+{
3891+ unsigned char bits[8];
3892+ unsigned int index, padLen;
3893+
3894+ /* Save number of bits */
3895+ bits[7] = context->count[0] & 0xFF;
3896+ bits[6] = (context->count[0] >> 8) & 0xFF;
3897+ bits[5] = (context->count[0] >> 16) & 0xFF;
3898+ bits[4] = (context->count[0] >> 24) & 0xFF;
3899+ bits[3] = context->count[1] & 0xFF;
3900+ bits[2] = (context->count[1] >> 8) & 0xFF;
3901+ bits[1] = (context->count[1] >> 16) & 0xFF;
3902+ bits[0] = (context->count[1] >> 24) & 0xFF;
3903+
3904+ /* Pad out to 56 mod 64.
3905+ */
3906+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
3907+ padLen = (index < 56) ? (56 - index) : (120 - index);
3908+ PHP_SHA256Update(context, PADDING, padLen);
3909+
3910+ /* Append length (before padding) */
3911+ PHP_SHA256Update(context, bits, 8);
3912+
3913+ /* Store state in digest */
3914+ SHA256Encode(digest, context->state, 32);
3915+
3916+ /* Zeroize sensitive information.
3917+ */
3918+ memset((unsigned char*) context, 0, sizeof(*context));
3919+}
3920+/* }}} */
3921+
3922+/* {{{ SHA256Transform
3923+ * SHA256 basic transformation. Transforms state based on block.
3924+ */
3925+static void SHA256Transform(state, block)
3926+php_uint32 state[8];
3927+const unsigned char block[64];
3928+{
3929+ php_uint32 a = state[0], b = state[1], c = state[2];
3930+ php_uint32 d = state[3], e = state[4], f = state[5];
3931+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
3932+
3933+ SHA256Decode(x, block, 64);
3934+
3935+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
3936+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
3937+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
3938+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
3939+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
3940+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
3941+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
3942+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
3943+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
3944+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
3945+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
3946+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
3947+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
3948+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
3949+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
3950+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
3951+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
3952+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
3953+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
3954+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
3955+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
3956+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
3957+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
3958+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
3959+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
3960+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
3961+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
3962+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
3963+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
3964+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
3965+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
3966+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
3967+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
3968+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
3969+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
3970+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
3971+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
3972+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
3973+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
3974+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
3975+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
3976+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
3977+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
3978+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
3979+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
3980+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
3981+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
3982+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
3983+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
3984+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
3985+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
3986+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
3987+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
3988+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
3989+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
3990+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
3991+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
3992+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
3993+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
3994+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
3995+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
3996+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
3997+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
3998+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
3999+
4000+ state[0] += a;
4001+ state[1] += b;
4002+ state[2] += c;
4003+ state[3] += d;
4004+ state[4] += e;
4005+ state[5] += f;
4006+ state[6] += g;
4007+ state[7] += h;
4008+
4009+ /* Zeroize sensitive information. */
4010+ memset((unsigned char*) x, 0, sizeof(x));
4011+}
4012+/* }}} */
4013+
4014+/* {{{ SHA256Encode
4015+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
4016+ a multiple of 4.
4017+ */
4018+static void SHA256Encode(output, input, len)
4019+unsigned char *output;
4020+php_uint32 *input;
4021+unsigned int len;
4022+{
4023+ unsigned int i, j;
4024+
4025+ for (i = 0, j = 0; j < len; i++, j += 4) {
4026+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
4027+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
4028+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
4029+ output[j + 3] = (unsigned char) (input[i] & 0xff);
4030+ }
4031+}
4032+/* }}} */
4033+
4034+/* {{{ SHA256Decode
4035+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
4036+ a multiple of 4.
4037+ */
4038+static void SHA256Decode(output, input, len)
4039+php_uint32 *output;
4040+const unsigned char *input;
4041+unsigned int len;
4042+{
4043+ unsigned int i, j;
4044+
4045+ for (i = 0, j = 0; j < len; i++, j += 4)
4046+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
4047+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
4048+}
4049+/* }}} */
4050+
4051+/*
4052+ * Local variables:
4053+ * tab-width: 4
4054+ * c-basic-offset: 4
4055+ * End:
4056+ * vim600: sw=4 ts=4 fdm=marker
4057+ * vim<600: sw=4 ts=4
4058+ */
4059diff -Nura php-5.1.4/ext/standard/sha256.h hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h
4060--- php-5.1.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
4061+++ hardening-patch-5.1.4-0.4.15/ext/standard/sha256.h 2006-09-05 20:31:04.000000000 +0200
4062@@ -0,0 +1,40 @@
4063+/*
4064+ +----------------------------------------------------------------------+
4065+ | PHP Version 5 |
4066+ +----------------------------------------------------------------------+
4067+ | Copyright (c) 1997-2004 The PHP Group |
4068+ +----------------------------------------------------------------------+
4069+ | This source file is subject to version 3.0 of the PHP license, |
4070+ | that is bundled with this package in the file LICENSE, and is |
4071+ | available through the world-wide-web at the following url: |
4072+ | http://www.php.net/license/3_0.txt. |
4073+ | If you did not receive a copy of the PHP license and are unable to |
4074+ | obtain it through the world-wide-web, please send a note to |
4075+ | license@php.net so we can mail you a copy immediately. |
4076+ +----------------------------------------------------------------------+
4077+ | Author: Stefan Esser <sesser@php.net> |
4078+ +----------------------------------------------------------------------+
4079+*/
4080+
4081+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
4082+
4083+#ifndef SHA256_H
4084+#define SHA256_H
4085+
4086+#include "ext/standard/basic_functions.h"
4087+
4088+/* SHA1 context. */
4089+typedef struct {
4090+ php_uint32 state[8]; /* state (ABCD) */
4091+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4092+ unsigned char buffer[64]; /* input buffer */
4093+} PHP_SHA256_CTX;
4094+
4095+static void PHP_SHA256Init(PHP_SHA256_CTX *);
4096+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
4097+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
4098+
4099+PHP_FUNCTION(sha256);
4100+PHP_FUNCTION(sha256_file);
4101+
4102+#endif
4103diff -Nura php-5.1.4/ext/standard/string.c hardening-patch-5.1.4-0.4.15/ext/standard/string.c
4104--- php-5.1.4/ext/standard/string.c 2006-04-25 14:48:41.000000000 +0200
4105+++ hardening-patch-5.1.4-0.4.15/ext/standard/string.c 2006-09-05 20:31:04.000000000 +0200
4106@@ -18,7 +18,7 @@
4107 +----------------------------------------------------------------------+
4108 */
4109
4110-/* $Id: string.c,v 1.445.2.14 2006/04/25 12:48:41 tony2001 Exp $ */
4111+/* $Id: string.c,v 1.445.2.16 2006/08/10 17:46:43 iliaa Exp $ */
4112
4113 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
4114
4115@@ -632,7 +632,8 @@
4116 {
4117 const char *text, *breakchar = "\n";
4118 char *newtext;
4119- int textlen, breakcharlen = 1, newtextlen, alloced, chk;
4120+ int textlen, breakcharlen = 1, newtextlen, chk;
4121+ size_t alloced;
4122 long current = 0, laststart = 0, lastspace = 0;
4123 long linelength = 75;
4124 zend_bool docut = 0;
4125@@ -1612,10 +1613,18 @@
4126 RETURN_FALSE;
4127 }
4128
4129+ if (haystack_len == 0) {
4130+ RETURN_FALSE;
4131+ }
4132+
4133 haystack_dup = estrndup(haystack, haystack_len);
4134 php_strtolower(haystack_dup, haystack_len);
4135
4136 if (Z_TYPE_P(needle) == IS_STRING) {
4137+ if (Z_STRLEN_P(needle) == 0 || Z_STRLEN_P(needle) > haystack_len) {
4138+ efree(haystack_dup);
4139+ RETURN_FALSE;
4140+ }
4141 needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle));
4142 php_strtolower(needle_dup, Z_STRLEN_P(needle));
4143 found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len);
4144@@ -4194,7 +4203,7 @@
4145 zval **input_str; /* Input string */
4146 zval **mult; /* Multiplier */
4147 char *result; /* Resulting string */
4148- int result_len; /* Length of the resulting string */
4149+ size_t result_len; /* Length of the resulting string */
4150
4151 if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &input_str, &mult) == FAILURE) {
4152 WRONG_PARAM_COUNT;
4153@@ -4219,11 +4228,7 @@
4154
4155 /* Initialize the result string */
4156 result_len = Z_STRLEN_PP(input_str) * Z_LVAL_PP(mult);
4157- if (result_len < 1 || result_len > 2147483647) {
4158- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may not create strings longer than 2147483647 bytes");
4159- RETURN_FALSE;
4160- }
4161- result = (char *)emalloc(result_len + 1);
4162+ result = (char *)safe_emalloc(Z_STRLEN_PP(input_str), Z_LVAL_PP(mult), 1);
4163
4164 /* Heavy optimization for situations where input string is 1 byte long */
4165 if (Z_STRLEN_PP(input_str) == 1) {
4166@@ -4894,7 +4899,7 @@
4167 offset = (offset < 0) ? 0 : offset;
4168 }
4169
4170- if ((offset + len) >= s1_len) {
4171+ if ((offset + len) > s1_len) {
4172 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The start position cannot exceed initial string length");
4173 RETURN_FALSE;
4174 }
4175diff -Nura php-5.1.4/ext/standard/syslog.c hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c
4176--- php-5.1.4/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100
4177+++ hardening-patch-5.1.4-0.4.15/ext/standard/syslog.c 2006-09-05 20:31:04.000000000 +0200
4178@@ -42,6 +42,7 @@
4179 */
4180 PHP_MINIT_FUNCTION(syslog)
4181 {
4182+#if !HARDENING_PATCH
4183 /* error levels */
4184 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
4185 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
4186@@ -97,6 +98,7 @@
4187 /* AIX doesn't have LOG_PERROR */
4188 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
4189 #endif
4190+#endif
4191 BG(syslog_device)=NULL;
4192
4193 return SUCCESS;
4194diff -Nura php-5.1.4/ext/varfilter/config.m4 hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4
4195--- php-5.1.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
4196+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/config.m4 2006-09-05 20:31:04.000000000 +0200
4197@@ -0,0 +1,11 @@
4198+dnl
4199+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
4200+dnl
4201+
4202+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
4203+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
4204+
4205+if test "$PHP_VARFILTER" != "no"; then
4206+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
4207+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
4208+fi
4209diff -Nura php-5.1.4/ext/varfilter/CREDITS hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS
4210--- php-5.1.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
4211+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/CREDITS 2006-09-05 20:31:04.000000000 +0200
4212@@ -0,0 +1,2 @@
4213+varfilter
4214+Stefan Esser
4215\ Kein Zeilenumbruch am Dateiende.
4216diff -Nura php-5.1.4/ext/varfilter/php_varfilter.h hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h
4217--- php-5.1.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
4218+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/php_varfilter.h 2006-09-05 20:31:04.000000000 +0200
4219@@ -0,0 +1,144 @@
4220+/*
4221+ +----------------------------------------------------------------------+
4222+ | Hardened-PHP Project's varfilter extension |
4223+ +----------------------------------------------------------------------+
4224+ | Copyright (c) 2004-2005 Stefan Esser |
4225+ +----------------------------------------------------------------------+
4226+ | This source file is subject to version 2.02 of the PHP license, |
4227+ | that is bundled with this package in the file LICENSE, and is |
4228+ | available at through the world-wide-web at |
4229+ | http://www.php.net/license/2_02.txt. |
4230+ | If you did not receive a copy of the PHP license and are unable to |
4231+ | obtain it through the world-wide-web, please send a note to |
4232+ | license@php.net so we can mail you a copy immediately. |
4233+ +----------------------------------------------------------------------+
4234+ | Author: Stefan Esser <sesser@hardened-php.net> |
4235+ +----------------------------------------------------------------------+
4236+
4237+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
4238+*/
4239+
4240+#ifndef PHP_VARFILTER_H
4241+#define PHP_VARFILTER_H
4242+
4243+extern zend_module_entry varfilter_module_entry;
4244+#define phpext_varfilter_ptr &varfilter_module_entry
4245+
4246+#ifdef PHP_WIN32
4247+#define PHP_VARFILTER_API __declspec(dllexport)
4248+#else
4249+#define PHP_VARFILTER_API
4250+#endif
4251+
4252+#ifdef ZTS
4253+#include "TSRM.h"
4254+#endif
4255+
4256+#include "SAPI.h"
4257+
4258+#include "php_variables.h"
4259+
4260+#ifdef ZEND_ENGINE_2
4261+#define HASH_HTTP_GET_VARS 0x2095733f
4262+#define HASH_HTTP_POST_VARS 0xbfee1265
4263+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
4264+#define HASH_HTTP_ENV_VARS 0x1fe186a8
4265+#define HASH_HTTP_SERVER_VARS 0xc987afd6
4266+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
4267+#define HASH_HTTP_POST_FILES 0x98eb1ddc
4268+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
4269+#else
4270+#define HASH_HTTP_GET_VARS 0x8d8645bd
4271+#define HASH_HTTP_POST_VARS 0x7c699bf3
4272+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
4273+#define HASH_HTTP_ENV_VARS 0x84da3016
4274+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
4275+#define HASH_HTTP_SESSION_VARS 0x322906f5
4276+#define HASH_HTTP_POST_FILES 0xe4e4ce70
4277+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
4278+#endif
4279+
4280+PHP_MINIT_FUNCTION(varfilter);
4281+PHP_MSHUTDOWN_FUNCTION(varfilter);
4282+PHP_RINIT_FUNCTION(varfilter);
4283+PHP_RSHUTDOWN_FUNCTION(varfilter);
4284+PHP_MINFO_FUNCTION(varfilter);
4285+
4286+
4287+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
4288+/* request variables */
4289+ long max_request_variables;
4290+ long cur_request_variables;
4291+ long max_varname_length;
4292+ long max_totalname_length;
4293+ long max_value_length;
4294+ long max_array_depth;
4295+ long max_array_index_length;
4296+ zend_bool disallow_nul;
4297+/* cookie variables */
4298+ long max_cookie_vars;
4299+ long cur_cookie_vars;
4300+ long max_cookie_name_length;
4301+ long max_cookie_totalname_length;
4302+ long max_cookie_value_length;
4303+ long max_cookie_array_depth;
4304+ long max_cookie_array_index_length;
4305+ zend_bool disallow_cookie_nul;
4306+/* get variables */
4307+ long max_get_vars;
4308+ long cur_get_vars;
4309+ long max_get_name_length;
4310+ long max_get_totalname_length;
4311+ long max_get_value_length;
4312+ long max_get_array_depth;
4313+ long max_get_array_index_length;
4314+ zend_bool disallow_get_nul;
4315+/* post variables */
4316+ long max_post_vars;
4317+ long cur_post_vars;
4318+ long max_post_name_length;
4319+ long max_post_totalname_length;
4320+ long max_post_value_length;
4321+ long max_post_array_depth;
4322+ long max_post_array_index_length;
4323+ zend_bool disallow_post_nul;
4324+/* fileupload */
4325+ long max_uploads;
4326+ long cur_uploads;
4327+ zend_bool disallow_elf_files;
4328+ char *verification_script;
4329+
4330+ zend_bool no_more_variables;
4331+ zend_bool no_more_get_variables;
4332+ zend_bool no_more_post_variables;
4333+ zend_bool no_more_cookie_variables;
4334+ zend_bool no_more_uploads;
4335+
4336+ZEND_END_MODULE_GLOBALS(varfilter)
4337+
4338+
4339+#ifdef ZTS
4340+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
4341+#else
4342+#define VARFILTER_G(v) (varfilter_globals.v)
4343+#endif
4344+
4345+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
4346+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
4347+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
4348+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
4349+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
4350+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
4351+
4352+
4353+
4354+#endif /* PHP_VARFILTER_H */
4355+
4356+
4357+/*
4358+ * Local variables:
4359+ * tab-width: 4
4360+ * c-basic-offset: 4
4361+ * indent-tabs-mode: t
4362+ * End:
4363+ */
4364diff -Nura php-5.1.4/ext/varfilter/varfilter.c hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c
4365--- php-5.1.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
4366+++ hardening-patch-5.1.4-0.4.15/ext/varfilter/varfilter.c 2006-09-07 18:51:41.000000000 +0200
4367@@ -0,0 +1,915 @@
4368+/*
4369+ +----------------------------------------------------------------------+
4370+ | Hardened-PHP Project's varfilter extension |
4371+ +----------------------------------------------------------------------+
4372+ | Copyright (c) 2004-2005 Stefan Esser |
4373+ +----------------------------------------------------------------------+
4374+ | This source file is subject to version 2.02 of the PHP license, |
4375+ | that is bundled with this package in the file LICENSE, and is |
4376+ | available at through the world-wide-web at |
4377+ | http://www.php.net/license/2_02.txt. |
4378+ | If you did not receive a copy of the PHP license and are unable to |
4379+ | obtain it through the world-wide-web, please send a note to |
4380+ | license@php.net so we can mail you a copy immediately. |
4381+ +----------------------------------------------------------------------+
4382+ | Author: Stefan Esser <sesser@hardened-php.net> |
4383+ +----------------------------------------------------------------------+
4384+
4385+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
4386+*/
4387+
4388+#ifdef HAVE_CONFIG_H
4389+#include "config.h"
4390+#endif
4391+
4392+#include "php.h"
4393+#include "php_ini.h"
4394+#include "ext/standard/info.h"
4395+#include "php_varfilter.h"
4396+#include "hardening_patch.h"
4397+
4398+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
4399+
4400+/* True global resources - no need for thread safety here */
4401+static int le_varfilter;
4402+
4403+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
4404+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
4405+static zend_bool hooked = 0;
4406+
4407+/* {{{ varfilter_module_entry
4408+ */
4409+zend_module_entry varfilter_module_entry = {
4410+#if ZEND_MODULE_API_NO >= 20010901
4411+ STANDARD_MODULE_HEADER,
4412+#endif
4413+ "varfilter",
4414+ NULL,
4415+ PHP_MINIT(varfilter),
4416+ PHP_MSHUTDOWN(varfilter),
4417+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
4418+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
4419+ PHP_MINFO(varfilter),
4420+#if ZEND_MODULE_API_NO >= 20010901
4421+ "0.4.15", /* Replace with version number for your extension */
4422+#endif
4423+ STANDARD_MODULE_PROPERTIES
4424+};
4425+/* }}} */
4426+
4427+#ifdef COMPILE_DL_VARFILTER
4428+ZEND_GET_MODULE(varfilter)
4429+#endif
4430+
4431+/* {{{ PHP_INI
4432+ */
4433+PHP_INI_BEGIN()
4434+ /* for backward compatibility */
4435+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
4436+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
4437+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
4438+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
4439+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
4440+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
4441+
4442+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
4443+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
4444+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
4445+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
4446+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
4447+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
4448+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
4449+
4450+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
4451+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
4452+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
4453+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
4454+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
4455+ 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)
4456+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
4457+
4458+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
4459+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
4460+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
4461+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
4462+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
4463+ 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)
4464+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
4465+
4466+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
4467+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
4468+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
4469+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
4470+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
4471+ 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)
4472+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
4473+
4474+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
4475+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
4476+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
4477+
4478+
4479+PHP_INI_END()
4480+/* }}} */
4481+
4482+/* {{{ php_varfilter_init_globals
4483+ */
4484+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
4485+{
4486+ varfilter_globals->max_request_variables = 200;
4487+ varfilter_globals->max_varname_length = 64;
4488+ varfilter_globals->max_value_length = 10000;
4489+ varfilter_globals->max_array_depth = 100;
4490+ varfilter_globals->max_totalname_length = 256;
4491+ varfilter_globals->max_array_index_length = 64;
4492+ varfilter_globals->disallow_nul = 1;
4493+
4494+ varfilter_globals->max_cookie_vars = 100;
4495+ varfilter_globals->max_cookie_name_length = 64;
4496+ varfilter_globals->max_cookie_totalname_length = 256;
4497+ varfilter_globals->max_cookie_value_length = 10000;
4498+ varfilter_globals->max_cookie_array_depth = 100;
4499+ varfilter_globals->max_cookie_array_index_length = 64;
4500+ varfilter_globals->disallow_cookie_nul = 1;
4501+
4502+ varfilter_globals->max_get_vars = 100;
4503+ varfilter_globals->max_get_name_length = 64;
4504+ varfilter_globals->max_get_totalname_length = 256;
4505+ varfilter_globals->max_get_value_length = 512;
4506+ varfilter_globals->max_get_array_depth = 50;
4507+ varfilter_globals->max_get_array_index_length = 64;
4508+ varfilter_globals->disallow_get_nul = 1;
4509+
4510+ varfilter_globals->max_post_vars = 200;
4511+ varfilter_globals->max_post_name_length = 64;
4512+ varfilter_globals->max_post_totalname_length = 256;
4513+ varfilter_globals->max_post_value_length = 65000;
4514+ varfilter_globals->max_post_array_depth = 100;
4515+ varfilter_globals->max_post_array_index_length = 64;
4516+ varfilter_globals->disallow_post_nul = 1;
4517+
4518+ varfilter_globals->max_uploads = 25;
4519+ varfilter_globals->disallow_elf_files = 1;
4520+ varfilter_globals->verification_script = NULL;
4521+
4522+ varfilter_globals->no_more_variables = 0;
4523+ varfilter_globals->no_more_get_variables = 0;
4524+ varfilter_globals->no_more_post_variables = 0;
4525+ varfilter_globals->no_more_cookie_variables = 0;
4526+ varfilter_globals->no_more_uploads = 0;
4527+
4528+ varfilter_globals->cur_request_variables = 0;
4529+ varfilter_globals->cur_get_vars = 0;
4530+ varfilter_globals->cur_post_vars = 0;
4531+ varfilter_globals->cur_cookie_vars = 0;
4532+
4533+ varfilter_globals->cur_uploads = 0;
4534+
4535+}
4536+/* }}} */
4537+
4538+
4539+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
4540+{
4541+ HashTable *svars;
4542+ int retval, failure=0;
4543+
4544+ orig_register_server_variables(track_vars_array TSRMLS_CC);
4545+
4546+ svars = Z_ARRVAL_P(track_vars_array);
4547+
4548+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
4549+ if (retval == SUCCESS) failure = 1;
4550+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
4551+ if (retval == SUCCESS) failure = 1;
4552+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
4553+ if (retval == SUCCESS) failure = 1;
4554+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
4555+ if (retval == SUCCESS) failure = 1;
4556+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
4557+ if (retval == SUCCESS) failure = 1;
4558+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
4559+ if (retval == SUCCESS) failure = 1;
4560+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
4561+ if (retval == SUCCESS) failure = 1;
4562+ 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);
4563+ if (retval == SUCCESS) failure = 1;
4564+
4565+ if (failure) {
4566+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
4567+ }
4568+}
4569+
4570+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
4571+{
4572+ int retval = SAPI_HEADER_ADD, i;
4573+ char *tmp;
4574+
4575+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
4576+
4577+ tmp = sapi_header->header;
4578+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
4579+ if (tmp[0] == 0) {
4580+ char *fname = get_active_function_name(TSRMLS_C);
4581+
4582+ if (!fname) {
4583+ fname = "unknown";
4584+ }
4585+
4586+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
4587+ sapi_header->header_len = i;
4588+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
4589+ char *fname = get_active_function_name(TSRMLS_C);
4590+
4591+ if (!fname) {
4592+ fname = "unknown";
4593+ }
4594+
4595+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
4596+ sapi_header->header_len = i;
4597+ tmp[0] = 0;
4598+ }
4599+ }
4600+ }
4601+
4602+ if (orig_header_handler) {
4603+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
4604+ }
4605+
4606+ return retval;
4607+}
4608+
4609+/* {{{ PHP_MINIT_FUNCTION
4610+ */
4611+PHP_MINIT_FUNCTION(varfilter)
4612+{
4613+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
4614+ REGISTER_INI_ENTRIES();
4615+
4616+ if (!hooked) {
4617+ void *temp;
4618+ hooked = 1;
4619+
4620+ temp = (void *)sapi_module.register_server_variables;
4621+ if (temp != varfilter_register_server_variables) {
4622+ orig_register_server_variables = temp;
4623+ }
4624+ temp = (void *)sapi_module.header_handler;
4625+ if (temp != varfilter_header_handler) {
4626+ orig_header_handler = temp;
4627+ }
4628+ }
4629+
4630+ sapi_register_input_filter(varfilter_input_filter);
4631+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
4632+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
4633+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
4634+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
4635+
4636+ sapi_module.header_handler = varfilter_header_handler;
4637+ sapi_module.register_server_variables = varfilter_register_server_variables;
4638+
4639+
4640+ return SUCCESS;
4641+}
4642+/* }}} */
4643+
4644+/* {{{ PHP_MSHUTDOWN_FUNCTION
4645+ */
4646+PHP_MSHUTDOWN_FUNCTION(varfilter)
4647+{
4648+ UNREGISTER_INI_ENTRIES();
4649+
4650+ return SUCCESS;
4651+}
4652+/* }}} */
4653+
4654+/* Remove if there's nothing to do at request start */
4655+/* {{{ PHP_RINIT_FUNCTION
4656+ */
4657+PHP_RINIT_FUNCTION(varfilter)
4658+{
4659+ VARFILTER_G(cur_request_variables) = 0;
4660+ VARFILTER_G(cur_get_vars) = 0;
4661+ VARFILTER_G(cur_post_vars) = 0;
4662+ VARFILTER_G(cur_cookie_vars) = 0;
4663+
4664+ VARFILTER_G(cur_uploads) = 0;
4665+
4666+ VARFILTER_G(no_more_variables) = 0;
4667+ VARFILTER_G(no_more_get_variables) = 0;
4668+ VARFILTER_G(no_more_post_variables) = 0;
4669+ VARFILTER_G(no_more_cookie_variables) = 0;
4670+ VARFILTER_G(no_more_uploads) = 0;
4671+
4672+ return SUCCESS;
4673+}
4674+/* }}} */
4675+
4676+/* Remove if there's nothing to do at request end */
4677+/* {{{ PHP_RSHUTDOWN_FUNCTION
4678+ */
4679+PHP_RSHUTDOWN_FUNCTION(varfilter)
4680+{
4681+ return SUCCESS;
4682+}
4683+/* }}} */
4684+
4685+/* {{{ PHP_MINFO_FUNCTION
4686+ */
4687+PHP_MINFO_FUNCTION(varfilter)
4688+{
4689+ php_info_print_table_start();
4690+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
4691+ php_info_print_table_end();
4692+
4693+ DISPLAY_INI_ENTRIES();
4694+}
4695+/* }}} */
4696+
4697+/* {{{ normalize_varname
4698+ */
4699+static void normalize_varname(char *varname)
4700+{
4701+ char *s=varname, *index=NULL, *indexend=NULL, *p;
4702+
4703+ /* overjump leading space */
4704+ while (*s == ' ') {
4705+ s++;
4706+ }
4707+
4708+ /* and remove it */
4709+ if (s != varname) {
4710+ memmove(varname, s, strlen(s)+1);
4711+ }
4712+
4713+ for (p=varname; *p && *p != '['; p++) {
4714+ switch(*p) {
4715+ case ' ':
4716+ case '.':
4717+ *p='_';
4718+ break;
4719+ }
4720+ }
4721+
4722+ /* find index */
4723+ index = strchr(varname, '[');
4724+ if (index) {
4725+ index++;
4726+ s=index;
4727+ } else {
4728+ return;
4729+ }
4730+
4731+ /* done? */
4732+ while (index) {
4733+
4734+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
4735+ index++;
4736+ }
4737+ indexend = strchr(index, ']');
4738+ indexend = indexend ? indexend + 1 : index + strlen(index);
4739+
4740+ if (s != index) {
4741+ memmove(s, index, strlen(index)+1);
4742+ s += indexend-index;
4743+ } else {
4744+ s = indexend;
4745+ }
4746+
4747+ if (*s == '[') {
4748+ s++;
4749+ index = s;
4750+ } else {
4751+ index = NULL;
4752+ }
4753+ }
4754+ *s++='\0';
4755+}
4756+/* }}} */
4757+
4758+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
4759+ */
4760+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
4761+{
4762+ char *index, *prev_index = NULL, *var;
4763+ unsigned int var_len, total_len, depth = 0;
4764+
4765+ var = estrdup(varname);
4766+
4767+ /* Normalize the variable name */
4768+ normalize_varname(var);
4769+
4770+ /* Find length of variable name */
4771+ index = strchr(var, '[');
4772+ total_len = strlen(var);
4773+ var_len = index ? index-var : total_len;
4774+
4775+ /* Drop this variable if it exceeds the varname/total length limit */
4776+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
4777+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
4778+ goto return_failure;
4779+ }
4780+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
4781+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
4782+ goto return_failure;
4783+ }
4784+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
4785+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
4786+
4787+ goto return_failure;
4788+ }
4789+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
4790+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
4791+ goto return_failure;
4792+ }
4793+
4794+ /* Find out array depth */
4795+ while (index) {
4796+ unsigned int index_length;
4797+
4798+ depth++;
4799+ index = strchr(index+1, '[');
4800+
4801+ if (prev_index) {
4802+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
4803+
4804+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
4805+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
4806+ goto return_failure;
4807+ }
4808+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
4809+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
4810+ goto return_failure;
4811+ }
4812+ prev_index = index;
4813+ }
4814+
4815+ }
4816+
4817+ /* Drop this variable if it exceeds the array depth limit */
4818+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
4819+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
4820+ goto return_failure;
4821+ }
4822+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
4823+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
4824+ goto return_failure;
4825+ }
4826+
4827+
4828+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
4829+ /* This is to protect several silly scripts that do globalizing themself */
4830+
4831+ switch (var_len) {
4832+ case 18:
4833+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
4834+ break;
4835+ case 17:
4836+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
4837+ break;
4838+ case 16:
4839+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
4840+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
4841+ break;
4842+ case 15:
4843+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
4844+ break;
4845+ case 14:
4846+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
4847+ break;
4848+ case 13:
4849+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
4850+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
4851+ break;
4852+ case 8:
4853+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
4854+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
4855+ break;
4856+ case 7:
4857+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
4858+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
4859+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
4860+ break;
4861+ case 6:
4862+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
4863+ break;
4864+ case 5:
4865+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
4866+ break;
4867+ case 4:
4868+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
4869+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
4870+ break;
4871+ }
4872+
4873+ efree(var);
4874+ return SUCCESS;
4875+protected_varname2:
4876+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
4877+return_failure:
4878+ efree(var);
4879+ return FAILURE;
4880+}
4881+/* }}} */
4882+
4883+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
4884+ */
4885+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
4886+{
4887+ /* Drop if no more variables flag is set */
4888+ if (VARFILTER_G(no_more_uploads)) {
4889+ return FAILURE;
4890+ }
4891+ /* Drop this fileupload if the limit is reached */
4892+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
4893+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
4894+ VARFILTER_G(no_more_uploads) = 1;
4895+ return FAILURE;
4896+ }
4897+
4898+ return SUCCESS;
4899+}
4900+/* }}} */
4901+
4902+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
4903+ */
4904+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
4905+{
4906+
4907+ if (VARFILTER_G(disallow_elf_files)) {
4908+
4909+ if (offset == 0 && buffer_len > 10) {
4910+
4911+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
4912+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
4913+ return FAILURE;
4914+ }
4915+ }
4916+
4917+ }
4918+
4919+ return SUCCESS;
4920+}
4921+/* }}} */
4922+
4923+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
4924+ */
4925+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
4926+{
4927+ int retval = SUCCESS;
4928+
4929+ if (VARFILTER_G(verification_script)) {
4930+ char cmd[8192];
4931+ FILE *in;
4932+ int first=1;
4933+
4934+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
4935+
4936+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4937+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
4938+ return FAILURE;
4939+ }
4940+
4941+ retval = FAILURE;
4942+
4943+ /* read and forget the result */
4944+ while (1) {
4945+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4946+ if (readbytes<=0) {
4947+ break;
4948+ }
4949+ if (first) {
4950+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
4951+ first = 0;
4952+ }
4953+ }
4954+ pclose(in);
4955+ }
4956+
4957+ if (retval != SUCCESS) {
4958+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
4959+ return FAILURE;
4960+ }
4961+
4962+ VARFILTER_G(cur_uploads)++;
4963+ return SUCCESS;
4964+}
4965+/* }}} */
4966+
4967+/* {{{ SAPI_INPUT_FILTER_FUNC
4968+ */
4969+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
4970+{
4971+ char *index, *prev_index = NULL;
4972+ unsigned int var_len, total_len, depth = 0;
4973+
4974+ /* Drop this variable if the limit was reached */
4975+ switch (arg) {
4976+ case PARSE_GET:
4977+ if (VARFILTER_G(no_more_get_variables)) {
4978+ return 0;
4979+ }
4980+ break;
4981+ case PARSE_POST:
4982+ if (VARFILTER_G(no_more_post_variables)) {
4983+ return 0;
4984+ }
4985+ break;
4986+ case PARSE_COOKIE:
4987+ if (VARFILTER_G(no_more_cookie_variables)) {
4988+ return 0;
4989+ }
4990+ break;
4991+ default: /* we do not want to protect parse_str() and friends */
4992+ if (new_val_len) {
4993+ *new_val_len = val_len;
4994+ }
4995+ return 1;
4996+ }
4997+ if (VARFILTER_G(no_more_variables)) {
4998+ return 0;
4999+ }
5000+
5001+ /* Drop this variable if the limit is now reached */
5002+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
5003+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
5004+ VARFILTER_G(no_more_variables) = 1;
5005+ return 0;
5006+ }
5007+ switch (arg) {
5008+ case PARSE_GET:
5009+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
5010+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
5011+ VARFILTER_G(no_more_get_variables) = 1;
5012+ return 0;
5013+ }
5014+ break;
5015+ case PARSE_COOKIE:
5016+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
5017+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
5018+ VARFILTER_G(no_more_cookie_variables) = 1;
5019+ return 0;
5020+ }
5021+ break;
5022+ case PARSE_POST:
5023+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
5024+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
5025+ VARFILTER_G(no_more_post_variables) = 1;
5026+ return 0;
5027+ }
5028+ break;
5029+ }
5030+
5031+
5032+ /* Drop this variable if it exceeds the value length limit */
5033+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
5034+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
5035+ return 0;
5036+ }
5037+ switch (arg) {
5038+ case PARSE_GET:
5039+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
5040+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
5041+ return 0;
5042+ }
5043+ break;
5044+ case PARSE_COOKIE:
5045+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
5046+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
5047+ return 0;
5048+ }
5049+ break;
5050+ case PARSE_POST:
5051+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
5052+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
5053+ return 0;
5054+ }
5055+ break;
5056+ }
5057+
5058+ /* Normalize the variable name */
5059+ normalize_varname(var);
5060+
5061+ /* Find length of variable name */
5062+ index = strchr(var, '[');
5063+ total_len = strlen(var);
5064+ var_len = index ? index-var : total_len;
5065+
5066+ /* Drop this variable if it exceeds the varname/total length limit */
5067+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
5068+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
5069+ return 0;
5070+ }
5071+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
5072+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
5073+ return 0;
5074+ }
5075+ switch (arg) {
5076+ case PARSE_GET:
5077+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
5078+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
5079+ return 0;
5080+ }
5081+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
5082+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
5083+ return 0;
5084+ }
5085+ break;
5086+ case PARSE_COOKIE:
5087+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
5088+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
5089+ return 0;
5090+ }
5091+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
5092+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
5093+ return 0;
5094+ }
5095+ break;
5096+ case PARSE_POST:
5097+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
5098+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
5099+ return 0;
5100+ }
5101+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
5102+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
5103+ return 0;
5104+ }
5105+ break;
5106+ }
5107+
5108+ /* Find out array depth */
5109+ while (index) {
5110+ unsigned int index_length;
5111+
5112+ depth++;
5113+ index = strchr(index+1, '[');
5114+
5115+ if (prev_index) {
5116+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
5117+
5118+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
5119+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
5120+ return 0;
5121+ }
5122+ switch (arg) {
5123+ case PARSE_GET:
5124+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
5125+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
5126+ return 0;
5127+ }
5128+ break;
5129+ case PARSE_COOKIE:
5130+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
5131+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
5132+ return 0;
5133+ }
5134+ break;
5135+ case PARSE_POST:
5136+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
5137+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
5138+ return 0;
5139+ }
5140+ break;
5141+ }
5142+ prev_index = index;
5143+ }
5144+
5145+ }
5146+
5147+ /* Drop this variable if it exceeds the array depth limit */
5148+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
5149+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
5150+ return 0;
5151+ }
5152+ switch (arg) {
5153+ case PARSE_GET:
5154+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
5155+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
5156+ return 0;
5157+ }
5158+ break;
5159+ case PARSE_COOKIE:
5160+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
5161+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
5162+ return 0;
5163+ }
5164+ break;
5165+ case PARSE_POST:
5166+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
5167+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
5168+ return 0;
5169+ }
5170+ break;
5171+ }
5172+
5173+ /* Check if variable value is truncated by a \0 */
5174+
5175+ if (val && *val && val_len != strlen(*val)) {
5176+
5177+ if (VARFILTER_G(disallow_nul)) {
5178+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
5179+ return 0;
5180+ }
5181+ switch (arg) {
5182+ case PARSE_GET:
5183+ if (VARFILTER_G(disallow_get_nul)) {
5184+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
5185+ return 0;
5186+ }
5187+ break;
5188+ case PARSE_COOKIE:
5189+ if (VARFILTER_G(disallow_cookie_nul)) {
5190+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
5191+ return 0;
5192+ }
5193+ break;
5194+ case PARSE_POST:
5195+ if (VARFILTER_G(disallow_post_nul)) {
5196+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
5197+ return 0;
5198+ }
5199+ break;
5200+ }
5201+ }
5202+
5203+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
5204+ /* This is to protect several silly scripts that do globalizing themself */
5205+
5206+ switch (var_len) {
5207+ case 18:
5208+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
5209+ break;
5210+ case 17:
5211+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
5212+ break;
5213+ case 16:
5214+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
5215+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
5216+ break;
5217+ case 15:
5218+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
5219+ break;
5220+ case 14:
5221+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
5222+ break;
5223+ case 13:
5224+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
5225+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
5226+ break;
5227+ case 8:
5228+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
5229+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
5230+ break;
5231+ case 7:
5232+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
5233+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
5234+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
5235+ break;
5236+ case 6:
5237+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
5238+ break;
5239+ case 5:
5240+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
5241+ break;
5242+ case 4:
5243+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
5244+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
5245+ break;
5246+ }
5247+
5248+ /* Okay let PHP register this variable */
5249+ VARFILTER_G(cur_request_variables)++;
5250+ switch (arg) {
5251+ case PARSE_GET:
5252+ VARFILTER_G(cur_get_vars)++;
5253+ break;
5254+ case PARSE_COOKIE:
5255+ VARFILTER_G(cur_cookie_vars)++;
5256+ break;
5257+ case PARSE_POST:
5258+ VARFILTER_G(cur_post_vars)++;
5259+ break;
5260+ }
5261+
5262+ if (new_val_len) {
5263+ *new_val_len = val_len;
5264+ }
5265+
5266+ return 1;
5267+protected_varname:
5268+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
5269+ return 0;
5270+}
5271+/* }}} */
5272+
5273+/*
5274+ * Local variables:
5275+ * tab-width: 4
5276+ * c-basic-offset: 4
5277+ * End:
5278+ * vim600: noet sw=4 ts=4 fdm=marker
5279+ * vim<600: noet sw=4 ts=4
5280+ */
5281+
5282+
5283diff -Nura php-5.1.4/ext/wddx/wddx.c hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c
5284--- php-5.1.4/ext/wddx/wddx.c 2006-04-23 18:02:05.000000000 +0200
5285+++ hardening-patch-5.1.4-0.4.15/ext/wddx/wddx.c 2006-09-05 20:31:04.000000000 +0200
5286@@ -399,9 +399,9 @@
5287 break;
5288
5289 default:
5290- if (iscntrl((int)*(unsigned char *)p)) {
5291+ if (iscntrl((int)*(unsigned char *)p)||(int)*(unsigned char *)p >= 127) {
5292 FLUSH_BUF();
5293- sprintf(control_buf, WDDX_CHAR, *p);
5294+ sprintf(control_buf, WDDX_CHAR, (int)*(unsigned char *)p);
5295 php_wddx_add_chunk(packet, control_buf);
5296 } else
5297 buf[l++] = *p;
5298@@ -751,7 +751,7 @@
5299 } else if (!strcmp(name, EL_CHAR)) {
5300 int i;
5301
5302- for (i = 0; atts[i]; i++) {
5303+ if (atts) for (i = 0; atts[i]; i++) {
5304 if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
5305 char tmp_buf[2];
5306
5307@@ -771,7 +771,7 @@
5308 } else if (!strcmp(name, EL_BOOLEAN)) {
5309 int i;
5310
5311- for (i = 0; atts[i]; i++) {
5312+ if (atts) for (i = 0; atts[i]; i++) {
5313 if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
5314 ent.type = ST_BOOLEAN;
5315 SET_STACK_VARNAME;
5316@@ -812,7 +812,7 @@
5317 } else if (!strcmp(name, EL_VAR)) {
5318 int i;
5319
5320- for (i = 0; atts[i]; i++) {
5321+ if (atts) for (i = 0; atts[i]; i++) {
5322 if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
5323 char *decoded;
5324 int decoded_len;
5325@@ -829,7 +829,7 @@
5326 MAKE_STD_ZVAL(ent.data);
5327 array_init(ent.data);
5328
5329- for (i = 0; atts[i]; i++) {
5330+ if (atts) for (i = 0; atts[i]; i++) {
5331 if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
5332 zval *tmp;
5333 char *key;
5334@@ -869,7 +869,7 @@
5335 ent.varname = NULL;
5336 ent.data = NULL;
5337
5338- for (i = 0; atts[i]; i++) {
5339+ if (atts) for (i = 0; atts[i]; i++) {
5340 if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
5341 char *decoded;
5342 int decoded_len;
5343diff -Nura php-5.1.4/main/fopen_wrappers.c hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c
5344--- php-5.1.4/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100
5345+++ hardening-patch-5.1.4-0.4.15/main/fopen_wrappers.c 2006-09-07 18:53:55.000000000 +0200
5346@@ -104,7 +104,10 @@
5347 }
5348
5349 /* Resolve the real path into resolved_name */
5350- if ((expand_filepath(path, resolved_name TSRMLS_CC) != NULL) && (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL)) {
5351+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
5352+ return -2;
5353+ }
5354+ if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) {
5355 /* Handler for basedirs that end with a / */
5356 resolved_basedir_len = strlen(resolved_basedir);
5357 if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
5358@@ -114,14 +117,20 @@
5359 }
5360 }
5361
5362+ resolved_name_len = strlen(resolved_name);
5363 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
5364- resolved_name_len = strlen(resolved_name);
5365 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
5366 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
5367 resolved_name[++resolved_name_len] = '\0';
5368 }
5369 }
5370
5371+ if (resolved_name_len == resolved_basedir_len - 1) {
5372+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
5373+ resolved_basedir_len--;
5374+ }
5375+ }
5376+
5377 /* Check the path */
5378 #if defined(PHP_WIN32) || defined(NETWARE)
5379 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
5380@@ -135,7 +144,7 @@
5381 }
5382 } else {
5383 /* Unable to resolve the real path, return -1 */
5384- return -1;
5385+ return -3;
5386 }
5387 }
5388 /* }}} */
5389@@ -154,22 +163,44 @@
5390 char *pathbuf;
5391 char *ptr;
5392 char *end;
5393+ char path_copy[MAXPATHLEN];
5394+ int path_len;
5395+
5396+ /* Special case path ends with a trailing slash */
5397+ path_len = strlen(path);
5398+ if (path_len >= MAXPATHLEN) {
5399+ errno = EPERM; /* we deny permission to open it */
5400+ return -1;
5401+ }
5402+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
5403+ memcpy(path_copy, path, path_len+1);
5404+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
5405+ path_copy[path_len] = '\0';
5406+ path = (const char *)&path_copy;
5407+ }
5408
5409 pathbuf = estrdup(PG(open_basedir));
5410
5411 ptr = pathbuf;
5412
5413 while (ptr && *ptr) {
5414+ int res;
5415 end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
5416 if (end != NULL) {
5417 *end = '\0';
5418 end++;
5419 }
5420
5421- if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) {
5422+ res = php_check_specific_open_basedir(ptr, path TSRMLS_CC);
5423+ if (res == 0) {
5424 efree(pathbuf);
5425 return 0;
5426 }
5427+ if (res == -2) {
5428+ efree(pathbuf);
5429+ errno = EPERM;
5430+ return -1;
5431+ }
5432
5433 ptr = end;
5434 }
5435diff -Nura php-5.1.4/main/hardened_globals.h hardening-patch-5.1.4-0.4.15/main/hardened_globals.h
5436--- php-5.1.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
5437+++ hardening-patch-5.1.4-0.4.15/main/hardened_globals.h 2006-09-05 20:31:05.000000000 +0200
5438@@ -0,0 +1,64 @@
5439+/*
5440+ +----------------------------------------------------------------------+
5441+ | Hardening-Patch for PHP |
5442+ +----------------------------------------------------------------------+
5443+ | Copyright (c) 2004-2005 Stefan Esser |
5444+ +----------------------------------------------------------------------+
5445+ | This source file is subject to version 2.02 of the PHP license, |
5446+ | that is bundled with this package in the file LICENSE, and is |
5447+ | available at through the world-wide-web at |
5448+ | http://www.php.net/license/2_02.txt. |
5449+ | If you did not receive a copy of the PHP license and are unable to |
5450+ | obtain it through the world-wide-web, please send a note to |
5451+ | license@php.net so we can mail you a copy immediately. |
5452+ +----------------------------------------------------------------------+
5453+ | Author: Stefan Esser <sesser@hardened-php.net> |
5454+ +----------------------------------------------------------------------+
5455+ */
5456+
5457+#ifndef HARDENED_GLOBALS_H
5458+#define HARDENED_GLOBALS_H
5459+
5460+typedef struct _hardened_globals hardened_globals_struct;
5461+
5462+#ifdef ZTS
5463+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
5464+extern int hardened_globals_id;
5465+#else
5466+# define HG(v) (hardened_globals.v)
5467+extern struct _hardened_globals hardened_globals;
5468+#endif
5469+
5470+
5471+struct _hardened_globals {
5472+#if HARDENING_PATCH_MM_PROTECT
5473+ unsigned int canary_1;
5474+ unsigned int canary_2;
5475+#endif
5476+#if HARDENING_PATCH_LL_PROTECT
5477+ unsigned int canary_3;
5478+ unsigned int canary_4;
5479+ unsigned int ll_canary_inited;
5480+#endif
5481+ zend_bool hphp_sql_bailout_on_error;
5482+ zend_bool hphp_multiheader;
5483+ unsigned long hphp_mailprotect;
5484+ long hard_memory_limit;
5485+ HashTable *eval_whitelist;
5486+ HashTable *eval_blacklist;
5487+ HashTable *func_whitelist;
5488+ HashTable *func_blacklist;
5489+ HashTable *include_whitelist;
5490+ HashTable *include_blacklist;
5491+ unsigned int dummy;
5492+};
5493+
5494+
5495+#endif /* HARDENED_GLOBALS_H */
5496+
5497+/*
5498+ * Local variables:
5499+ * tab-width: 4
5500+ * c-basic-offset: 4
5501+ * End:
5502+ */
5503diff -Nura php-5.1.4/main/hardening_patch.c hardening-patch-5.1.4-0.4.15/main/hardening_patch.c
5504--- php-5.1.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
5505+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.c 2006-09-05 20:31:05.000000000 +0200
5506@@ -0,0 +1,430 @@
5507+/*
5508+ +----------------------------------------------------------------------+
5509+ | Hardening Patch for PHP |
5510+ +----------------------------------------------------------------------+
5511+ | Copyright (c) 2004-2005 Stefan Esser |
5512+ +----------------------------------------------------------------------+
5513+ | This source file is subject to version 2.02 of the PHP license, |
5514+ | that is bundled with this package in the file LICENSE, and is |
5515+ | available at through the world-wide-web at |
5516+ | http://www.php.net/license/2_02.txt. |
5517+ | If you did not receive a copy of the PHP license and are unable to |
5518+ | obtain it through the world-wide-web, please send a note to |
5519+ | license@php.net so we can mail you a copy immediately. |
5520+ +----------------------------------------------------------------------+
5521+ | Author: Stefan Esser <sesser@hardened-php.net> |
5522+ +----------------------------------------------------------------------+
5523+ */
5524+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
5525+
5526+#include "php.h"
5527+
5528+#include <stdio.h>
5529+#include <stdlib.h>
5530+
5531+#if HAVE_UNISTD_H
5532+#include <unistd.h>
5533+#endif
5534+#include "SAPI.h"
5535+#include "php_globals.h"
5536+
5537+#if HARDENING_PATCH
5538+
5539+#ifdef HAVE_SYS_SOCKET_H
5540+#include <sys/socket.h>
5541+#endif
5542+
5543+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
5544+#undef AF_UNIX
5545+#endif
5546+
5547+#if defined(AF_UNIX)
5548+#include <sys/un.h>
5549+#endif
5550+
5551+#define SYSLOG_PATH "/dev/log"
5552+
5553+#include "snprintf.h"
5554+
5555+#include "hardening_patch.h"
5556+
5557+#ifdef ZTS
5558+#include "hardened_globals.h"
5559+int hardened_globals_id;
5560+#else
5561+struct _hardened_globals hardened_globals;
5562+#endif
5563+
5564+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
5565+{
5566+ memset(hardened_globals, 0, sizeof(*hardened_globals));
5567+}
5568+
5569+
5570+PHPAPI void hardened_startup()
5571+{
5572+#ifdef ZTS
5573+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
5574+#else
5575+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
5576+#endif
5577+}
5578+
5579+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
5580+{
5581+ HG(canary_1) = php_canary();
5582+ HG(canary_2) = php_canary();
5583+}
5584+
5585+char *loglevel2string(int loglevel)
5586+{
5587+ switch (loglevel) {
5588+ case S_FILES:
5589+ return "FILES";
5590+ case S_INCLUDE:
5591+ return "INCLUDE";
5592+ case S_MEMORY:
5593+ return "MEMORY";
5594+ case S_MISC:
5595+ return "MISC";
5596+ case S_SQL:
5597+ return "SQL";
5598+ case S_EXECUTOR:
5599+ return "EXECUTOR";
5600+ case S_VARS:
5601+ return "VARS";
5602+ default:
5603+ return "UNKNOWN";
5604+ }
5605+}
5606+
5607+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
5608+{
5609+#if defined(AF_UNIX)
5610+ int s, r, i=0;
5611+ struct sockaddr_un saun;
5612+ char buf[4096+64];
5613+ char error[4096+100];
5614+ char *ip_address;
5615+ char *fname;
5616+ int lineno;
5617+ va_list ap;
5618+ TSRMLS_FETCH();
5619+
5620+ if (EG(hphp_log_use_x_forwarded_for)) {
5621+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
5622+ if (ip_address == NULL) {
5623+ ip_address = "X-FORWARDED-FOR not set";
5624+ }
5625+ } else {
5626+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
5627+ if (ip_address == NULL) {
5628+ ip_address = "REMOTE_ADDR not set";
5629+ }
5630+ }
5631+
5632+
5633+ va_start(ap, fmt);
5634+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
5635+ va_end(ap);
5636+ while (error[i]) {
5637+ if (error[i] < 32) error[i] = '.';
5638+ i++;
5639+ }
5640+
5641+ if (zend_is_executing(TSRMLS_C)) {
5642+ lineno = zend_get_executed_lineno(TSRMLS_C);
5643+ fname = zend_get_executed_filename(TSRMLS_C);
5644+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
5645+ } else {
5646+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
5647+ if (fname==NULL) {
5648+ fname = "unknown";
5649+ }
5650+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
5651+ }
5652+
5653+ /* Syslog-Logging disabled? */
5654+ if ((EG(hphp_log_syslog) & loglevel)==0) {
5655+ goto log_sapi;
5656+ }
5657+
5658+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
5659+
5660+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
5661+ if (s == -1) {
5662+ goto log_sapi;
5663+ }
5664+
5665+ memset(&saun, 0, sizeof(saun));
5666+ saun.sun_family = AF_UNIX;
5667+ strcpy(saun.sun_path, SYSLOG_PATH);
5668+ /*saun.sun_len = sizeof(saun);*/
5669+
5670+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5671+ if (r) {
5672+ close(s);
5673+ s = socket(AF_UNIX, SOCK_STREAM, 0);
5674+ if (s == -1) {
5675+ goto log_sapi;
5676+ }
5677+
5678+ memset(&saun, 0, sizeof(saun));
5679+ saun.sun_family = AF_UNIX;
5680+ strcpy(saun.sun_path, SYSLOG_PATH);
5681+ /*saun.sun_len = sizeof(saun);*/
5682+
5683+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
5684+ if (r) {
5685+ close(s);
5686+ goto log_sapi;
5687+ }
5688+ }
5689+ send(s, error, strlen(error), 0);
5690+
5691+ close(s);
5692+
5693+log_sapi:
5694+ /* SAPI Logging activated? */
5695+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
5696+ sapi_module.log_message(buf);
5697+ }
5698+
5699+log_script:
5700+ /* script logging activaed? */
5701+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
5702+ char cmd[8192], *cmdpos, *bufpos;
5703+ FILE *in;
5704+ int space;
5705+
5706+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
5707+ space = sizeof(cmd) - strlen(cmd);
5708+ cmdpos = cmd + strlen(cmd);
5709+ bufpos = buf;
5710+ if (space <= 1) return;
5711+ while (space > 2 && *bufpos) {
5712+ if (*bufpos == '\'') {
5713+ if (space<=5) break;
5714+ *cmdpos++ = '\'';
5715+ *cmdpos++ = '\\';
5716+ *cmdpos++ = '\'';
5717+ *cmdpos++ = '\'';
5718+ bufpos++;
5719+ space-=4;
5720+ } else {
5721+ *cmdpos++ = *bufpos++;
5722+ space--;
5723+ }
5724+ }
5725+ *cmdpos++ = '\'';
5726+ *cmdpos = 0;
5727+
5728+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
5729+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
5730+ return;
5731+ }
5732+ /* read and forget the result */
5733+ while (1) {
5734+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
5735+ if (readbytes<=0) {
5736+ break;
5737+ }
5738+ }
5739+ pclose(in);
5740+ }
5741+
5742+#endif
5743+}
5744+#endif
5745+
5746+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
5747+
5748+/* will be replaced later with more compatible method */
5749+PHPAPI unsigned int php_canary()
5750+{
5751+ time_t t;
5752+ unsigned int canary;
5753+ int fd;
5754+
5755+ fd = open("/dev/urandom", 0);
5756+ if (fd != -1) {
5757+ int r = read(fd, &canary, sizeof(canary));
5758+ close(fd);
5759+ if (r == sizeof(canary)) {
5760+ return (canary);
5761+ }
5762+ }
5763+ /* not good but we never want to do this */
5764+ time(&t);
5765+ canary = *(unsigned int *)&t + getpid() << 16;
5766+ return (canary);
5767+}
5768+#endif
5769+
5770+#if HARDENING_PATCH_INC_PROTECT
5771+
5772+PHPAPI int php_is_valid_include(zval *z)
5773+{
5774+ char *filename;
5775+ int len, i;
5776+ TSRMLS_FETCH();
5777+
5778+ /* must be of type string */
5779+ if (z->type != IS_STRING || z->value.str.val == NULL) {
5780+ return (0);
5781+ }
5782+
5783+ /* short cut */
5784+ filename = z->value.str.val;
5785+ len = z->value.str.len;
5786+
5787+ /* 1. must be shorter than MAXPATHLEN */
5788+ if (len > MAXPATHLEN) {
5789+ char *fname = estrndup(filename, len);
5790+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
5791+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
5792+ efree(fname);
5793+ return (0);
5794+ }
5795+
5796+ /* 2. must not be cutted */
5797+ if (len != strlen(filename)) {
5798+ char *fname = estrndup(filename, len);
5799+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
5800+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
5801+ efree(fname);
5802+ return (0);
5803+ }
5804+
5805+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
5806+ if (strstr(filename, "://")) {
5807+ char *fname = estrndup(filename, len);
5808+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
5809+
5810+ /* no black or whitelist then disallow all */
5811+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
5812+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
5813+ efree(fname);
5814+ return (0);
5815+ }
5816+
5817+ /* whitelist is stronger than blacklist */
5818+ if (HG(include_whitelist)) {
5819+ char *s, *t, *h, *index;
5820+ uint indexlen;
5821+ ulong numindex;
5822+
5823+ s = filename;
5824+
5825+ do {
5826+ zend_bool isOk = 0;
5827+ int tlen;
5828+
5829+ t = h = strstr(s, "://");
5830+ if (h == NULL) break;
5831+
5832+
5833+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
5834+ t--;
5835+ }
5836+
5837+ tlen = strlen(t);
5838+
5839+ zend_hash_internal_pointer_reset(HG(include_whitelist));
5840+ do {
5841+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
5842+
5843+ if (r==HASH_KEY_NON_EXISTANT) {
5844+ break;
5845+ }
5846+ if (r==HASH_KEY_IS_STRING) {
5847+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
5848+ if (strncmp(t, index, indexlen-1)==0) {
5849+ isOk = 1;
5850+ break;
5851+ }
5852+ }
5853+ }
5854+
5855+ zend_hash_move_forward(HG(include_whitelist));
5856+ } while (1);
5857+
5858+ /* not found in whitelist */
5859+ if (!isOk) {
5860+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
5861+ efree(fname);
5862+ return 0;
5863+ }
5864+
5865+ s = h + 3;
5866+ } while (1);
5867+ } else {
5868+ /* okay then handle the blacklist */
5869+ char *s, *t, *h, *index;
5870+ uint indexlen;
5871+ ulong numindex;
5872+
5873+ s = filename;
5874+
5875+ do {
5876+ int tlen;
5877+
5878+ t = h = strstr(s, "://");
5879+ if (h == NULL) break;
5880+
5881+
5882+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
5883+ t--;
5884+ }
5885+
5886+ tlen = strlen(t);
5887+
5888+ zend_hash_internal_pointer_reset(HG(include_blacklist));
5889+ do {
5890+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
5891+
5892+ if (r==HASH_KEY_NON_EXISTANT) {
5893+ break;
5894+ }
5895+ if (r==HASH_KEY_IS_STRING) {
5896+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
5897+ if (strncmp(t, index, indexlen-1)==0) {
5898+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
5899+ efree(fname);
5900+ return 0;
5901+ }
5902+ }
5903+ }
5904+
5905+ zend_hash_move_forward(HG(include_blacklist));
5906+ } while (1);
5907+
5908+ s = h + 3;
5909+ } while (1);
5910+ }
5911+
5912+ efree(fname);
5913+ }
5914+
5915+ /* 4. must not be an uploaded file */
5916+ if (SG(rfc1867_uploaded_files)) {
5917+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
5918+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
5919+ return (0);
5920+ }
5921+ }
5922+
5923+ /* passed all tests */
5924+ return (1);
5925+}
5926+
5927+#endif
5928+
5929+/*
5930+ * Local variables:
5931+ * tab-width: 4
5932+ * c-basic-offset: 4
5933+ * End:
5934+ * vim600: sw=4 ts=4 fdm=marker
5935+ * vim<600: sw=4 ts=4
5936+ */
5937diff -Nura php-5.1.4/main/hardening_patch.h hardening-patch-5.1.4-0.4.15/main/hardening_patch.h
5938--- php-5.1.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
5939+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.h 2006-09-07 18:51:30.000000000 +0200
5940@@ -0,0 +1,46 @@
5941+/*
5942+ +----------------------------------------------------------------------+
5943+ | Hardening Patch for PHP |
5944+ +----------------------------------------------------------------------+
5945+ | Copyright (c) 2004-2005 Stefan Esser |
5946+ +----------------------------------------------------------------------+
5947+ | This source file is subject to version 2.02 of the PHP license, |
5948+ | that is bundled with this package in the file LICENSE, and is |
5949+ | available at through the world-wide-web at |
5950+ | http://www.php.net/license/2_02.txt. |
5951+ | If you did not receive a copy of the PHP license and are unable to |
5952+ | obtain it through the world-wide-web, please send a note to |
5953+ | license@php.net so we can mail you a copy immediately. |
5954+ +----------------------------------------------------------------------+
5955+ | Author: Stefan Esser <sesser@hardened-php.net> |
5956+ +----------------------------------------------------------------------+
5957+ */
5958+
5959+#ifndef HARDENING_PATCH_H
5960+#define HARDENING_PATCH_H
5961+
5962+#include "zend.h"
5963+
5964+#if HARDENING_PATCH
5965+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
5966+PHPAPI void hardened_startup();
5967+#define HARDENING_PATCH_VERSION "0.4.15"
5968+
5969+#endif
5970+
5971+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
5972+PHPAPI unsigned int php_canary();
5973+#endif
5974+
5975+#if HARDENING_PATCH_INC_PROTECT
5976+PHPAPI int php_is_valid_include(zval *z);
5977+#endif
5978+
5979+#endif /* HARDENING_PATCH_H */
5980+
5981+/*
5982+ * Local variables:
5983+ * tab-width: 4
5984+ * c-basic-offset: 4
5985+ * End:
5986+ */
5987diff -Nura php-5.1.4/main/hardening_patch.m4 hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4
5988--- php-5.1.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
5989+++ hardening-patch-5.1.4-0.4.15/main/hardening_patch.m4 2006-09-05 20:31:05.000000000 +0200
5990@@ -0,0 +1,95 @@
5991+dnl
5992+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
5993+dnl
5994+dnl This file contains Hardening Patch for PHP specific autoconf functions.
5995+dnl
5996+
5997+AC_ARG_ENABLE(hardening-patch-mm-protect,
5998+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
5999+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
6000+],[
6001+ DO_HARDENING_PATCH_MM_PROTECT=yes
6002+])
6003+
6004+AC_ARG_ENABLE(hardening-patch-ll-protect,
6005+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
6006+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
6007+],[
6008+ DO_HARDENING_PATCH_LL_PROTECT=yes
6009+])
6010+
6011+AC_ARG_ENABLE(hardening-patch-inc-protect,
6012+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
6013+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
6014+],[
6015+ DO_HARDENING_PATCH_INC_PROTECT=yes
6016+])
6017+
6018+AC_ARG_ENABLE(hardening-patch-fmt-protect,
6019+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
6020+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
6021+],[
6022+ DO_HARDENING_PATCH_FMT_PROTECT=yes
6023+])
6024+
6025+AC_ARG_ENABLE(hardening-patch-hash-protect,
6026+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
6027+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
6028+],[
6029+ DO_HARDENING_PATCH_HASH_PROTECT=yes
6030+])
6031+
6032+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
6033+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
6034+
6035+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
6036+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
6037+
6038+AC_MSG_CHECKING(whether to protect include/require statements)
6039+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
6040+
6041+AC_MSG_CHECKING(whether to protect PHP Format String functions)
6042+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
6043+
6044+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
6045+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
6046+
6047+
6048+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6049+
6050+
6051+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
6052+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6053+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
6054+else
6055+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
6056+fi
6057+
6058+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
6059+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6060+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
6061+else
6062+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
6063+fi
6064+
6065+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
6066+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6067+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
6068+else
6069+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
6070+fi
6071+
6072+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
6073+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6074+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
6075+else
6076+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
6077+fi
6078+
6079+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
6080+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
6081+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
6082+else
6083+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
6084+fi
6085+
6086diff -Nura php-5.1.4/main/main.c hardening-patch-5.1.4-0.4.15/main/main.c
6087--- php-5.1.4/main/main.c 2006-04-12 14:49:39.000000000 +0200
6088+++ hardening-patch-5.1.4-0.4.15/main/main.c 2006-09-05 20:31:05.000000000 +0200
6089@@ -85,6 +85,10 @@
6090
6091 #include "SAPI.h"
6092 #include "rfc1867.h"
6093+#if HARDENING_PATCH
6094+#include "hardened_globals.h"
6095+#endif
6096+
6097 /* }}} */
6098
6099 #ifndef ZTS
6100@@ -109,17 +113,39 @@
6101 */
6102 static PHP_INI_MH(OnChangeMemoryLimit)
6103 {
6104+#if HARDENING_PATCH
6105+ long hard_memory_limit = 1<<30;
6106+
6107+ if (stage == ZEND_INI_STAGE_RUNTIME) {
6108+ if (HG(hard_memory_limit) == 0) {
6109+ HG(hard_memory_limit) = PG(memory_limit);
6110+ }
6111+ hard_memory_limit = HG(hard_memory_limit);
6112+ } else {
6113+ HG(hard_memory_limit) = 0;
6114+ }
6115+#endif
6116 if (new_value) {
6117 PG(memory_limit) = zend_atoi(new_value, new_value_length);
6118+#if HARDENING_PATCH
6119+ if (PG(memory_limit) > hard_memory_limit) {
6120+ PG(memory_limit) = hard_memory_limit;
6121+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
6122+ return FAILURE;
6123+ }
6124+#endif
6125 } else {
6126+#if HARDENING_PATCH
6127+ PG(memory_limit) = hard_memory_limit;
6128+#else
6129 PG(memory_limit) = 1<<30; /* effectively, no limit */
6130+#endif
6131 }
6132 return zend_set_memory_limit(PG(memory_limit));
6133 }
6134 /* }}} */
6135 #endif
6136
6137-
6138 /* {{{ php_disable_functions
6139 */
6140 static void php_disable_functions(TSRMLS_D)
6141@@ -1095,6 +1121,13 @@
6142 sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
6143 }
6144
6145+ /* Disable realpath cache if safe_mode or open_basedir are set */
6146+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
6147+ CWDG(realpath_cache_disable) = 1;
6148+ } else {
6149+ CWDG(realpath_cache_disable) = 0;
6150+ }
6151+
6152 if (PG(output_handler) && PG(output_handler)[0]) {
6153 php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC);
6154 } else if (PG(output_buffering)) {
6155@@ -1222,6 +1255,9 @@
6156
6157 zend_try {
6158 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
6159+#if HARDENING_PATCH
6160+ hardened_clear_mm_canaries(TSRMLS_C);
6161+#endif
6162 } zend_end_try();
6163
6164 zend_try {
6165@@ -1393,6 +1429,10 @@
6166 tsrm_ls = ts_resource(0);
6167 #endif
6168
6169+#if HARDENING_PATCH
6170+ hardened_startup();
6171+#endif
6172+
6173 module_shutdown = 0;
6174 module_startup = 1;
6175 sapi_initialize_empty_request(TSRMLS_C);
6176@@ -1406,6 +1446,12 @@
6177
6178 php_output_startup();
6179
6180+#if HARDENING_PATCH_INC_PROTECT
6181+ zuf.is_valid_include = php_is_valid_include;
6182+#endif
6183+#if HARDENING_PATCH
6184+ zuf.security_log_function = php_security_log;
6185+#endif
6186 zuf.error_function = php_error_cb;
6187 zuf.printf_function = php_printf;
6188 zuf.write_function = php_body_write_wrapper;
6189@@ -1476,7 +1522,9 @@
6190
6191 /* Disable realpath cache if safe_mode or open_basedir are set */
6192 if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
6193- CWDG(realpath_cache_size_limit) = 0;
6194+ CWDG(realpath_cache_disable) = 1;
6195+ } else {
6196+ CWDG(realpath_cache_disable) = 0;
6197 }
6198
6199 /* initialize stream wrappers registry
6200@@ -1517,6 +1565,10 @@
6201 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
6202 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);
6203 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
6204+#if HARDENING_PATCH
6205+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
6206+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
6207+#endif
6208 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
6209 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
6210 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
6211diff -Nura php-5.1.4/main/php_config.h.in hardening-patch-5.1.4-0.4.15/main/php_config.h.in
6212--- php-5.1.4/main/php_config.h.in 2006-05-12 16:41:13.000000000 +0200
6213+++ hardening-patch-5.1.4-0.4.15/main/php_config.h.in 2006-09-05 20:31:05.000000000 +0200
6214@@ -788,6 +788,39 @@
6215 /* Enabling BIND8 compatibility for Panther */
6216 #undef BIND_8_COMPAT
6217
6218+/* Hardening-Patch for PHP */
6219+#undef HARDENING_PATCH
6220+
6221+/* Memory Manager Protection */
6222+#undef HARDENING_PATCH_MM_PROTECT
6223+
6224+/* Memory Manager Protection */
6225+#undef HARDENING_PATCH_MM_PROTECT
6226+
6227+/* Linked List Protection */
6228+#undef HARDENING_PATCH_LL_PROTECT
6229+
6230+/* Linked List Protection */
6231+#undef HARDENING_PATCH_LL_PROTECT
6232+
6233+/* Include/Require Protection */
6234+#undef HARDENING_PATCH_INC_PROTECT
6235+
6236+/* Include/Require Protection */
6237+#undef HARDENING_PATCH_INC_PROTECT
6238+
6239+/* Fmt String Protection */
6240+#undef HARDENING_PATCH_FMT_PROTECT
6241+
6242+/* Fmt String Protection */
6243+#undef HARDENING_PATCH_FMT_PROTECT
6244+
6245+/* HashTable DTOR Protection */
6246+#undef HARDENING_PATCH_HASH_PROTECT
6247+
6248+/* HashTable DTOR Protection */
6249+#undef HARDENING_PATCH_HASH_PROTECT
6250+
6251 /* Whether you have AOLserver */
6252 #undef HAVE_AOLSERVER
6253
6254@@ -1131,6 +1164,12 @@
6255 /* Define if you have the getaddrinfo function */
6256 #undef HAVE_GETADDRINFO
6257
6258+/* Whether realpath is broken */
6259+#undef PHP_BROKEN_REALPATH
6260+
6261+/* Whether realpath is broken */
6262+#undef PHP_BROKEN_REALPATH
6263+
6264 /* Whether system headers declare timezone */
6265 #undef HAVE_DECLARED_TIMEZONE
6266
6267diff -Nura php-5.1.4/main/php.h hardening-patch-5.1.4-0.4.15/main/php.h
6268--- php-5.1.4/main/php.h 2006-03-07 23:37:53.000000000 +0100
6269+++ hardening-patch-5.1.4-0.4.15/main/php.h 2006-09-05 20:31:05.000000000 +0200
6270@@ -35,11 +35,19 @@
6271 #include "zend_qsort.h"
6272 #include "php_compat.h"
6273
6274+
6275 #include "zend_API.h"
6276
6277 #undef sprintf
6278 #define sprintf php_sprintf
6279
6280+#if HARDENING_PATCH
6281+#if HAVE_REALPATH
6282+#undef realpath
6283+#define realpath php_realpath
6284+#endif
6285+#endif
6286+
6287 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
6288 #undef PHP_DEBUG
6289 #define PHP_DEBUG ZEND_DEBUG
6290@@ -338,6 +346,7 @@
6291 #define PHP_FUNCTION ZEND_FUNCTION
6292 #define PHP_METHOD ZEND_METHOD
6293
6294+#define PHP_STATIC_FE ZEND_STATIC_FE
6295 #define PHP_NAMED_FE ZEND_NAMED_FE
6296 #define PHP_FE ZEND_FE
6297 #define PHP_DEP_FE ZEND_DEP_FE
6298@@ -447,6 +456,10 @@
6299 #endif
6300 #endif /* !XtOffsetOf */
6301
6302+#if HARDENING_PATCH
6303+#include "hardening_patch.h"
6304+#endif
6305+
6306 #endif
6307
6308 /*
6309diff -Nura php-5.1.4/main/php_open_temporary_file.c hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c
6310--- php-5.1.4/main/php_open_temporary_file.c 2006-01-01 13:50:17.000000000 +0100
6311+++ hardening-patch-5.1.4-0.4.15/main/php_open_temporary_file.c 2006-09-05 20:31:05.000000000 +0200
6312@@ -114,17 +114,16 @@
6313
6314 path_len = strlen(path);
6315
6316- if (!(opened_path = emalloc(MAXPATHLEN))) {
6317- return -1;
6318- }
6319-
6320 if (!path_len || IS_SLASH(path[path_len - 1])) {
6321 trailing_slash = "";
6322 } else {
6323 trailing_slash = "/";
6324 }
6325
6326- (void)snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", path, trailing_slash, pfx);
6327+ if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", path, trailing_slash, pfx) >= MAXPATHLEN) {
6328+ efree(opened_path);
6329+ return -1;
6330+ }
6331
6332 #ifdef PHP_WIN32
6333 if (GetTempFileName(path, pfx, 0, opened_path)) {
6334diff -Nura php-5.1.4/main/php_variables.c hardening-patch-5.1.4-0.4.15/main/php_variables.c
6335--- php-5.1.4/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200
6336+++ hardening-patch-5.1.4-0.4.15/main/php_variables.c 2006-09-05 20:31:05.000000000 +0200
6337@@ -73,6 +73,10 @@
6338 symtable1 = Z_ARRVAL_P(track_vars_array);
6339 } else if (PG(register_globals)) {
6340 symtable1 = EG(active_symbol_table);
6341+ /* GLOBALS hijack attempt, reject parameter */
6342+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) {
6343+ symtable1 = NULL;
6344+ }
6345 }
6346 if (!symtable1) {
6347 /* Nothing to do */
6348@@ -513,7 +517,7 @@
6349 */
6350 static inline void php_register_server_variables(TSRMLS_D)
6351 {
6352- zval *array_ptr = NULL;
6353+ zval *array_ptr = NULL, *vptr;
6354 /* turn off magic_quotes while importing server variables */
6355 int magic_quotes_gpc = PG(magic_quotes_gpc);
6356
6357diff -Nura php-5.1.4/main/rfc1867.c hardening-patch-5.1.4-0.4.15/main/rfc1867.c
6358--- php-5.1.4/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100
6359+++ hardening-patch-5.1.4-0.4.15/main/rfc1867.c 2006-09-05 20:31:05.000000000 +0200
6360@@ -132,6 +132,7 @@
6361 #define UPLOAD_ERROR_D 4 /* No file uploaded */
6362 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
6363 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
6364+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
6365
6366 void php_rfc1867_register_constants(TSRMLS_D)
6367 {
6368@@ -142,6 +143,7 @@
6369 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
6370 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
6371 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
6372+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
6373 }
6374
6375 static void normalize_protected_variable(char *varname TSRMLS_DC)
6376@@ -854,6 +856,7 @@
6377 char buff[FILLUNIT];
6378 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
6379 int blen=0, wlen=0;
6380+ unsigned long offset;
6381
6382 zend_llist_clean(&header);
6383
6384@@ -970,7 +973,11 @@
6385 tmp++;
6386 }
6387 }
6388-
6389+
6390+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
6391+ skip_upload = 1;
6392+ }
6393+
6394 total_bytes = cancel_upload = 0;
6395
6396 if (!skip_upload) {
6397@@ -994,6 +1001,11 @@
6398 cancel_upload = UPLOAD_ERROR_D;
6399 }
6400
6401+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
6402+ cancel_upload = UPLOAD_ERROR_X;
6403+ }
6404+
6405+ offset = 0;
6406 end = 0;
6407 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
6408 {
6409@@ -1008,6 +1020,10 @@
6410 #endif
6411 cancel_upload = UPLOAD_ERROR_B;
6412 } else if (blen > 0) {
6413+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
6414+ cancel_upload = UPLOAD_ERROR_X;
6415+ }
6416+
6417 wlen = write(fd, buff, blen);
6418
6419 if (wlen < blen) {
6420@@ -1036,6 +1052,10 @@
6421 }
6422 #endif
6423
6424+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
6425+ cancel_upload = UPLOAD_ERROR_X;
6426+ }
6427+
6428 if (cancel_upload) {
6429 if (temp_filename) {
6430 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
6431diff -Nura php-5.1.4/main/SAPI.c hardening-patch-5.1.4-0.4.15/main/SAPI.c
6432--- php-5.1.4/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100
6433+++ hardening-patch-5.1.4-0.4.15/main/SAPI.c 2006-09-05 20:31:05.000000000 +0200
6434@@ -870,6 +870,36 @@
6435 post_entry->content_type_len+1);
6436 }
6437
6438+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))
6439+{
6440+ sapi_module.input_filter = input_filter;
6441+ return SUCCESS;
6442+}
6443+
6444+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
6445+{
6446+ sapi_module.upload_varname_filter = upload_varname_filter;
6447+ return SUCCESS;
6448+}
6449+
6450+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
6451+{
6452+ sapi_module.pre_upload_filter = pre_upload_filter;
6453+ return SUCCESS;
6454+}
6455+
6456+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))
6457+{
6458+ sapi_module.upload_content_filter = upload_content_filter;
6459+ return SUCCESS;
6460+}
6461+
6462+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
6463+{
6464+ sapi_module.post_upload_filter = post_upload_filter;
6465+ return SUCCESS;
6466+}
6467+
6468
6469 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
6470 {
6471@@ -884,11 +914,6 @@
6472 return SUCCESS;
6473 }
6474
6475-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))
6476-{
6477- sapi_module.input_filter = input_filter;
6478- return SUCCESS;
6479-}
6480
6481 SAPI_API int sapi_flush(TSRMLS_D)
6482 {
6483diff -Nura php-5.1.4/main/SAPI.h hardening-patch-5.1.4-0.4.15/main/SAPI.h
6484--- php-5.1.4/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100
6485+++ hardening-patch-5.1.4-0.4.15/main/SAPI.h 2006-09-05 20:31:05.000000000 +0200
6486@@ -190,6 +190,10 @@
6487 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
6488 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));
6489
6490+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
6491+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));
6492+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
6493+
6494 SAPI_API int sapi_flush(TSRMLS_D);
6495 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
6496 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
6497@@ -254,6 +258,11 @@
6498 int (*get_target_gid)(gid_t * TSRMLS_DC);
6499
6500 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
6501+
6502+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
6503+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
6504+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
6505+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
6506
6507 void (*ini_defaults)(HashTable *configuration_hash);
6508 int phpinfo_as_text;
6509@@ -279,7 +288,11 @@
6510
6511 #define SAPI_DEFAULT_MIMETYPE "text/html"
6512 #define SAPI_DEFAULT_CHARSET ""
6513+#if HARDENING_PATCH
6514+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
6515+#else
6516 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
6517+#endif
6518
6519 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
6520 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
6521@@ -287,6 +300,11 @@
6522 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
6523 #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)
6524
6525+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
6526+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
6527+#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)
6528+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
6529+
6530 BEGIN_EXTERN_C()
6531 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
6532 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
6533diff -Nura php-5.1.4/main/snprintf.c hardening-patch-5.1.4-0.4.15/main/snprintf.c
6534--- php-5.1.4/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100
6535+++ hardening-patch-5.1.4-0.4.15/main/snprintf.c 2006-09-05 20:31:05.000000000 +0200
6536@@ -1014,7 +1014,11 @@
6537
6538
6539 case 'n':
6540+#if HARDENING_PATCH_FMT_PROTECT
6541+ php_security_log(S_MISC, "'n' specifier within format string");
6542+#else
6543 *(va_arg(ap, int *)) = cc;
6544+#endif
6545 goto skip_output;
6546
6547 /*
6548diff -Nura php-5.1.4/main/spprintf.c hardening-patch-5.1.4-0.4.15/main/spprintf.c
6549--- php-5.1.4/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100
6550+++ hardening-patch-5.1.4-0.4.15/main/spprintf.c 2006-09-05 20:31:05.000000000 +0200
6551@@ -630,7 +630,11 @@
6552
6553
6554 case 'n':
6555+#if HARDENING_PATCH_FMT_PROTECT
6556+ php_security_log(S_MISC, "'n' specifier within format string");
6557+#else
6558 *(va_arg(ap, int *)) = xbuf->len;
6559+#endif
6560 goto skip_output;
6561
6562 /*
6563diff -Nura php-5.1.4/pear/Makefile.frag hardening-patch-5.1.4-0.4.15/pear/Makefile.frag
6564--- php-5.1.4/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100
6565+++ hardening-patch-5.1.4-0.4.15/pear/Makefile.frag 2006-09-05 20:31:05.000000000 +0200
6566@@ -3,7 +3,7 @@
6567 peardir=$(PEAR_INSTALLDIR)
6568
6569 # Skip all php.ini files altogether
6570-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0
6571+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
6572
6573 install-pear-installer: $(SAPI_CLI_PATH)
6574 @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)"
6575diff -Nura php-5.1.4/php.ini-dist hardening-patch-5.1.4-0.4.15/php.ini-dist
6576--- php-5.1.4/php.ini-dist 2006-02-09 00:43:48.000000000 +0100
6577+++ hardening-patch-5.1.4-0.4.15/php.ini-dist 2006-09-05 20:31:05.000000000 +0200
6578@@ -1197,6 +1197,209 @@
6579 ; instead of original one.
6580 soap.wsdl_cache_ttl=86400
6581
6582+[hardening-patch]
6583+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6584+; Hardening-Patch's logging ;
6585+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6586+
6587+;
6588+; hphp.log.syslog - Configures level for alerts reported through syslog
6589+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
6590+; hphp.log.script - Configures level for alerts reported through external script
6591+;
6592+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
6593+; Or each number up to get desired Hardening-Patch's reporting level
6594+;
6595+; S_ALL - All alerts
6596+; S_MEMORY - All canary violations and the safe unlink protection use this class
6597+; S_VARS - All variable filters trigger this class
6598+; S_FILES - All violation of uploaded files filter use this class
6599+; S_INCLUDE - The protection against malicious include filenames use this class
6600+; S_SQL - Failed SQL queries in MySQL are logged with this class
6601+; S_EXECUTOR - The execution depth protection uses this logging class
6602+; S_MISC - All other log messages (f.e. format string protection) use this class
6603+;
6604+; Example:
6605+;
6606+; - Report all alerts (except memory alerts) to the SAPI errorlog,
6607+; memory alerts through syslog and SQL+Include alerts fo the script
6608+;
6609+;hphp.log.syslog = S_MEMORY
6610+;hphp.log.sapi = S_ALL & ~S_MEMORY
6611+;hphp.log.script = S_INCLUDE | S_SQL
6612+;
6613+; Syslog logging:
6614+;
6615+; - Facility configuration: one of the following facilities
6616+;
6617+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
6618+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
6619+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
6620+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
6621+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
6622+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
6623+; LOG_PERROR
6624+;
6625+; - Priority configuration: one of the followinf priorities
6626+;
6627+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
6628+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
6629+;
6630+hphp.log.syslog.priority = LOG_ALERT
6631+hphp.log.syslog.facility = LOG_USER
6632+;
6633+; Script logging:
6634+;
6635+;hphp.log.script.name = /home/hphp/log_script
6636+;
6637+; Alert configuration:
6638+;
6639+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
6640+;
6641+;hphp.log.use-x-forwarded-for = On
6642+;
6643+
6644+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6645+; Hardening-Patch's Executor options ;
6646+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6647+
6648+; Execution depth limit
6649+;hphp.executor.max_depth = 8000
6650+
6651+; White-/blacklist for function calls during normal execution
6652+;hphp.executor.func.whitelist = ord,chr
6653+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
6654+
6655+; White-/blacklist for function calls during eval() execution
6656+;hphp.executor.eval.whitelist = ord,chr
6657+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
6658+
6659+; White-/blacklist for URLs allowes in include filenames
6660+;
6661+; - When both options are not set all URLs are forbidden
6662+;
6663+; - When both options are set whitelist is taken and blacklist ignored
6664+;
6665+; - An entry in the lists is either a URL sheme like: http, https
6666+; or the beginning of an URL like: php://input
6667+;
6668+;hphp.executor.include.whitelist = cookietest
6669+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
6670+
6671+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6672+; Hardening-Patch's REQUEST variable filters ;
6673+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6674+
6675+; Limits the number of REQUEST variables
6676+hphp.request.max_vars = 200
6677+
6678+; Limits the length of variable names (without indices)
6679+hphp.request.max_varname_length = 64
6680+
6681+; Limits the length of complete variable names (with indices)
6682+hphp.request.max_totalname_length = 256
6683+
6684+; Limits the length of array indices
6685+hphp.request.max_array_index_length = 64
6686+
6687+; Limits the depth of arrays
6688+hphp.request.max_array_depth = 100
6689+
6690+; Limits the length of variable values
6691+hphp.request.max_value_length = 65000
6692+
6693+; Disallow ASCII-NUL characters in input
6694+hphp.request.disallow_nul = 1
6695+
6696+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6697+; Hardening-Patch's COOKIE variable filters ;
6698+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6699+
6700+; Limits the number of COOKIE variables
6701+hphp.cookie.max_vars = 100
6702+
6703+; Limits the length of variable names (without indices)
6704+hphp.cookie.max_name_length = 64
6705+
6706+; Limits the length of complete variable names (with indices)
6707+hphp.cookie.max_totalname_length = 256
6708+
6709+; Limits the length of array indices
6710+hphp.cookie.max_array_index_length = 64
6711+
6712+; Limits the depth of arrays
6713+hphp.cookie.max_array_depth = 100
6714+
6715+; Limits the length of variable values
6716+hphp.cookie.max_value_length = 10000
6717+
6718+; Disallow ASCII-NUL characters in input
6719+hphp.cookie.disallow_nul = 1
6720+
6721+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6722+; Hardening-Patch's GET variable filters ;
6723+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6724+
6725+; Limits the number of COOKIE variables
6726+hphp.get.max_vars = 100
6727+
6728+; Limits the length of variable names (without indices)
6729+hphp.get.max_name_length = 64
6730+
6731+; Limits the length of complete variable names (with indices)
6732+hphp.get.max_totalname_length = 256
6733+
6734+; Limits the length of array indices
6735+hphp.get.max_array_index_length = 64
6736+
6737+; Limits the depth of arrays
6738+hphp.get.max_array_depth = 50
6739+
6740+; Limits the length of variable values
6741+hphp.get.max_value_length = 512
6742+
6743+; Disallow ASCII-NUL characters in input
6744+hphp.get.disallow_nul = 1
6745+
6746+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6747+; Hardening-Patch's POST variable filters ;
6748+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6749+
6750+; Limits the number of POST variables
6751+hphp.post.max_vars = 200
6752+
6753+; Limits the length of variable names (without indices)
6754+hphp.post.max_name_length = 64
6755+
6756+; Limits the length of complete variable names (with indices)
6757+hphp.post.max_totalname_length = 256
6758+
6759+; Limits the length of array indices
6760+hphp.post.max_array_index_length = 64
6761+
6762+; Limits the depth of arrays
6763+hphp.post.max_array_depth = 100
6764+
6765+; Limits the length of variable values
6766+hphp.post.max_value_length = 65000
6767+
6768+; Disallow ASCII-NUL characters in input
6769+hphp.post.disallow_nul = 1
6770+
6771+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6772+; Hardening-Patch's fileupload variable filters ;
6773+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6774+
6775+; Limits the number of uploadable files
6776+hphp.upload.max_uploads = 25
6777+
6778+; Filter out the upload of ELF executables
6779+hphp.upload.disallow_elf_files = On
6780+
6781+; External filterscript for upload verification
6782+;hphp.upload.verification_script = /home/hphp/verify_script
6783+
6784+
6785 ; Local Variables:
6786 ; tab-width: 4
6787 ; End:
6788diff -Nura php-5.1.4/php.ini-recommended hardening-patch-5.1.4-0.4.15/php.ini-recommended
6789--- php-5.1.4/php.ini-recommended 2006-02-09 00:43:48.000000000 +0100
6790+++ hardening-patch-5.1.4-0.4.15/php.ini-recommended 2006-09-05 20:31:06.000000000 +0200
6791@@ -1255,6 +1255,209 @@
6792 ; instead of original one.
6793 soap.wsdl_cache_ttl=86400
6794
6795+[hardening-patch]
6796+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6797+; Hardening-Patch's logging ;
6798+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6799+
6800+;
6801+; hphp.log.syslog - Configures level for alerts reported through syslog
6802+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
6803+; hphp.log.script - Configures level for alerts reported through external script
6804+;
6805+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
6806+; Or each number up to get desired Hardening-Patch's reporting level
6807+;
6808+; S_ALL - All alerts
6809+; S_MEMORY - All canary violations and the safe unlink protection use this class
6810+; S_VARS - All variable filters trigger this class
6811+; S_FILES - All violation of uploaded files filter use this class
6812+; S_INCLUDE - The protection against malicious include filenames use this class
6813+; S_SQL - Failed SQL queries in MySQL are logged with this class
6814+; S_EXECUTOR - The execution depth protection uses this logging class
6815+; S_MISC - All other log messages (f.e. format string protection) use this class
6816+;
6817+; Example:
6818+;
6819+; - Report all alerts (except memory alerts) to the SAPI errorlog,
6820+; memory alerts through syslog and SQL+Include alerts fo the script
6821+;
6822+;hphp.log.syslog = S_MEMORY
6823+;hphp.log.sapi = S_ALL & ~S_MEMORY
6824+;hphp.log.script = S_INCLUDE | S_SQL
6825+;
6826+; Syslog logging:
6827+;
6828+; - Facility configuration: one of the following facilities
6829+;
6830+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
6831+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
6832+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
6833+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
6834+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
6835+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
6836+; LOG_PERROR
6837+;
6838+; - Priority configuration: one of the followinf priorities
6839+;
6840+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
6841+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
6842+;
6843+hphp.log.syslog.priority = LOG_ALERT
6844+hphp.log.syslog.facility = LOG_USER
6845+;
6846+; Script logging:
6847+;
6848+;hphp.log.script.name = /home/hphp/log_script
6849+;
6850+; Alert configuration:
6851+;
6852+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
6853+;
6854+;hphp.log.use-x-forwarded-for = On
6855+;
6856+
6857+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6858+; Hardening-Patch's Executor options ;
6859+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6860+
6861+; Execution depth limit
6862+;hphp.executor.max_depth = 8000
6863+
6864+; White-/blacklist for function calls during normal execution
6865+;hphp.executor.func.whitelist = ord,chr
6866+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
6867+
6868+; White-/blacklist for function calls during eval() execution
6869+;hphp.executor.eval.whitelist = ord,chr
6870+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
6871+
6872+; White-/blacklist for URLs allowes in include filenames
6873+;
6874+; - When both options are not set all URLs are forbidden
6875+;
6876+; - When both options are set whitelist is taken and blacklist ignored
6877+;
6878+; - An entry in the lists is either a URL sheme like: http, https
6879+; or the beginning of an URL like: php://input
6880+;
6881+;hphp.executor.include.whitelist = cookietest
6882+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
6883+
6884+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6885+; Hardening-Patch's REQUEST variable filters ;
6886+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6887+
6888+; Limits the number of REQUEST variables
6889+hphp.request.max_vars = 200
6890+
6891+; Limits the length of variable names (without indices)
6892+hphp.request.max_varname_length = 64
6893+
6894+; Limits the length of complete variable names (with indices)
6895+hphp.request.max_totalname_length = 256
6896+
6897+; Limits the length of array indices
6898+hphp.request.max_array_index_length = 64
6899+
6900+; Limits the depth of arrays
6901+hphp.request.max_array_depth = 100
6902+
6903+; Limits the length of variable values
6904+hphp.request.max_value_length = 65000
6905+
6906+; Disallow ASCII-NUL characters in input
6907+hphp.request.disallow_nul = 1
6908+
6909+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6910+; Hardening-Patch's COOKIE variable filters ;
6911+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6912+
6913+; Limits the number of COOKIE variables
6914+hphp.cookie.max_vars = 100
6915+
6916+; Limits the length of variable names (without indices)
6917+hphp.cookie.max_name_length = 64
6918+
6919+; Limits the length of complete variable names (with indices)
6920+hphp.cookie.max_totalname_length = 256
6921+
6922+; Limits the length of array indices
6923+hphp.cookie.max_array_index_length = 64
6924+
6925+; Limits the depth of arrays
6926+hphp.cookie.max_array_depth = 100
6927+
6928+; Limits the length of variable values
6929+hphp.cookie.max_value_length = 10000
6930+
6931+; Disallow ASCII-NUL characters in input
6932+hphp.cookie.disallow_nul = 1
6933+
6934+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6935+; Hardening-Patch's GET variable filters ;
6936+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6937+
6938+; Limits the number of COOKIE variables
6939+hphp.get.max_vars = 100
6940+
6941+; Limits the length of variable names (without indices)
6942+hphp.get.max_name_length = 64
6943+
6944+; Limits the length of complete variable names (with indices)
6945+hphp.get.max_totalname_length = 256
6946+
6947+; Limits the length of array indices
6948+hphp.get.max_array_index_length = 64
6949+
6950+; Limits the depth of arrays
6951+hphp.get.max_array_depth = 50
6952+
6953+; Limits the length of variable values
6954+hphp.get.max_value_length = 512
6955+
6956+; Disallow ASCII-NUL characters in input
6957+hphp.get.disallow_nul = 1
6958+
6959+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6960+; Hardening-Patch's POST variable filters ;
6961+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6962+
6963+; Limits the number of POST variables
6964+hphp.post.max_vars = 200
6965+
6966+; Limits the length of variable names (without indices)
6967+hphp.post.max_name_length = 64
6968+
6969+; Limits the length of complete variable names (with indices)
6970+hphp.post.max_totalname_length = 256
6971+
6972+; Limits the length of array indices
6973+hphp.post.max_array_index_length = 64
6974+
6975+; Limits the depth of arrays
6976+hphp.post.max_array_depth = 100
6977+
6978+; Limits the length of variable values
6979+hphp.post.max_value_length = 65000
6980+
6981+; Disallow ASCII-NUL characters in input
6982+hphp.post.disallow_nul = 1
6983+
6984+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6985+; Hardening-Patch's fileupload variable filters ;
6986+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6987+
6988+; Limits the number of uploadable files
6989+hphp.upload.max_uploads = 25
6990+
6991+; Filter out the upload of ELF executables
6992+hphp.upload.disallow_elf_files = On
6993+
6994+; External filterscript for upload verification
6995+;hphp.upload.verification_script = /home/hphp/verify_script
6996+
6997+
6998 ; Local Variables:
6999 ; tab-width: 4
7000 ; End:
7001diff -Nura php-5.1.4/run-tests.php hardening-patch-5.1.4-0.4.15/run-tests.php
7002--- php-5.1.4/run-tests.php 2006-05-03 23:37:16.000000000 +0200
7003+++ hardening-patch-5.1.4-0.4.15/run-tests.php 2006-09-05 20:31:06.000000000 +0200
7004@@ -161,6 +161,10 @@
7005 'error_reporting=4095',
7006 'display_errors=1',
7007 'log_errors=0',
7008+ 'hphp.executor.include.whitelist=cookietest',
7009+ 'hphp.log.syslog=0',
7010+ 'hphp.log.sapi=0',
7011+ 'hphp.log.script=0',
7012 'html_errors=0',
7013 'track_errors=1',
7014 'report_memleaks=1',
7015diff -Nura php-5.1.4/sapi/apache/mod_php5.c hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c
7016--- php-5.1.4/sapi/apache/mod_php5.c 2006-04-02 19:58:17.000000000 +0200
7017+++ hardening-patch-5.1.4-0.4.15/sapi/apache/mod_php5.c 2006-09-05 20:31:06.000000000 +0200
7018@@ -482,7 +482,7 @@
7019 sapi_apache_get_fd,
7020 sapi_apache_force_http_10,
7021 sapi_apache_get_target_uid,
7022- sapi_apache_get_target_gid
7023+ sapi_apache_get_target_gid,
7024 };
7025 /* }}} */
7026
7027@@ -936,7 +936,11 @@
7028 {
7029 TSRMLS_FETCH();
7030 if (PG(expose_php)) {
7031+#if HARDENING_PATCH
7032+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
7033+#else
7034 ap_add_version_component("PHP/" PHP_VERSION);
7035+#endif
7036 }
7037 }
7038 #endif
7039diff -Nura php-5.1.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c
7040--- php-5.1.4/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
7041+++ hardening-patch-5.1.4-0.4.15/sapi/apache2filter/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200
7042@@ -573,7 +573,11 @@
7043 {
7044 TSRMLS_FETCH();
7045 if (PG(expose_php)) {
7046+#if HARDENING_PATCH
7047+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
7048+#else
7049 ap_add_version_component(p, "PHP/" PHP_VERSION);
7050+#endif
7051 }
7052 }
7053
7054diff -Nura php-5.1.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c
7055--- php-5.1.4/sapi/apache2handler/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
7056+++ hardening-patch-5.1.4-0.4.15/sapi/apache2handler/sapi_apache2.c 2006-09-05 20:31:06.000000000 +0200
7057@@ -341,7 +341,11 @@
7058 {
7059 TSRMLS_FETCH();
7060 if (PG(expose_php)) {
7061+#if HARDENING_PATCH
7062+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
7063+#else
7064 ap_add_version_component(p, "PHP/" PHP_VERSION);
7065+#endif
7066 }
7067 }
7068
7069diff -Nura php-5.1.4/sapi/cgi/cgi_main.c hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c
7070--- php-5.1.4/sapi/cgi/cgi_main.c 2006-05-03 21:40:58.000000000 +0200
7071+++ hardening-patch-5.1.4-0.4.15/sapi/cgi/cgi_main.c 2006-09-05 20:31:06.000000000 +0200
7072@@ -1444,10 +1444,18 @@
7073 SG(headers_sent) = 1;
7074 SG(request_info).no_headers = 1;
7075 }
7076+#if HARDENING_PATCH
7077 #if ZEND_DEBUG
7078- 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());
7079+ 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());
7080 #else
7081- 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());
7082+ 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());
7083+#endif
7084+#else
7085+#if ZEND_DEBUG
7086+ 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());
7087+#else
7088+ 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());
7089+#endif
7090 #endif
7091 php_end_ob_buffers(1 TSRMLS_CC);
7092 exit(0);
7093diff -Nura php-5.1.4/sapi/cli/php_cli.c hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c
7094--- php-5.1.4/sapi/cli/php_cli.c 2006-02-21 22:15:13.000000000 +0100
7095+++ hardening-patch-5.1.4-0.4.15/sapi/cli/php_cli.c 2006-09-05 20:31:06.000000000 +0200
7096@@ -753,8 +753,14 @@
7097 goto err;
7098 }
7099
7100+#if HARDENING_PATCH
7101+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
7102+ PHP_VERSION, HARDENING_PATCH_VERSION,
7103+#else
7104 php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
7105- PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
7106+ PHP_VERSION,
7107+#endif
7108+ sapi_module.name, __DATE__, __TIME__,
7109 #if ZEND_DEBUG && defined(HAVE_GCOV)
7110 "(DEBUG GCOV)",
7111 #elif ZEND_DEBUG
7112diff -Nura php-5.1.4/TSRM/TSRM.h hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h
7113--- php-5.1.4/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100
7114+++ hardening-patch-5.1.4-0.4.15/TSRM/TSRM.h 2006-09-05 20:31:06.000000000 +0200
7115@@ -33,6 +33,13 @@
7116 # define TSRM_API
7117 #endif
7118
7119+#if HARDENING_PATCH
7120+# if HAVE_REALPATH
7121+# undef realpath
7122+# define realpath php_realpath
7123+# endif
7124+#endif
7125+
7126 /* Only compile multi-threading functions if we're in ZTS mode */
7127 #ifdef ZTS
7128
7129@@ -88,6 +95,7 @@
7130
7131 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
7132
7133+
7134 #ifdef __cplusplus
7135 extern "C" {
7136 #endif
7137diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c
7138--- php-5.1.4/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100
7139+++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.c 2006-09-05 20:31:06.000000000 +0200
7140@@ -163,6 +163,7 @@
7141 static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
7142 {
7143 CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
7144+ cwd_globals->realpath_cache_disable = 0;
7145 cwd_globals->realpath_cache_size = 0;
7146 cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
7147 cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL;
7148@@ -201,6 +202,176 @@
7149 return p;
7150 }
7151
7152+#if HARDENING_PATCH
7153+CWD_API char *php_realpath(const char *path, char *resolved)
7154+{
7155+ struct stat sb;
7156+ char *p, *q, *s;
7157+ size_t left_len, resolved_len;
7158+ unsigned symlinks;
7159+ int serrno, slen;
7160+ int is_dir = 1;
7161+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
7162+
7163+ serrno = errno;
7164+ symlinks = 0;
7165+ if (path[0] == '/') {
7166+ resolved[0] = '/';
7167+ resolved[1] = '\0';
7168+ if (path[1] == '\0')
7169+ return (resolved);
7170+ resolved_len = 1;
7171+ left_len = strlcpy(left, path + 1, sizeof(left));
7172+ } else {
7173+ if (getcwd(resolved, PATH_MAX) == NULL) {
7174+ strlcpy(resolved, ".", PATH_MAX);
7175+ return (NULL);
7176+ }
7177+ resolved_len = strlen(resolved);
7178+ left_len = strlcpy(left, path, sizeof(left));
7179+ }
7180+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
7181+ errno = ENAMETOOLONG;
7182+ return (NULL);
7183+ }
7184+
7185+ /*
7186+ * Iterate over path components in `left'.
7187+ */
7188+ while (left_len != 0) {
7189+ /*
7190+ * Extract the next path component and adjust `left'
7191+ * and its length.
7192+ */
7193+ p = strchr(left, '/');
7194+ s = p ? p : left + left_len;
7195+ if (s - left >= sizeof(next_token)) {
7196+ errno = ENAMETOOLONG;
7197+ return (NULL);
7198+ }
7199+ memcpy(next_token, left, s - left);
7200+ next_token[s - left] = '\0';
7201+ left_len -= s - left;
7202+ if (p != NULL)
7203+ memmove(left, s + 1, left_len + 1);
7204+ if (resolved[resolved_len - 1] != '/') {
7205+ if (resolved_len + 1 >= PATH_MAX) {
7206+ errno = ENAMETOOLONG;
7207+ return (NULL);
7208+ }
7209+ resolved[resolved_len++] = '/';
7210+ resolved[resolved_len] = '\0';
7211+ }
7212+ if (next_token[0] == '\0')
7213+ continue;
7214+ else if (strcmp(next_token, ".") == 0)
7215+ continue;
7216+ else if (strcmp(next_token, "..") == 0) {
7217+ /*
7218+ * Strip the last path component except when we have
7219+ * single "/"
7220+ */
7221+ if (!is_dir) {
7222+ errno = ENOENT;
7223+ return (NULL);
7224+ }
7225+ if (resolved_len > 1) {
7226+ resolved[resolved_len - 1] = '\0';
7227+ q = strrchr(resolved, '/');
7228+ *q = '\0';
7229+ resolved_len = q - resolved;
7230+ }
7231+ continue;
7232+ }
7233+
7234+ /*
7235+ * Append the next path component and lstat() it. If
7236+ * lstat() fails we still can return successfully if
7237+ * there are no more path components left.
7238+ */
7239+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
7240+ if (resolved_len >= PATH_MAX) {
7241+ errno = ENAMETOOLONG;
7242+ return (NULL);
7243+ }
7244+ if (lstat(resolved, &sb) != 0) {
7245+ if (errno == ENOENT) {
7246+ if (p == NULL) {
7247+ errno = serrno;
7248+ return (resolved);
7249+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
7250+ resolved_len = strlcat(resolved, "/", PATH_MAX);
7251+ resolved_len = strlcat(resolved, left, PATH_MAX);
7252+ if (resolved_len >= PATH_MAX) {
7253+ errno = ENAMETOOLONG;
7254+ return (NULL);
7255+ }
7256+ errno = serrno;
7257+ return (resolved);
7258+ }
7259+ }
7260+ return (NULL);
7261+ }
7262+ if (S_ISLNK(sb.st_mode)) {
7263+ if (symlinks++ > MAXSYMLINKS) {
7264+ errno = ELOOP;
7265+ return (NULL);
7266+ }
7267+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
7268+ if (slen < 0)
7269+ return (NULL);
7270+ symlink[slen] = '\0';
7271+ if (symlink[0] == '/') {
7272+ resolved[1] = 0;
7273+ resolved_len = 1;
7274+ } else if (resolved_len > 1) {
7275+ /* Strip the last path component. */
7276+ resolved[resolved_len - 1] = '\0';
7277+ q = strrchr(resolved, '/');
7278+ *q = '\0';
7279+ resolved_len = q - resolved;
7280+ }
7281+
7282+ /*
7283+ * If there are any path components left, then
7284+ * append them to symlink. The result is placed
7285+ * in `left'.
7286+ */
7287+ if (p != NULL) {
7288+ if (symlink[slen - 1] != '/') {
7289+ if (slen + 1 >= sizeof(symlink)) {
7290+ errno = ENAMETOOLONG;
7291+ return (NULL);
7292+ }
7293+ symlink[slen] = '/';
7294+ symlink[slen + 1] = 0;
7295+ }
7296+ left_len = strlcat(symlink, left, sizeof(left));
7297+ if (left_len >= sizeof(left)) {
7298+ errno = ENAMETOOLONG;
7299+ return (NULL);
7300+ }
7301+ }
7302+ left_len = strlcpy(left, symlink, sizeof(left));
7303+ } else {
7304+ if (S_ISDIR(sb.st_mode)) {
7305+ is_dir = 1;
7306+ } else {
7307+ is_dir = 0;
7308+ }
7309+ }
7310+ }
7311+
7312+ /*
7313+ * Remove trailing slash except when the resolved pathname
7314+ * is a single "/".
7315+ */
7316+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
7317+ resolved[resolved_len - 1] = '\0';
7318+ return (resolved);
7319+}
7320+#endif
7321+
7322 CWD_API void virtual_cwd_startup(void)
7323 {
7324 char cwd[MAXPATHLEN];
7325@@ -381,22 +552,33 @@
7326 #endif
7327 char orig_path[MAXPATHLEN];
7328 int orig_path_len = 0;
7329+ int use_realpath_cache = 1;
7330 realpath_cache_bucket *bucket;
7331 time_t t = 0;
7332 TSRMLS_FETCH();
7333
7334 if (path_length == 0)
7335 return (0);
7336- if (path_length >= MAXPATHLEN)
7337+ if (path_length >= MAXPATHLEN) {
7338+ state->cwd[0] = 0;
7339+ state->cwd_length = 0;
7340 return (1);
7341+ }
7342+
7343+ /* Disable realpath cache if safe_mode or open_basedir are set */
7344+ if (CWDG(realpath_cache_disable)) {
7345+ use_realpath_cache = 0;
7346+ }
7347
7348- if (use_realpath && CWDG(realpath_cache_size_limit)) {
7349+ if (use_realpath && use_realpath_cache) {
7350 if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
7351 memcpy(orig_path, path, path_length+1);
7352 orig_path_len = path_length;
7353 } else {
7354 orig_path_len = path_length + state->cwd_length + 1;
7355 if (orig_path_len >= MAXPATHLEN) {
7356+ state->cwd[0] = 0;
7357+ state->cwd_length = 0;
7358 return 1;
7359 }
7360 memcpy(orig_path, state->cwd, state->cwd_length);
7361@@ -414,6 +596,8 @@
7362 if (verify_path && verify_path(state)) {
7363 CWD_STATE_FREE(state);
7364 *state = old_state;
7365+ state->cwd[0] = 0;
7366+ state->cwd_length = 0;
7367 return 1;
7368 } else {
7369 CWD_STATE_FREE(&old_state);
7370@@ -431,8 +615,9 @@
7371 path = resolved_path;
7372 path_length = strlen(path);
7373 } else {
7374- /* disable for now
7375- return 1; */
7376+ state->cwd[0] = 0;
7377+ state->cwd_length = 0;
7378+ return 1;
7379 }
7380 }
7381 } else { /* Concat current directory with relative path and then run realpath() on it */
7382@@ -441,6 +626,8 @@
7383
7384 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
7385 if (!tmp) {
7386+ state->cwd[0] = 0;
7387+ state->cwd_length = 0;
7388 return 1;
7389 }
7390 memcpy(ptr, state->cwd, state->cwd_length);
7391@@ -451,6 +638,8 @@
7392 *ptr = '\0';
7393 if (strlen(tmp) >= MAXPATHLEN) {
7394 free(tmp);
7395+ state->cwd[0] = 0;
7396+ state->cwd_length = 0;
7397 return 1;
7398 }
7399 if (use_realpath) {
7400@@ -458,9 +647,10 @@
7401 path = resolved_path;
7402 path_length = strlen(path);
7403 } else {
7404- /* disable for now
7405 free(tmp);
7406- return 1; */
7407+ state->cwd[0] = 0;
7408+ state->cwd_length = 0;
7409+ return 1;
7410 }
7411 }
7412 free(tmp);
7413@@ -599,7 +789,7 @@
7414 #endif
7415 free(free_path);
7416
7417- if (use_realpath && CWDG(realpath_cache_size_limit)) {
7418+ if (use_realpath && use_realpath_cache) {
7419 realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC);
7420 }
7421
7422diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h
7423--- php-5.1.4/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200
7424+++ hardening-patch-5.1.4-0.4.15/TSRM/tsrm_virtual_cwd.h 2006-09-05 20:31:06.000000000 +0200
7425@@ -127,6 +127,22 @@
7426
7427 typedef int (*verify_path_func)(const cwd_state *);
7428
7429+#ifndef HAVE_STRLCPY
7430+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
7431+#undef strlcpy
7432+#define strlcpy php_strlcpy
7433+#endif
7434+
7435+#ifndef HAVE_STRLCAT
7436+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
7437+#undef strlcat
7438+#define strlcat php_strlcat
7439+#endif
7440+
7441+
7442+#if HARDENING_PATCH
7443+CWD_API char *php_realpath(const char *path, char *resolved);
7444+#endif
7445 CWD_API void virtual_cwd_startup(void);
7446 CWD_API void virtual_cwd_shutdown(void);
7447 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
7448@@ -199,6 +215,7 @@
7449 long realpath_cache_size_limit;
7450 long realpath_cache_ttl;
7451 realpath_cache_bucket *realpath_cache[1024];
7452+ int realpath_cache_disable;
7453 } virtual_cwd_globals;
7454
7455 #ifdef ZTS
7456diff -Nura php-5.1.4/Zend/zend_alloc.c hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c
7457--- php-5.1.4/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100
7458+++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.c 2006-09-05 20:31:06.000000000 +0200
7459@@ -64,6 +64,11 @@
7460 # define END_MAGIC_SIZE 0
7461 #endif
7462
7463+#if HARDENING_PATCH_MM_PROTECT
7464+# define CANARY_SIZE sizeof(unsigned int)
7465+#else
7466+# define CANARY_SIZE 0
7467+#endif
7468
7469 # if MEMORY_LIMIT
7470 # if ZEND_DEBUG
7471@@ -72,7 +77,15 @@
7472 #define CHECK_MEMORY_LIMIT(s, rs) _CHECK_MEMORY_LIMIT(s, rs, NULL, 0)
7473 # endif
7474
7475-#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { AG(allocated_memory) += rs;\
7476+#define _CHECK_MEMORY_LIMIT(s, rs, file, lineno) { if ((ssize_t)(rs) > (ssize_t)(INT_MAX - AG(allocated_memory))) { \
7477+ if (file) { \
7478+ fprintf(stderr, "Integer overflow in memory_limit check detected at %s:%d\n", file, lineno); \
7479+ } else { \
7480+ fprintf(stderr, "Integer overflow in memory_limit check detected\n"); \
7481+ } \
7482+ exit(1); \
7483+ } \
7484+ AG(allocated_memory) += rs;\
7485 if (AG(memory_limit)<AG(allocated_memory)) {\
7486 int php_mem_limit = AG(memory_limit); \
7487 AG(allocated_memory) -= rs; \
7488@@ -105,9 +118,17 @@
7489 if (p==AG(head)) { \
7490 AG(head) = p->pNext; \
7491 } else { \
7492+ if (p != p->pLast->pNext) { \
7493+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
7494+ exit(1); \
7495+ } \
7496 p->pLast->pNext = p->pNext; \
7497 } \
7498 if (p->pNext) { \
7499+ if (p != p->pNext->pLast) { \
7500+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
7501+ exit(1); \
7502+ } \
7503 p->pNext->pLast = p->pLast; \
7504 }
7505 #else
7506@@ -127,7 +148,7 @@
7507 #endif
7508
7509 #define DECLARE_CACHE_VARS() \
7510- unsigned int real_size; \
7511+ size_t real_size; \
7512 unsigned int cache_index
7513
7514 #define REAL_SIZE(size) ((size+7) & ~0x7)
7515@@ -142,12 +163,22 @@
7516
7517 ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
7518 {
7519- zend_mem_header *p;
7520+ zend_mem_header *p = NULL;
7521 DECLARE_CACHE_VARS();
7522 TSRMLS_FETCH();
7523
7524+#if HARDENING_PATCH_MM_PROTECT
7525+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
7526+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
7527+ exit(1);
7528+ }
7529+#endif
7530 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
7531
7532+ if (size > INT_MAX || SIZE < size) {
7533+ goto emalloc_error;
7534+ }
7535+
7536 #if !ZEND_DISABLE_MEMORY_CACHE
7537 if ((CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
7538 p = AG(cache)[CACHE_INDEX][--AG(cache_count)[CACHE_INDEX]];
7539@@ -164,6 +195,10 @@
7540 AG(cache_stats)[CACHE_INDEX][1]++;
7541 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
7542 #endif
7543+#if HARDENING_PATCH_MM_PROTECT
7544+ p->canary = HG(canary_1);
7545+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
7546+#endif
7547 p->size = size;
7548 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
7549 } else {
7550@@ -179,11 +214,13 @@
7551 AG(allocated_memory_peak) = AG(allocated_memory);
7552 }
7553 #endif
7554- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
7555+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
7556 #if !ZEND_DISABLE_MEMORY_CACHE
7557 }
7558 #endif
7559
7560+emalloc_error:
7561+
7562 HANDLE_BLOCK_INTERRUPTIONS();
7563
7564 if (!p) {
7565@@ -210,7 +247,10 @@
7566 # endif
7567 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
7568 #endif
7569-
7570+#if HARDENING_PATCH_MM_PROTECT
7571+ p->canary = HG(canary_1);
7572+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
7573+#endif
7574 HANDLE_UNBLOCK_INTERRUPTIONS();
7575 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
7576 }
7577@@ -238,6 +278,10 @@
7578 }
7579 }
7580
7581+
7582+#if HARDENING_PATCH
7583+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
7584+#endif
7585 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
7586 return 0;
7587 }
7588@@ -270,9 +314,25 @@
7589
7590 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
7591 {
7592+#if HARDENING_PATCH_MM_PROTECT
7593+ unsigned int canary_2;
7594+#endif
7595 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
7596 DECLARE_CACHE_VARS();
7597 TSRMLS_FETCH();
7598+
7599+#if HARDENING_PATCH_MM_PROTECT
7600+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
7601+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
7602+ if (canary_2 != HG(canary_2)) {
7603+efree_canary_mismatch:
7604+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
7605+ exit(1);
7606+ }
7607+ /* to catch double efree()s */
7608+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
7609+ p->canary = 0;
7610+#endif
7611
7612 #if defined(ZTS) && TSRM_DEBUG
7613 if (p->thread_id != tsrm_thread_id()) {
7614@@ -313,23 +373,35 @@
7615
7616 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
7617 {
7618- void *p;
7619- int final_size = size*nmemb;
7620+ char *p;
7621+ size_t _size = nmemb * size;
7622+
7623+ if (nmemb && (_size/nmemb!=size)) {
7624+#if HARDENING_PATCH
7625+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
7626+#endif
7627+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
7628+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
7629+ kill(getpid(), SIGSEGV);
7630+#else
7631+ exit(1);
7632+#endif
7633+ }
7634
7635- HANDLE_BLOCK_INTERRUPTIONS();
7636- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
7637- if (!p) {
7638- HANDLE_UNBLOCK_INTERRUPTIONS();
7639- return (void *) p;
7640+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
7641+ if (p) {
7642+ memset(p, 0, _size);
7643 }
7644- memset(p, 0, final_size);
7645- HANDLE_UNBLOCK_INTERRUPTIONS();
7646- return p;
7647+
7648+ return ((void *)p);
7649 }
7650
7651
7652 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
7653 {
7654+#if HARDENING_PATCH_MM_PROTECT
7655+ unsigned int canary_2;
7656+#endif
7657 zend_mem_header *p;
7658 zend_mem_header *orig;
7659 DECLARE_CACHE_VARS();
7660@@ -341,6 +413,16 @@
7661
7662 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
7663
7664+#if HARDENING_PATCH_MM_PROTECT
7665+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
7666+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
7667+ if (canary_2 != HG(canary_2)) {
7668+erealloc_canary_mismatch:
7669+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
7670+ exit(1);
7671+ }
7672+#endif
7673+
7674 #if defined(ZTS) && TSRM_DEBUG
7675 if (p->thread_id != tsrm_thread_id()) {
7676 void *new_p;
7677@@ -357,6 +439,13 @@
7678 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
7679
7680 HANDLE_BLOCK_INTERRUPTIONS();
7681+
7682+ if (size > INT_MAX || SIZE < size) {
7683+ REMOVE_POINTER_FROM_LIST(p);
7684+ p = NULL;
7685+ goto erealloc_error;
7686+ }
7687+
7688 #if MEMORY_LIMIT
7689 CHECK_MEMORY_LIMIT(size - p->size, SIZE - REAL_SIZE(p->size));
7690 if (AG(allocated_memory) > AG(allocated_memory_peak)) {
7691@@ -364,7 +453,8 @@
7692 }
7693 #endif
7694 REMOVE_POINTER_FROM_LIST(p);
7695- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
7696+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
7697+erealloc_error:
7698 if (!p) {
7699 if (!allow_failure) {
7700 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
7701@@ -386,6 +476,9 @@
7702 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
7703 #endif
7704
7705+#if HARDENING_PATCH_MM_PROTECT
7706+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
7707+#endif
7708 p->size = size;
7709
7710 HANDLE_UNBLOCK_INTERRUPTIONS();
7711@@ -460,6 +553,10 @@
7712 {
7713 AG(head) = NULL;
7714
7715+#if HARDENING_PATCH_MM_PROTECT
7716+ HG(canary_1) = zend_canary();
7717+ HG(canary_2) = zend_canary();
7718+#endif
7719 #if MEMORY_LIMIT
7720 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
7721 AG(allocated_memory) = 0;
7722diff -Nura php-5.1.4/Zend/zend_alloc.h hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h
7723--- php-5.1.4/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100
7724+++ hardening-patch-5.1.4-0.4.15/Zend/zend_alloc.h 2006-09-05 20:31:06.000000000 +0200
7725@@ -35,6 +35,9 @@
7726 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
7727
7728 typedef struct _zend_mem_header {
7729+#if HARDENING_PATCH_MM_PROTECT
7730+ unsigned int canary;
7731+#endif
7732 #if ZEND_DEBUG
7733 long magic;
7734 char *filename;
7735diff -Nura php-5.1.4/Zend/zend_API.h hardening-patch-5.1.4-0.4.15/Zend/zend_API.h
7736--- php-5.1.4/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100
7737+++ hardening-patch-5.1.4-0.4.15/Zend/zend_API.h 2006-09-05 20:31:06.000000000 +0200
7738@@ -47,6 +47,7 @@
7739 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
7740
7741 #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 },
7742+#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 },
7743
7744 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
7745 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
7746diff -Nura php-5.1.4/Zend/zend_builtin_functions.c hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c
7747--- php-5.1.4/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200
7748+++ hardening-patch-5.1.4-0.4.15/Zend/zend_builtin_functions.c 2006-09-05 20:31:06.000000000 +0200
7749@@ -53,6 +53,9 @@
7750 static ZEND_FUNCTION(crash);
7751 #endif
7752 #endif
7753+#if HARDENING_PATCH_MM_PROTECT_DEBUG
7754+static ZEND_FUNCTION(heap_overflow);
7755+#endif
7756 static ZEND_FUNCTION(get_included_files);
7757 static ZEND_FUNCTION(is_subclass_of);
7758 static ZEND_FUNCTION(is_a);
7759@@ -113,6 +116,9 @@
7760 ZEND_FE(crash, NULL)
7761 #endif
7762 #endif
7763+#if HARDENING_PATCH_MM_PROTECT_DEBUG
7764+ ZEND_FE(heap_overflow, NULL)
7765+#endif
7766 ZEND_FE(get_included_files, NULL)
7767 ZEND_FALIAS(get_required_files, get_included_files, NULL)
7768 ZEND_FE(is_subclass_of, NULL)
7769@@ -1103,6 +1109,19 @@
7770
7771 #endif /* ZEND_DEBUG */
7772
7773+
7774+#if HARDENING_PATCH_MM_PROTECT_DEBUG
7775+ZEND_FUNCTION(heap_overflow)
7776+{
7777+ char *nowhere = emalloc(10);
7778+
7779+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
7780+
7781+ efree(nowhere);
7782+}
7783+#endif
7784+
7785+
7786 /* {{{ proto array get_included_files(void)
7787 Returns an array with the file names that were include_once()'d */
7788 ZEND_FUNCTION(get_included_files)
7789diff -Nura php-5.1.4/Zend/zend.c hardening-patch-5.1.4-0.4.15/Zend/zend.c
7790--- php-5.1.4/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200
7791+++ hardening-patch-5.1.4-0.4.15/Zend/zend.c 2006-09-05 20:31:06.000000000 +0200
7792@@ -55,6 +55,12 @@
7793 ZEND_API void (*zend_unblock_interruptions)(void);
7794 ZEND_API void (*zend_ticks_function)(int ticks);
7795 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
7796+#if HARDENING_PATCH
7797+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7798+#endif
7799+#if HARDENING_PATCH_INC_PROTECT
7800+ZEND_API int (*zend_is_valid_include)(zval *z);
7801+#endif
7802 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
7803 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
7804
7805@@ -74,9 +80,391 @@
7806 return SUCCESS;
7807 }
7808
7809+#if HARDENING_PATCH
7810+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
7811+{
7812+ if (!new_value) {
7813+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
7814+ } else {
7815+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
7816+ }
7817+ return SUCCESS;
7818+}
7819+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
7820+{
7821+ if (!new_value) {
7822+ EG(hphp_log_syslog_facility) = LOG_USER;
7823+ } else {
7824+ EG(hphp_log_syslog_facility) = atoi(new_value);
7825+ }
7826+ return SUCCESS;
7827+}
7828+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
7829+{
7830+ if (!new_value) {
7831+ EG(hphp_log_syslog_priority) = LOG_ALERT;
7832+ } else {
7833+ EG(hphp_log_syslog_priority) = atoi(new_value);
7834+ }
7835+ return SUCCESS;
7836+}
7837+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
7838+{
7839+ if (!new_value) {
7840+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
7841+ } else {
7842+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
7843+ }
7844+ return SUCCESS;
7845+}
7846+static ZEND_INI_MH(OnUpdateHPHP_log_script)
7847+{
7848+ if (!new_value) {
7849+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
7850+ } else {
7851+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
7852+ }
7853+ return SUCCESS;
7854+}
7855+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
7856+{
7857+ if (EG(hphp_log_scriptname)) {
7858+ pefree(EG(hphp_log_scriptname),1);
7859+ }
7860+ EG(hphp_log_scriptname) = NULL;
7861+ if (new_value) {
7862+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
7863+ }
7864+ return SUCCESS;
7865+}
7866+
7867+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
7868+{
7869+ char *s = NULL, *e, *val;
7870+ unsigned long dummy = 1;
7871+
7872+ if (!new_value) {
7873+include_whitelist_destroy:
7874+ if (HG(include_whitelist)) {
7875+ zend_hash_destroy(HG(include_whitelist));
7876+ pefree(HG(include_whitelist),1);
7877+ }
7878+ HG(include_whitelist) = NULL;
7879+ return SUCCESS;
7880+ }
7881+ if (!(*new_value)) {
7882+ goto include_whitelist_destroy;
7883+ }
7884+
7885+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
7886+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
7887+
7888+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7889+ e = val;
7890+
7891+ while (*e) {
7892+ switch (*e) {
7893+ case ' ':
7894+ case ',':
7895+ if (s) {
7896+ *e = '\0';
7897+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7898+ s = NULL;
7899+ }
7900+ break;
7901+ default:
7902+ if (!s) {
7903+ s = e;
7904+ }
7905+ break;
7906+ }
7907+ e++;
7908+ }
7909+ if (s) {
7910+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7911+ }
7912+ efree(val);
7913+
7914+ return SUCCESS;
7915+}
7916+
7917+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
7918+{
7919+ char *s = NULL, *e, *val;
7920+ unsigned long dummy = 1;
7921+
7922+ if (!new_value) {
7923+include_blacklist_destroy:
7924+ if (HG(include_blacklist)) {
7925+ zend_hash_destroy(HG(include_blacklist));
7926+ pefree(HG(include_blacklist),1);
7927+ }
7928+ HG(include_blacklist) = NULL;
7929+ return SUCCESS;
7930+ }
7931+ if (!(*new_value)) {
7932+ goto include_blacklist_destroy;
7933+ }
7934+
7935+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
7936+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
7937+
7938+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7939+ e = val;
7940+
7941+ while (*e) {
7942+ switch (*e) {
7943+ case ' ':
7944+ case ',':
7945+ if (s) {
7946+ *e = '\0';
7947+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7948+ s = NULL;
7949+ }
7950+ break;
7951+ default:
7952+ if (!s) {
7953+ s = e;
7954+ }
7955+ break;
7956+ }
7957+ e++;
7958+ }
7959+ if (s) {
7960+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7961+ }
7962+ efree(val);
7963+
7964+ return SUCCESS;
7965+}
7966+
7967+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
7968+{
7969+ char *s = NULL, *e, *val;
7970+ unsigned long dummy = 1;
7971+
7972+ if (!new_value) {
7973+eval_whitelist_destroy:
7974+ if (HG(eval_whitelist)) {
7975+ zend_hash_destroy(HG(eval_whitelist));
7976+ pefree(HG(eval_whitelist),1);
7977+ }
7978+ HG(eval_whitelist) = NULL;
7979+ return SUCCESS;
7980+ }
7981+ if (!(*new_value)) {
7982+ goto eval_whitelist_destroy;
7983+ }
7984+
7985+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
7986+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
7987+
7988+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7989+ e = val;
7990+
7991+ while (*e) {
7992+ switch (*e) {
7993+ case ' ':
7994+ case ',':
7995+ if (s) {
7996+ *e = '\0';
7997+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7998+ s = NULL;
7999+ }
8000+ break;
8001+ default:
8002+ if (!s) {
8003+ s = e;
8004+ }
8005+ break;
8006+ }
8007+ e++;
8008+ }
8009+ if (s) {
8010+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8011+ }
8012+ efree(val);
8013+
8014+ return SUCCESS;
8015+}
8016+
8017+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
8018+{
8019+ char *s = NULL, *e, *val;
8020+ unsigned long dummy = 1;
8021+
8022+ if (!new_value) {
8023+eval_blacklist_destroy:
8024+ if (HG(eval_blacklist)) {
8025+ zend_hash_destroy(HG(eval_blacklist));
8026+ pefree(HG(eval_blacklist), 1);
8027+ }
8028+ HG(eval_blacklist) = NULL;
8029+ return SUCCESS;
8030+ }
8031+ if (!(*new_value)) {
8032+ goto eval_blacklist_destroy;
8033+ }
8034+
8035+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
8036+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
8037+
8038+ val = zend_str_tolower_dup(new_value, strlen(new_value));
8039+ e = val;
8040+
8041+ while (*e) {
8042+ switch (*e) {
8043+ case ' ':
8044+ case ',':
8045+ if (s) {
8046+ *e = '\0';
8047+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8048+ s = NULL;
8049+ }
8050+ break;
8051+ default:
8052+ if (!s) {
8053+ s = e;
8054+ }
8055+ break;
8056+ }
8057+ e++;
8058+ }
8059+ if (s) {
8060+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8061+ }
8062+ efree(val);
8063+
8064+
8065+ return SUCCESS;
8066+}
8067+
8068+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
8069+{
8070+ char *s = NULL, *e, *val;
8071+ unsigned long dummy = 1;
8072+
8073+ if (!new_value) {
8074+func_whitelist_destroy:
8075+ if (HG(func_whitelist)) {
8076+ zend_hash_destroy(HG(func_whitelist));
8077+ pefree(HG(func_whitelist),1);
8078+ }
8079+ HG(func_whitelist) = NULL;
8080+ return SUCCESS;
8081+ }
8082+ if (!(*new_value)) {
8083+ goto func_whitelist_destroy;
8084+ }
8085+
8086+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
8087+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
8088+
8089+ val = zend_str_tolower_dup(new_value, strlen(new_value));
8090+ e = val;
8091+
8092+ while (*e) {
8093+ switch (*e) {
8094+ case ' ':
8095+ case ',':
8096+ if (s) {
8097+ *e = '\0';
8098+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8099+ s = NULL;
8100+ }
8101+ break;
8102+ default:
8103+ if (!s) {
8104+ s = e;
8105+ }
8106+ break;
8107+ }
8108+ e++;
8109+ }
8110+ if (s) {
8111+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8112+ }
8113+ efree(val);
8114+
8115+ return SUCCESS;
8116+}
8117+
8118+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
8119+{
8120+ char *s = NULL, *e, *val;
8121+ unsigned long dummy = 1;
8122+
8123+ if (!new_value) {
8124+func_blacklist_destroy:
8125+ if (HG(func_blacklist)) {
8126+ zend_hash_destroy(HG(func_blacklist));
8127+ pefree(HG(func_blacklist),1);
8128+ }
8129+ HG(func_blacklist) = NULL;
8130+ return SUCCESS;
8131+ }
8132+ if (!(*new_value)) {
8133+ goto func_blacklist_destroy;
8134+ }
8135+
8136+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
8137+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
8138+
8139+ val = zend_str_tolower_dup(new_value, strlen(new_value));
8140+ e = val;
8141+
8142+ while (*e) {
8143+ switch (*e) {
8144+ case ' ':
8145+ case ',':
8146+ if (s) {
8147+ *e = '\0';
8148+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8149+ s = NULL;
8150+ }
8151+ break;
8152+ default:
8153+ if (!s) {
8154+ s = e;
8155+ }
8156+ break;
8157+ }
8158+ e++;
8159+ }
8160+ if (s) {
8161+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
8162+ }
8163+ efree(val);
8164+
8165+
8166+ return SUCCESS;
8167+}
8168+
8169+#endif
8170
8171 ZEND_INI_BEGIN()
8172 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
8173+#if HARDENING_PATCH
8174+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
8175+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
8176+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
8177+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
8178+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
8179+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
8180+ 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)
8181+
8182+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
8183+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
8184+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
8185+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
8186+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
8187+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
8188+
8189+ 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)
8190+ 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)
8191+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
8192+ STD_ZEND_INI_ENTRY("hphp.mail.protect", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_mailprotect, hardened_globals_struct, hardened_globals)
8193+#endif
8194 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
8195 #ifdef ZEND_MULTIBYTE
8196 STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
8197@@ -501,9 +889,13 @@
8198 EG(user_error_handler) = NULL;
8199 EG(user_exception_handler) = NULL;
8200 EG(in_execution) = 0;
8201+ EG(in_code_type) = 0;
8202 EG(in_autoload) = NULL;
8203 EG(current_execute_data) = NULL;
8204 EG(current_module) = NULL;
8205+#if HARDENING_PATCH
8206+ EG(hphp_log_scriptname) = NULL;
8207+#endif
8208 }
8209
8210
8211@@ -574,6 +966,14 @@
8212 extern zend_scanner_globals language_scanner_globals;
8213 #endif
8214
8215+ /* Set up Hardening-Patch utility functions first */
8216+#if HARDENING_PATCH
8217+ zend_security_log = utility_functions->security_log_function;
8218+#endif
8219+#if HARDENING_PATCH_INC_PROTECT
8220+ zend_is_valid_include = utility_functions->is_valid_include;
8221+#endif
8222+
8223 #ifdef ZTS
8224 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
8225 #else
8226@@ -777,6 +1177,7 @@
8227 }
8228 CG(unclean_shutdown) = 1;
8229 CG(in_compilation) = EG(in_execution) = 0;
8230+ EG(in_code_type) = 0;
8231 EG(current_execute_data) = NULL;
8232 longjmp(EG(bailout), FAILURE);
8233 }
8234diff -Nura php-5.1.4/Zend/zend_canary.c hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c
8235--- php-5.1.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
8236+++ hardening-patch-5.1.4-0.4.15/Zend/zend_canary.c 2006-09-05 20:31:06.000000000 +0200
8237@@ -0,0 +1,58 @@
8238+/*
8239+ +----------------------------------------------------------------------+
8240+ | Hardening-Patch for PHP |
8241+ +----------------------------------------------------------------------+
8242+ | Copyright (c) 2004-2005 Stefan Esser |
8243+ +----------------------------------------------------------------------+
8244+ | This source file is subject to version 2.02 of the PHP license, |
8245+ | that is bundled with this package in the file LICENSE, and is |
8246+ | available at through the world-wide-web at |
8247+ | http://www.php.net/license/2_02.txt. |
8248+ | If you did not receive a copy of the PHP license and are unable to |
8249+ | obtain it through the world-wide-web, please send a note to |
8250+ | license@php.net so we can mail you a copy immediately. |
8251+ +----------------------------------------------------------------------+
8252+ | Author: Stefan Esser <sesser@hardened-php.net> |
8253+ +----------------------------------------------------------------------+
8254+ */
8255+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
8256+
8257+#include "zend.h"
8258+
8259+#include <stdio.h>
8260+#include <stdlib.h>
8261+
8262+
8263+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
8264+
8265+/* will be replaced later with more compatible method */
8266+ZEND_API unsigned int zend_canary()
8267+{
8268+ time_t t;
8269+ unsigned int canary;
8270+ int fd;
8271+
8272+ fd = open("/dev/urandom", 0);
8273+ if (fd != -1) {
8274+ int r = read(fd, &canary, sizeof(canary));
8275+ close(fd);
8276+ if (r == sizeof(canary)) {
8277+ return (canary);
8278+ }
8279+ }
8280+ /* not good but we never want to do this */
8281+ time(&t);
8282+ canary = *(unsigned int *)&t + getpid() << 16;
8283+ return (canary);
8284+}
8285+#endif
8286+
8287+
8288+/*
8289+ * Local variables:
8290+ * tab-width: 4
8291+ * c-basic-offset: 4
8292+ * End:
8293+ * vim600: sw=4 ts=4 fdm=marker
8294+ * vim<600: sw=4 ts=4
8295+ */
8296diff -Nura php-5.1.4/Zend/zend_compile.c hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c
8297--- php-5.1.4/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200
8298+++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.c 2006-09-05 20:31:06.000000000 +0200
8299@@ -1093,6 +1093,13 @@
8300 op_array.prototype = NULL;
8301
8302 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
8303+#if HARDENING_PATCH
8304+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
8305+ op_array.created_by_eval = 1;
8306+ } else {
8307+ op_array.created_by_eval = 0;
8308+ }
8309+#endif
8310
8311 if (is_method) {
8312 char *short_class_name = CG(active_class_entry)->name;
8313diff -Nura php-5.1.4/Zend/zend_compile.h hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h
8314--- php-5.1.4/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100
8315+++ hardening-patch-5.1.4-0.4.15/Zend/zend_compile.h 2006-09-05 20:31:06.000000000 +0200
8316@@ -217,6 +217,9 @@
8317 zend_uint doc_comment_len;
8318
8319 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
8320+#if HARDENING_PATCH
8321+ zend_bool created_by_eval;
8322+#endif
8323 };
8324
8325
8326@@ -295,6 +298,8 @@
8327 zval ***CVs;
8328 zend_bool original_in_execution;
8329 HashTable *symbol_table;
8330+ zend_uint original_in_code_type;
8331+ zend_uint execute_depth;
8332 struct _zend_execute_data *prev_execute_data;
8333 zval *old_error_reporting;
8334 };
8335@@ -617,6 +622,7 @@
8336 #define ZEND_OVERLOADED_FUNCTION 3
8337 #define ZEND_EVAL_CODE 4
8338 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
8339+#define ZEND_SANDBOX_CODE 6
8340
8341 #define ZEND_INTERNAL_CLASS 1
8342 #define ZEND_USER_CLASS 2
8343diff -Nura php-5.1.4/Zend/zend_constants.c hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c
8344--- php-5.1.4/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100
8345+++ hardening-patch-5.1.4-0.4.15/Zend/zend_constants.c 2006-09-05 20:31:06.000000000 +0200
8346@@ -109,6 +109,74 @@
8347 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
8348
8349 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
8350+#if HARDENING_PATCH
8351+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
8352+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
8353+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
8354+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
8355+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
8356+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
8357+ REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
8358+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
8359+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
8360+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
8361+
8362+ /* error levels */
8363+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
8364+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
8365+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
8366+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
8367+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
8368+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
8369+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
8370+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
8371+ /* facility: type of program logging the message */
8372+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
8373+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
8374+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
8375+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
8376+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
8377+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
8378+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
8379+#ifdef LOG_NEWS
8380+ /* No LOG_NEWS on HP-UX */
8381+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
8382+#endif
8383+#ifdef LOG_UUCP
8384+ /* No LOG_UUCP on HP-UX */
8385+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
8386+#endif
8387+#ifdef LOG_CRON
8388+ /* apparently some systems don't have this one */
8389+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
8390+#endif
8391+#ifdef LOG_AUTHPRIV
8392+ /* AIX doesn't have LOG_AUTHPRIV */
8393+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
8394+#endif
8395+#if !defined(PHP_WIN32) && !defined(NETWARE)
8396+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
8397+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
8398+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
8399+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
8400+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
8401+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
8402+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
8403+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
8404+#endif
8405+ /* options */
8406+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
8407+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
8408+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
8409+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
8410+#ifdef LOG_NOWAIT
8411+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
8412+#endif
8413+#ifdef LOG_PERROR
8414+ /* AIX doesn't have LOG_PERROR */
8415+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
8416+#endif
8417+#endif
8418
8419 /* true/false constants */
8420 {
8421diff -Nura php-5.1.4/Zend/zend_errors.h hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h
8422--- php-5.1.4/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100
8423+++ hardening-patch-5.1.4-0.4.15/Zend/zend_errors.h 2006-09-05 20:31:06.000000000 +0200
8424@@ -38,6 +38,19 @@
8425 #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)
8426 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
8427
8428+#if HARDENING_PATCH
8429+#define S_MEMORY (1<<0L)
8430+#define S_VARS (1<<1L)
8431+#define S_FILES (1<<2L)
8432+#define S_INCLUDE (1<<3L)
8433+#define S_SQL (1<<4L)
8434+#define S_EXECUTOR (1<<5L)
8435+#define S_MAIL (1<<6L)
8436+#define S_MISC (1<<30L)
8437+#define S_INTERNAL (1<<29L)
8438+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MAIL | S_MISC | S_SQL | S_EXECUTOR)
8439+#endif
8440+
8441 #endif /* ZEND_ERRORS_H */
8442
8443 /*
8444diff -Nura php-5.1.4/Zend/zend_execute_API.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c
8445--- php-5.1.4/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200
8446+++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute_API.c 2006-09-05 20:31:06.000000000 +0200
8447@@ -142,6 +142,7 @@
8448 EG(class_table) = CG(class_table);
8449
8450 EG(in_execution) = 0;
8451+ EG(in_code_type) = 0;
8452 EG(in_autoload) = NULL;
8453 EG(autoload_func) = NULL;
8454
8455@@ -784,6 +785,39 @@
8456 if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
8457 EX(function_state).function = NULL;
8458 }
8459+#if HARDENING_PATCH
8460+ else {
8461+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8462+ if (HG(eval_whitelist) != NULL) {
8463+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
8464+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
8465+ efree(function_name_lc);
8466+ zend_bailout();
8467+ }
8468+ } else if (HG(eval_blacklist) != NULL) {
8469+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
8470+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
8471+ efree(function_name_lc);
8472+ zend_bailout();
8473+ }
8474+ }
8475+ }
8476+
8477+ if (HG(func_whitelist) != NULL) {
8478+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
8479+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
8480+ efree(function_name_lc);
8481+ zend_bailout();
8482+ }
8483+ } else if (HG(func_blacklist) != NULL) {
8484+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
8485+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
8486+ efree(function_name_lc);
8487+ zend_bailout();
8488+ }
8489+ }
8490+ }
8491+#endif
8492 efree(function_name_lc);
8493 }
8494
8495@@ -1076,7 +1110,7 @@
8496 return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
8497 }
8498
8499-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
8500+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
8501 {
8502 zval pv;
8503 zend_op_array *new_op_array;
8504@@ -1109,6 +1143,7 @@
8505 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
8506 zend_op **original_opline_ptr = EG(opline_ptr);
8507
8508+ new_op_array->type = type;
8509 EG(return_value_ptr_ptr) = &local_retval_ptr;
8510 EG(active_op_array) = new_op_array;
8511 EG(no_extensions)=1;
8512@@ -1143,6 +1178,12 @@
8513 }
8514
8515
8516+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
8517+{
8518+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
8519+}
8520+
8521+
8522 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
8523 {
8524 int result;
8525diff -Nura php-5.1.4/Zend/zend_execute.c hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c
8526--- php-5.1.4/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100
8527+++ hardening-patch-5.1.4-0.4.15/Zend/zend_execute.c 2006-09-05 20:31:06.000000000 +0200
8528@@ -1351,6 +1351,37 @@
8529 /* OBJ-TBI - doesn't support new object model! */
8530 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
8531 }
8532+#if HARDENING_PATCH
8533+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8534+ if (HG(eval_whitelist) != NULL) {
8535+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8536+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8537+ efree(lcname);
8538+ zend_bailout();
8539+ }
8540+ } else if (HG(eval_blacklist) != NULL) {
8541+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8542+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8543+ efree(lcname);
8544+ zend_bailout();
8545+ }
8546+ }
8547+ }
8548+
8549+ if (HG(func_whitelist) != NULL) {
8550+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8551+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8552+ efree(lcname);
8553+ zend_bailout();
8554+ }
8555+ } else if (HG(func_blacklist) != NULL) {
8556+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8557+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8558+ efree(lcname);
8559+ zend_bailout();
8560+ }
8561+ }
8562+#endif
8563
8564 return 0;
8565 }
8566@@ -1396,6 +1427,7 @@
8567 efree(EX(Ts)); \
8568 } \
8569 EG(in_execution) = EX(original_in_execution); \
8570+ EG(in_code_type) = EX(original_in_code_type); \
8571 EG(current_execute_data) = EX(prev_execute_data); \
8572 ZEND_VM_RETURN()
8573
8574diff -Nura php-5.1.4/Zend/zend_extensions.c hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c
8575--- php-5.1.4/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100
8576+++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.c 2006-09-05 20:31:06.000000000 +0200
8577@@ -55,23 +55,44 @@
8578 return FAILURE;
8579 }
8580
8581+ /* check if module is compiled against Hardening-Patch */
8582+ if (extension_version_info->zend_extension_api_no < 1000000000) {
8583+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
8584+ "The Hardening-Patch version %d is installed.\n\n",
8585+ new_extension->name,
8586+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
8587+ DL_UNLOAD(handle);
8588+ return FAILURE;
8589+ }
8590+
8591+
8592+ /* check if module is compiled against correct Hardening-Patch version */
8593+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
8594+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
8595+ "The Hardening-Patch version %d is installed.\n\n",
8596+ new_extension->name,
8597+ extension_version_info->zend_extension_api_no,
8598+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
8599+ DL_UNLOAD(handle);
8600+ return FAILURE;
8601+ }
8602
8603 /* allow extension to proclaim compatibility with any Zend version */
8604- 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)) {
8605- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
8606+ 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)) {
8607+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
8608 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
8609 "The Zend Engine API version %d which is installed, is outdated.\n\n",
8610 new_extension->name,
8611- extension_version_info->zend_extension_api_no,
8612+ extension_version_info->real_zend_extension_api_no,
8613 ZEND_EXTENSION_API_NO);
8614 DL_UNLOAD(handle);
8615 return FAILURE;
8616- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
8617+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
8618 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
8619 "The Zend Engine API version %d which is installed, is newer.\n"
8620 "Contact %s at %s for a later version of %s.\n\n",
8621 new_extension->name,
8622- extension_version_info->zend_extension_api_no,
8623+ extension_version_info->real_zend_extension_api_no,
8624 ZEND_EXTENSION_API_NO,
8625 new_extension->author,
8626 new_extension->URL,
8627diff -Nura php-5.1.4/Zend/zend_extensions.h hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h
8628--- php-5.1.4/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100
8629+++ hardening-patch-5.1.4-0.4.15/Zend/zend_extensions.h 2006-09-05 20:31:06.000000000 +0200
8630@@ -24,9 +24,11 @@
8631
8632 #include "zend_compile.h"
8633
8634-/* The first number is the engine version and the rest is the date.
8635+/* The first API number is a flag saying that Hardening-Patch is used.
8636+ * The second number is the engine version and the date.
8637 * This way engine 2 API no. is always greater than engine 1 API no..
8638 */
8639+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106
8640 #define ZEND_EXTENSION_API_NO 220051025
8641
8642 typedef struct _zend_extension_version_info {
8643@@ -34,6 +36,7 @@
8644 char *required_zend_version;
8645 unsigned char thread_safe;
8646 unsigned char debug;
8647+ int real_zend_extension_api_no;
8648 } zend_extension_version_info;
8649
8650
8651@@ -101,7 +104,7 @@
8652
8653
8654 #define ZEND_EXTENSION() \
8655- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
8656+ 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 }
8657
8658 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
8659 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
8660diff -Nura php-5.1.4/Zend/zend_globals.h hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h
8661--- php-5.1.4/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100
8662+++ hardening-patch-5.1.4-0.4.15/Zend/zend_globals.h 2006-09-05 20:31:06.000000000 +0200
8663@@ -180,6 +180,16 @@
8664
8665 int error_reporting;
8666 int orig_error_reporting;
8667+#if HARDENING_PATCH
8668+ int hphp_log_syslog;
8669+ int hphp_log_syslog_facility;
8670+ int hphp_log_syslog_priority;
8671+ int hphp_log_sapi;
8672+ int hphp_log_script;
8673+ char *hphp_log_scriptname;
8674+ zend_bool hphp_log_use_x_forwarded_for;
8675+ long hphp_executor_max_depth;
8676+#endif
8677 int exit_status;
8678
8679 zend_op_array *active_op_array;
8680@@ -197,6 +207,7 @@
8681 int ticks_count;
8682
8683 zend_bool in_execution;
8684+ zend_uint in_code_type;
8685 HashTable *in_autoload;
8686 zend_function *autoload_func;
8687 zend_bool bailout_set;
8688diff -Nura php-5.1.4/Zend/zend.h hardening-patch-5.1.4-0.4.15/Zend/zend.h
8689--- php-5.1.4/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200
8690+++ hardening-patch-5.1.4-0.4.15/Zend/zend.h 2006-09-05 20:31:06.000000000 +0200
8691@@ -297,6 +297,7 @@
8692 /* Variable information */
8693 zvalue_value value; /* value */
8694 zend_uint refcount;
8695+ zend_ushort flags;
8696 zend_uchar type; /* active type */
8697 zend_uchar is_ref;
8698 };
8699@@ -382,6 +383,12 @@
8700 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
8701 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
8702 char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
8703+#if HARDENING_PATCH
8704+ void (*security_log_function)(int loglevel, char *fmt, ...);
8705+#endif
8706+#if HARDENING_PATCH_INC_PROTECT
8707+ int (*is_valid_include)(zval *z);
8708+#endif
8709 } zend_utility_functions;
8710
8711
8712@@ -519,7 +526,16 @@
8713 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
8714 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
8715 extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
8716+#if HARDENING_PATCH
8717+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
8718+#endif
8719+#if HARDENING_PATCH_INC_PROTECT
8720+extern ZEND_API int (*zend_is_valid_include)(zval *z);
8721+#endif
8722
8723+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
8724+ZEND_API unsigned int zend_canary(void);
8725+#endif
8726
8727 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
8728
8729@@ -644,6 +660,11 @@
8730
8731 #include "zend_variables.h"
8732
8733+#if HARDENING_PATCH
8734+#include "hardened_globals.h"
8735+#include "php_syslog.h"
8736+#endif
8737+
8738 #endif /* ZEND_H */
8739
8740 /*
8741diff -Nura php-5.1.4/Zend/zend_hash.c hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c
8742--- php-5.1.4/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200
8743+++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.c 2006-09-05 20:31:06.000000000 +0200
8744@@ -21,6 +21,18 @@
8745
8746 #include "zend.h"
8747
8748+#if HARDENING_PATCH_HASH_PROTECT
8749+ unsigned int zend_hash_canary = 0x1234567;
8750+ zend_bool zend_hash_canary_inited = 0;
8751+#endif
8752+
8753+#define CHECK_HASH_CANARY(hash) \
8754+ if (zend_hash_canary != (hash)->canary) { \
8755+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
8756+ exit(1); \
8757+ }
8758+
8759+
8760 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
8761 (element)->pNext = (list_head); \
8762 (element)->pLast = NULL; \
8763@@ -138,6 +150,9 @@
8764 {
8765 uint i = 3;
8766 Bucket **tmp;
8767+#if HARDENING_PATCH_HASH_PROTECT
8768+ TSRMLS_FETCH();
8769+#endif
8770
8771 SET_INCONSISTENT(HT_OK);
8772
8773@@ -147,6 +162,13 @@
8774
8775 ht->nTableSize = 1 << i;
8776 ht->nTableMask = ht->nTableSize - 1;
8777+#if HARDENING_PATCH_HASH_PROTECT
8778+ if (zend_hash_canary_inited==0) {
8779+ zend_hash_canary = zend_canary();
8780+ zend_hash_canary_inited = 1;
8781+ }
8782+ ht->canary = zend_hash_canary;
8783+#endif
8784 ht->pDestructor = pDestructor;
8785 ht->arBuckets = NULL;
8786 ht->pListHead = NULL;
8787@@ -226,6 +248,9 @@
8788 }
8789 #endif
8790 if (ht->pDestructor) {
8791+#if HARDENING_PATCH_HASH_PROTECT
8792+ CHECK_HASH_CANARY(ht);
8793+#endif
8794 ht->pDestructor(p->pData);
8795 }
8796 UPDATE_DATA(ht, p, pData, nDataSize);
8797@@ -291,6 +316,9 @@
8798 }
8799 #endif
8800 if (ht->pDestructor) {
8801+#if HARDENING_PATCH_HASH_PROTECT
8802+ CHECK_HASH_CANARY(ht);
8803+#endif
8804 ht->pDestructor(p->pData);
8805 }
8806 UPDATE_DATA(ht, p, pData, nDataSize);
8807@@ -366,6 +394,9 @@
8808 }
8809 #endif
8810 if (ht->pDestructor) {
8811+#if HARDENING_PATCH_HASH_PROTECT
8812+ CHECK_HASH_CANARY(ht);
8813+#endif
8814 ht->pDestructor(p->pData);
8815 }
8816 UPDATE_DATA(ht, p, pData, nDataSize);
8817@@ -414,7 +445,7 @@
8818 IS_CONSISTENT(ht);
8819
8820 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
8821- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
8822+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
8823 if (t) {
8824 HANDLE_BLOCK_INTERRUPTIONS();
8825 ht->arBuckets = t;
8826@@ -424,6 +455,7 @@
8827 HANDLE_UNBLOCK_INTERRUPTIONS();
8828 return SUCCESS;
8829 }
8830+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
8831 return FAILURE;
8832 }
8833 return SUCCESS;
8834@@ -489,6 +521,9 @@
8835 ht->pInternalPointer = p->pListNext;
8836 }
8837 if (ht->pDestructor) {
8838+#if HARDENING_PATCH_HASH_PROTECT
8839+ CHECK_HASH_CANARY(ht);
8840+#endif
8841 ht->pDestructor(p->pData);
8842 }
8843 if (p->pData != &p->pDataPtr) {
8844@@ -513,6 +548,11 @@
8845
8846 SET_INCONSISTENT(HT_IS_DESTROYING);
8847
8848+#if HARDENING_PATCH_HASH_PROTECT
8849+ if (ht->pDestructor) {
8850+ CHECK_HASH_CANARY(ht);
8851+ }
8852+#endif
8853 p = ht->pListHead;
8854 while (p != NULL) {
8855 q = p;
8856@@ -539,6 +579,11 @@
8857
8858 SET_INCONSISTENT(HT_CLEANING);
8859
8860+#if HARDENING_PATCH_HASH_PROTECT
8861+ if (ht->pDestructor) {
8862+ CHECK_HASH_CANARY(ht);
8863+ }
8864+#endif
8865 p = ht->pListHead;
8866 while (p != NULL) {
8867 q = p;
8868@@ -573,6 +618,9 @@
8869 HANDLE_BLOCK_INTERRUPTIONS();
8870
8871 if (ht->pDestructor) {
8872+#if HARDENING_PATCH_HASH_PROTECT
8873+ CHECK_HASH_CANARY(ht);
8874+#endif
8875 ht->pDestructor(p->pData);
8876 }
8877 if (p->pData != &p->pDataPtr) {
8878diff -Nura php-5.1.4/Zend/zend_hash.h hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h
8879--- php-5.1.4/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100
8880+++ hardening-patch-5.1.4-0.4.15/Zend/zend_hash.h 2006-09-05 20:31:06.000000000 +0200
8881@@ -58,6 +58,9 @@
8882 } Bucket;
8883
8884 typedef struct _hashtable {
8885+#if HARDENING_PATCH_HASH_PROTECT
8886+ unsigned int canary;
8887+#endif
8888 uint nTableSize;
8889 uint nTableMask;
8890 uint nNumOfElements;
8891diff -Nura php-5.1.4/Zend/zend_ini.c hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c
8892--- php-5.1.4/Zend/zend_ini.c 2006-01-05 00:53:04.000000000 +0100
8893+++ hardening-patch-5.1.4-0.4.15/Zend/zend_ini.c 2006-09-07 19:13:18.000000000 +0200
8894@@ -256,7 +256,8 @@
8895 zend_ini_entry *ini_entry;
8896 TSRMLS_FETCH();
8897
8898- if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE) {
8899+ if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry)==FAILURE ||
8900+ (stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
8901 return FAILURE;
8902 }
8903
8904diff -Nura php-5.1.4/Zend/zend_language_scanner.l hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l
8905--- php-5.1.4/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200
8906+++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.l 2006-09-05 20:31:06.000000000 +0200
8907@@ -389,6 +389,13 @@
8908 compilation_successful=0;
8909 } else {
8910 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
8911+#if HARDENING_PATCH
8912+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
8913+ op_array->created_by_eval = 1;
8914+ } else {
8915+ op_array->created_by_eval = 0;
8916+ }
8917+#endif
8918 CG(in_compilation) = 1;
8919 CG(active_op_array) = op_array;
8920 compiler_result = zendparse(TSRMLS_C);
8921diff -Nura php-5.1.4/Zend/zend_language_scanner.c hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c
8922--- php-5.1.4/Zend/zend_language_scanner.c 2006-05-12 16:41:13.000000000 +0200
8923+++ hardening-patch-5.1.4-0.4.15/Zend/zend_language_scanner.c 2006-09-05 20:31:06.000000000 +0200
8924@@ -3075,6 +3075,13 @@
8925 compilation_successful=0;
8926 } else {
8927 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
8928+#if HARDENING_PATCH
8929+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
8930+ op_array->created_by_eval = 1;
8931+ } else {
8932+ op_array->created_by_eval = 0;
8933+ }
8934+#endif
8935 CG(in_compilation) = 1;
8936 CG(active_op_array) = op_array;
8937 compiler_result = zendparse(TSRMLS_C);
8938diff -Nura php-5.1.4/Zend/zend_llist.c hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c
8939--- php-5.1.4/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100
8940+++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.c 2006-09-05 20:31:06.000000000 +0200
8941@@ -22,9 +22,49 @@
8942 #include "zend.h"
8943 #include "zend_llist.h"
8944 #include "zend_qsort.h"
8945+#include "zend_globals.h"
8946+
8947+#if HARDENING_PATCH_LL_PROTECT
8948+ unsigned int zend_llist_canary_1 = 0x1234567;
8949+ unsigned int zend_llist_canary_2 = 0x1553425;
8950+ zend_bool zend_llist_canary_inited = 0;
8951+#endif
8952+
8953+#define CHECK_LIST_CANARY(list) \
8954+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
8955+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
8956+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
8957+ exit(1); \
8958+ }
8959+
8960+#define CHECK_LISTELEMENT_CANARY(elem, list) \
8961+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
8962+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
8963+ exit(1); \
8964+ }
8965+
8966
8967 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
8968 {
8969+#if HARDENING_PATCH_LL_PROTECT
8970+ TSRMLS_FETCH();
8971+
8972+ if (persistent) {
8973+ if (!zend_llist_canary_inited) {
8974+ /* do not change order to ensure thread safety */
8975+ zend_llist_canary_1 = zend_canary();
8976+ zend_llist_canary_2 = zend_canary();
8977+ zend_llist_canary_inited = 1;
8978+ }
8979+ } else
8980+ if (!HG(ll_canary_inited)) {
8981+ HG(canary_3) = zend_canary();
8982+ HG(canary_4) = zend_canary();
8983+ HG(ll_canary_inited) = 1;
8984+ }
8985+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
8986+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
8987+#endif
8988 l->head = NULL;
8989 l->tail = NULL;
8990 l->count = 0;
8991@@ -38,6 +78,11 @@
8992 {
8993 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8994
8995+#if HARDENING_PATCH_LL_PROTECT
8996+ TSRMLS_FETCH();
8997+ CHECK_LIST_CANARY(l)
8998+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8999+#endif
9000 tmp->prev = l->tail;
9001 tmp->next = NULL;
9002 if (l->tail) {
9003@@ -56,6 +101,11 @@
9004 {
9005 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
9006
9007+#if HARDENING_PATCH_LL_PROTECT
9008+ TSRMLS_FETCH();
9009+ CHECK_LIST_CANARY(l)
9010+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
9011+#endif
9012 tmp->next = l->head;
9013 tmp->prev = NULL;
9014 if (l->head) {
9015@@ -93,10 +143,20 @@
9016 zend_llist_element *current=l->head;
9017 zend_llist_element *next;
9018
9019+#if HARDENING_PATCH_LL_PROTECT
9020+ TSRMLS_FETCH();
9021+ CHECK_LIST_CANARY(l)
9022+#endif
9023 while (current) {
9024+#if HARDENING_PATCH_LL_PROTECT
9025+ CHECK_LISTELEMENT_CANARY(current, l)
9026+#endif
9027 next = current->next;
9028 if (compare(current->data, element)) {
9029 DEL_LLIST_ELEMENT(current, l);
9030+#if HARDENING_PATCH_LL_PROTECT
9031+ current->canary = 0;
9032+#endif
9033 break;
9034 }
9035 current = next;
9036@@ -108,7 +168,14 @@
9037 {
9038 zend_llist_element *current=l->head, *next;
9039
9040+#if HARDENING_PATCH_LL_PROTECT
9041+ TSRMLS_FETCH();
9042+ CHECK_LIST_CANARY(l)
9043+#endif
9044 while (current) {
9045+#if HARDENING_PATCH_LL_PROTECT
9046+ CHECK_LISTELEMENT_CANARY(current, l)
9047+#endif
9048 next = current->next;
9049 if (l->dtor) {
9050 l->dtor(current->data);
9051@@ -133,7 +200,14 @@
9052 zend_llist_element *old_tail;
9053 void *data;
9054
9055+#if HARDENING_PATCH_LL_PROTECT
9056+ TSRMLS_FETCH();
9057+ CHECK_LIST_CANARY(l)
9058+#endif
9059 if ((old_tail = l->tail)) {
9060+#if HARDENING_PATCH_LL_PROTECT
9061+ CHECK_LISTELEMENT_CANARY(old_tail, l)
9062+#endif
9063 if (l->tail->prev) {
9064 l->tail->prev->next = NULL;
9065 }
9066@@ -159,9 +233,16 @@
9067 {
9068 zend_llist_element *ptr;
9069
9070+#if HARDENING_PATCH_LL_PROTECT
9071+ TSRMLS_FETCH();
9072+ CHECK_LIST_CANARY(src)
9073+#endif
9074 zend_llist_init(dst, src->size, src->dtor, src->persistent);
9075 ptr = src->head;
9076 while (ptr) {
9077+#if HARDENING_PATCH_LL_PROTECT
9078+ CHECK_LISTELEMENT_CANARY(ptr, src)
9079+#endif
9080 zend_llist_add_element(dst, ptr->data);
9081 ptr = ptr->next;
9082 }
9083@@ -172,11 +253,21 @@
9084 {
9085 zend_llist_element *element, *next;
9086
9087+#if HARDENING_PATCH_LL_PROTECT
9088+ TSRMLS_FETCH();
9089+ CHECK_LIST_CANARY(l)
9090+#endif
9091 element=l->head;
9092 while (element) {
9093+#if HARDENING_PATCH_LL_PROTECT
9094+ CHECK_LISTELEMENT_CANARY(element, l)
9095+#endif
9096 next = element->next;
9097 if (func(element->data)) {
9098 DEL_LLIST_ELEMENT(element, l);
9099+#if HARDENING_PATCH_LL_PROTECT
9100+ element->canary = 0;
9101+#endif
9102 }
9103 element = next;
9104 }
9105@@ -187,7 +278,13 @@
9106 {
9107 zend_llist_element *element;
9108
9109+#if HARDENING_PATCH_LL_PROTECT
9110+ CHECK_LIST_CANARY(l)
9111+#endif
9112 for (element=l->head; element; element=element->next) {
9113+#if HARDENING_PATCH_LL_PROTECT
9114+ CHECK_LISTELEMENT_CANARY(element, l)
9115+#endif
9116 func(element->data TSRMLS_CC);
9117 }
9118 }
9119@@ -199,6 +296,9 @@
9120 zend_llist_element **elements;
9121 zend_llist_element *element, **ptr;
9122
9123+#if HARDENING_PATCH_LL_PROTECT
9124+ CHECK_LIST_CANARY(l)
9125+#endif
9126 if (l->count <= 0) {
9127 return;
9128 }
9129@@ -208,6 +308,9 @@
9130 ptr = &elements[0];
9131
9132 for (element=l->head; element; element=element->next) {
9133+#if HARDENING_PATCH_LL_PROTECT
9134+ CHECK_LISTELEMENT_CANARY(element, l)
9135+#endif
9136 *ptr++ = element;
9137 }
9138
9139@@ -230,7 +333,13 @@
9140 {
9141 zend_llist_element *element;
9142
9143+#if HARDENING_PATCH_LL_PROTECT
9144+ CHECK_LIST_CANARY(l)
9145+#endif
9146 for (element=l->head; element; element=element->next) {
9147+#if HARDENING_PATCH_LL_PROTECT
9148+ CHECK_LISTELEMENT_CANARY(element, l)
9149+#endif
9150 func(element->data, arg TSRMLS_CC);
9151 }
9152 }
9153@@ -241,8 +350,14 @@
9154 zend_llist_element *element;
9155 va_list args;
9156
9157+#if HARDENING_PATCH_LL_PROTECT
9158+ CHECK_LIST_CANARY(l)
9159+#endif
9160 va_start(args, num_args);
9161 for (element=l->head; element; element=element->next) {
9162+#if HARDENING_PATCH_LL_PROTECT
9163+ CHECK_LISTELEMENT_CANARY(element, l)
9164+#endif
9165 func(element->data, num_args, args TSRMLS_CC);
9166 }
9167 va_end(args);
9168@@ -251,6 +366,10 @@
9169
9170 ZEND_API int zend_llist_count(zend_llist *l)
9171 {
9172+#if HARDENING_PATCH_LL_PROTECT
9173+ TSRMLS_FETCH();
9174+ CHECK_LIST_CANARY(l)
9175+#endif
9176 return l->count;
9177 }
9178
9179@@ -259,8 +378,15 @@
9180 {
9181 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
9182
9183+#if HARDENING_PATCH_LL_PROTECT
9184+ TSRMLS_FETCH();
9185+ CHECK_LIST_CANARY(l)
9186+#endif
9187 *current = l->head;
9188 if (*current) {
9189+#if HARDENING_PATCH_LL_PROTECT
9190+ CHECK_LISTELEMENT_CANARY(*current, l)
9191+#endif
9192 return (*current)->data;
9193 } else {
9194 return NULL;
9195@@ -272,8 +398,15 @@
9196 {
9197 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
9198
9199+#if HARDENING_PATCH_LL_PROTECT
9200+ TSRMLS_FETCH();
9201+ CHECK_LIST_CANARY(l)
9202+#endif
9203 *current = l->tail;
9204 if (*current) {
9205+#if HARDENING_PATCH_LL_PROTECT
9206+ CHECK_LISTELEMENT_CANARY(*current, l)
9207+#endif
9208 return (*current)->data;
9209 } else {
9210 return NULL;
9211@@ -285,9 +418,19 @@
9212 {
9213 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
9214
9215+#if HARDENING_PATCH_LL_PROTECT
9216+ TSRMLS_FETCH();
9217+ CHECK_LIST_CANARY(l)
9218+#endif
9219 if (*current) {
9220+#if HARDENING_PATCH_LL_PROTECT
9221+ CHECK_LISTELEMENT_CANARY(*current, l)
9222+#endif
9223 *current = (*current)->next;
9224 if (*current) {
9225+#if HARDENING_PATCH_LL_PROTECT
9226+ CHECK_LISTELEMENT_CANARY(*current, l)
9227+#endif
9228 return (*current)->data;
9229 }
9230 }
9231@@ -299,9 +442,19 @@
9232 {
9233 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
9234
9235+#if HARDENING_PATCH_LL_PROTECT
9236+ TSRMLS_FETCH();
9237+ CHECK_LIST_CANARY(l)
9238+#endif
9239 if (*current) {
9240+#if HARDENING_PATCH_LL_PROTECT
9241+ CHECK_LISTELEMENT_CANARY(*current, l)
9242+#endif
9243 *current = (*current)->prev;
9244 if (*current) {
9245+#if HARDENING_PATCH_LL_PROTECT
9246+ CHECK_LISTELEMENT_CANARY(*current, l)
9247+#endif
9248 return (*current)->data;
9249 }
9250 }
9251diff -Nura php-5.1.4/Zend/zend_llist.h hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h
9252--- php-5.1.4/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100
9253+++ hardening-patch-5.1.4-0.4.15/Zend/zend_llist.h 2006-09-05 20:31:06.000000000 +0200
9254@@ -23,6 +23,9 @@
9255 #define ZEND_LLIST_H
9256
9257 typedef struct _zend_llist_element {
9258+#if HARDENING_PATCH_LL_PROTECT
9259+ unsigned int canary, padding;
9260+#endif
9261 struct _zend_llist_element *next;
9262 struct _zend_llist_element *prev;
9263 char data[1]; /* Needs to always be last in the struct */
9264@@ -35,6 +38,9 @@
9265 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
9266
9267 typedef struct _zend_llist {
9268+#if HARDENING_PATCH_LL_PROTECT
9269+ unsigned int canary_h; /* head */
9270+#endif
9271 zend_llist_element *head;
9272 zend_llist_element *tail;
9273 size_t count;
9274@@ -42,6 +48,9 @@
9275 llist_dtor_func_t dtor;
9276 unsigned char persistent;
9277 zend_llist_element *traverse_ptr;
9278+#if HARDENING_PATCH_LL_PROTECT
9279+ unsigned int canary_t; /* tail */
9280+#endif
9281 } zend_llist;
9282
9283 typedef zend_llist_element* zend_llist_position;
9284diff -Nura php-5.1.4/Zend/zend_modules.h hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h
9285--- php-5.1.4/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200
9286+++ hardening-patch-5.1.4-0.4.15/Zend/zend_modules.h 2006-09-05 20:31:06.000000000 +0200
9287@@ -39,6 +39,7 @@
9288 extern struct _zend_arg_info fifth_arg_force_ref[6];
9289 extern struct _zend_arg_info all_args_by_ref[1];
9290
9291+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106
9292 #define ZEND_MODULE_API_NO 20050922
9293 #ifdef ZTS
9294 #define USING_ZTS 1
9295@@ -46,13 +47,13 @@
9296 #define USING_ZTS 0
9297 #endif
9298
9299-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
9300+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
9301 #define STANDARD_MODULE_HEADER \
9302 STANDARD_MODULE_HEADER_EX, NULL, NULL
9303 #define ZE2_STANDARD_MODULE_HEADER \
9304 STANDARD_MODULE_HEADER_EX, ini_entries, NULL
9305
9306-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
9307+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
9308
9309 #define STANDARD_MODULE_PROPERTIES \
9310 NULL, STANDARD_MODULE_PROPERTIES_EX
9311@@ -87,6 +88,7 @@
9312 unsigned char type;
9313 void *handle;
9314 int module_number;
9315+ unsigned int real_zend_api;
9316 };
9317
9318 #define MODULE_DEP_REQUIRED 1
9319diff -Nura php-5.1.4/Zend/zend_opcode.c hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c
9320--- php-5.1.4/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200
9321+++ hardening-patch-5.1.4-0.4.15/Zend/zend_opcode.c 2006-09-05 20:31:06.000000000 +0200
9322@@ -98,6 +98,9 @@
9323 op_array->uses_this = 0;
9324
9325 op_array->start_op = NULL;
9326+#if HARDENING_PATCH
9327+ op_array->created_by_eval = 0;
9328+#endif
9329
9330 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
9331 }
9332diff -Nura php-5.1.4/Zend/zend_vm_def.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h
9333--- php-5.1.4/Zend/zend_vm_def.h 2006-04-12 13:37:50.000000000 +0200
9334+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_def.h 2006-09-05 20:31:06.000000000 +0200
9335@@ -1769,6 +1769,37 @@
9336 efree(lcname);
9337 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
9338 }
9339+#if HARDENING_PATCH
9340+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9341+ if (HG(eval_whitelist) != NULL) {
9342+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
9343+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
9344+ efree(lcname);
9345+ zend_bailout();
9346+ }
9347+ } else if (HG(eval_blacklist) != NULL) {
9348+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
9349+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
9350+ efree(lcname);
9351+ zend_bailout();
9352+ }
9353+ }
9354+ }
9355+
9356+ if (HG(func_whitelist) != NULL) {
9357+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
9358+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
9359+ efree(lcname);
9360+ zend_bailout();
9361+ }
9362+ } else if (HG(func_blacklist) != NULL) {
9363+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
9364+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
9365+ efree(lcname);
9366+ zend_bailout();
9367+ }
9368+ }
9369+#endif
9370
9371 efree(lcname);
9372 if (OP2_TYPE != IS_CONST) {
9373@@ -1994,6 +2025,34 @@
9374 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
9375 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
9376 }
9377+#if HARDENING_PATCH
9378+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9379+ if (HG(eval_whitelist) != NULL) {
9380+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
9381+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
9382+ zend_bailout();
9383+ }
9384+ } else if (HG(eval_blacklist) != NULL) {
9385+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
9386+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
9387+ zend_bailout();
9388+ }
9389+ }
9390+ }
9391+
9392+ if (HG(func_whitelist) != NULL) {
9393+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
9394+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
9395+ zend_bailout();
9396+ }
9397+ } else if (HG(func_blacklist) != NULL) {
9398+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
9399+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
9400+ zend_bailout();
9401+ }
9402+ }
9403+#endif
9404+
9405 EX(object) = NULL;
9406
9407 FREE_OP1();
9408@@ -2709,7 +2768,12 @@
9409 int dummy = 1;
9410 zend_file_handle file_handle;
9411
9412- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9413+#if HARDENING_PATCH_INC_PROTECT
9414+ if (zend_is_valid_include(inc_filename)
9415+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
9416+#else
9417+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9418+#endif
9419
9420 if (!file_handle.opened_path) {
9421 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
9422@@ -2734,6 +2798,11 @@
9423 break;
9424 case ZEND_INCLUDE:
9425 case ZEND_REQUIRE:
9426+#if HARDENING_PATCH_INC_PROTECT
9427+ if (!zend_is_valid_include(inc_filename)) {
9428+ break;
9429+ }
9430+#endif
9431 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
9432 break;
9433 case ZEND_EVAL: {
9434diff -Nura php-5.1.4/Zend/zend_vm_execute.h hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h
9435--- php-5.1.4/Zend/zend_vm_execute.h 2006-04-12 13:37:50.000000000 +0200
9436+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.h 2006-09-05 20:31:07.000000000 +0200
9437@@ -56,6 +56,16 @@
9438 EX(symbol_table) = EG(active_symbol_table);
9439 EX(prev_execute_data) = EG(current_execute_data);
9440 EG(current_execute_data) = &execute_data;
9441+#if HARDENING_PATCH
9442+ EX(execute_depth) = 0;
9443+
9444+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
9445+ EG(in_code_type) = ZEND_EVAL_CODE;
9446+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
9447+ EG(in_code_type) = ZEND_SANDBOX_CODE;
9448+ op_array->type = ZEND_EVAL_CODE;
9449+ }
9450+#endif
9451
9452 EG(in_execution) = 1;
9453 if (op_array->start_op) {
9454@@ -81,6 +91,18 @@
9455 */
9456 EX(function_state).function_symbol_table = NULL;
9457 #endif
9458+#if HARDENING_PATCH
9459+ if (EX(prev_execute_data) == NULL) {
9460+ EX(execute_depth) = 0;
9461+ } else {
9462+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
9463+ }
9464+
9465+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
9466+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
9467+ zend_bailout();
9468+ }
9469+#endif
9470
9471 while (1) {
9472 #ifdef ZEND_WIN32
9473@@ -724,6 +746,37 @@
9474 efree(lcname);
9475 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
9476 }
9477+#if HARDENING_PATCH
9478+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9479+ if (HG(eval_whitelist) != NULL) {
9480+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
9481+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
9482+ efree(lcname);
9483+ zend_bailout();
9484+ }
9485+ } else if (HG(eval_blacklist) != NULL) {
9486+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
9487+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
9488+ efree(lcname);
9489+ zend_bailout();
9490+ }
9491+ }
9492+ }
9493+
9494+ if (HG(func_whitelist) != NULL) {
9495+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
9496+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
9497+ efree(lcname);
9498+ zend_bailout();
9499+ }
9500+ } else if (HG(func_blacklist) != NULL) {
9501+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
9502+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
9503+ efree(lcname);
9504+ zend_bailout();
9505+ }
9506+ }
9507+#endif
9508
9509 efree(lcname);
9510 if (IS_CONST != IS_CONST) {
9511@@ -925,6 +978,37 @@
9512 efree(lcname);
9513 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
9514 }
9515+#if HARDENING_PATCH
9516+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9517+ if (HG(eval_whitelist) != NULL) {
9518+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
9519+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
9520+ efree(lcname);
9521+ zend_bailout();
9522+ }
9523+ } else if (HG(eval_blacklist) != NULL) {
9524+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
9525+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
9526+ efree(lcname);
9527+ zend_bailout();
9528+ }
9529+ }
9530+ }
9531+
9532+ if (HG(func_whitelist) != NULL) {
9533+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
9534+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
9535+ efree(lcname);
9536+ zend_bailout();
9537+ }
9538+ } else if (HG(func_blacklist) != NULL) {
9539+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
9540+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
9541+ efree(lcname);
9542+ zend_bailout();
9543+ }
9544+ }
9545+#endif
9546
9547 efree(lcname);
9548 if (IS_TMP_VAR != IS_CONST) {
9549@@ -1083,6 +1167,37 @@
9550 efree(lcname);
9551 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
9552 }
9553+#if HARDENING_PATCH
9554+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9555+ if (HG(eval_whitelist) != NULL) {
9556+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
9557+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
9558+ efree(lcname);
9559+ zend_bailout();
9560+ }
9561+ } else if (HG(eval_blacklist) != NULL) {
9562+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
9563+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
9564+ efree(lcname);
9565+ zend_bailout();
9566+ }
9567+ }
9568+ }
9569+
9570+ if (HG(func_whitelist) != NULL) {
9571+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
9572+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
9573+ efree(lcname);
9574+ zend_bailout();
9575+ }
9576+ } else if (HG(func_blacklist) != NULL) {
9577+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
9578+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
9579+ efree(lcname);
9580+ zend_bailout();
9581+ }
9582+ }
9583+#endif
9584
9585 efree(lcname);
9586 if (IS_VAR != IS_CONST) {
9587@@ -1330,6 +1445,37 @@
9588 efree(lcname);
9589 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
9590 }
9591+#if HARDENING_PATCH
9592+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9593+ if (HG(eval_whitelist) != NULL) {
9594+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
9595+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
9596+ efree(lcname);
9597+ zend_bailout();
9598+ }
9599+ } else if (HG(eval_blacklist) != NULL) {
9600+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
9601+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
9602+ efree(lcname);
9603+ zend_bailout();
9604+ }
9605+ }
9606+ }
9607+
9608+ if (HG(func_whitelist) != NULL) {
9609+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
9610+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
9611+ efree(lcname);
9612+ zend_bailout();
9613+ }
9614+ } else if (HG(func_blacklist) != NULL) {
9615+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
9616+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
9617+ efree(lcname);
9618+ zend_bailout();
9619+ }
9620+ }
9621+#endif
9622
9623 efree(lcname);
9624 if (IS_CV != IS_CONST) {
9625@@ -1635,6 +1781,34 @@
9626 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
9627 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
9628 }
9629+#if HARDENING_PATCH
9630+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
9631+ if (HG(eval_whitelist) != NULL) {
9632+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
9633+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
9634+ zend_bailout();
9635+ }
9636+ } else if (HG(eval_blacklist) != NULL) {
9637+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
9638+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
9639+ zend_bailout();
9640+ }
9641+ }
9642+ }
9643+
9644+ if (HG(func_whitelist) != NULL) {
9645+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
9646+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
9647+ zend_bailout();
9648+ }
9649+ } else if (HG(func_blacklist) != NULL) {
9650+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
9651+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
9652+ zend_bailout();
9653+ }
9654+ }
9655+#endif
9656+
9657 EX(object) = NULL;
9658
9659 return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
9660@@ -1914,7 +2088,12 @@
9661 int dummy = 1;
9662 zend_file_handle file_handle;
9663
9664- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9665+#if HARDENING_PATCH_INC_PROTECT
9666+ if (zend_is_valid_include(inc_filename)
9667+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
9668+#else
9669+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9670+#endif
9671
9672 if (!file_handle.opened_path) {
9673 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
9674@@ -1939,6 +2118,11 @@
9675 break;
9676 case ZEND_INCLUDE:
9677 case ZEND_REQUIRE:
9678+#if HARDENING_PATCH_INC_PROTECT
9679+ if (!zend_is_valid_include(inc_filename)) {
9680+ break;
9681+ }
9682+#endif
9683 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
9684 break;
9685 case ZEND_EVAL: {
9686@@ -4345,7 +4529,12 @@
9687 int dummy = 1;
9688 zend_file_handle file_handle;
9689
9690- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9691+#if HARDENING_PATCH_INC_PROTECT
9692+ if (zend_is_valid_include(inc_filename)
9693+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
9694+#else
9695+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9696+#endif
9697
9698 if (!file_handle.opened_path) {
9699 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
9700@@ -4370,6 +4559,11 @@
9701 break;
9702 case ZEND_INCLUDE:
9703 case ZEND_REQUIRE:
9704+#if HARDENING_PATCH_INC_PROTECT
9705+ if (!zend_is_valid_include(inc_filename)) {
9706+ break;
9707+ }
9708+#endif
9709 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
9710 break;
9711 case ZEND_EVAL: {
9712@@ -7358,7 +7552,12 @@
9713 int dummy = 1;
9714 zend_file_handle file_handle;
9715
9716- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9717+#if HARDENING_PATCH_INC_PROTECT
9718+ if (zend_is_valid_include(inc_filename)
9719+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
9720+#else
9721+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9722+#endif
9723
9724 if (!file_handle.opened_path) {
9725 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
9726@@ -7383,6 +7582,11 @@
9727 break;
9728 case ZEND_INCLUDE:
9729 case ZEND_REQUIRE:
9730+#if HARDENING_PATCH_INC_PROTECT
9731+ if (!zend_is_valid_include(inc_filename)) {
9732+ break;
9733+ }
9734+#endif
9735 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
9736 break;
9737 case ZEND_EVAL: {
9738@@ -19470,7 +19674,12 @@
9739 int dummy = 1;
9740 zend_file_handle file_handle;
9741
9742- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9743+#if HARDENING_PATCH_INC_PROTECT
9744+ if (zend_is_valid_include(inc_filename)
9745+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
9746+#else
9747+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
9748+#endif
9749
9750 if (!file_handle.opened_path) {
9751 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
9752@@ -19495,6 +19704,11 @@
9753 break;
9754 case ZEND_INCLUDE:
9755 case ZEND_REQUIRE:
9756+#if HARDENING_PATCH_INC_PROTECT
9757+ if (!zend_is_valid_include(inc_filename)) {
9758+ break;
9759+ }
9760+#endif
9761 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
9762 break;
9763 case ZEND_EVAL: {
9764diff -Nura php-5.1.4/Zend/zend_vm_execute.skl hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl
9765--- php-5.1.4/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100
9766+++ hardening-patch-5.1.4-0.4.15/Zend/zend_vm_execute.skl 2006-09-05 20:31:07.000000000 +0200
9767@@ -27,6 +27,16 @@
9768 EX(symbol_table) = EG(active_symbol_table);
9769 EX(prev_execute_data) = EG(current_execute_data);
9770 EG(current_execute_data) = &execute_data;
9771+#if HARDENING_PATCH
9772+ EX(execute_depth) = 0;
9773+
9774+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
9775+ EG(in_code_type) = ZEND_EVAL_CODE;
9776+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
9777+ EG(in_code_type) = ZEND_SANDBOX_CODE;
9778+ op_array->type = ZEND_EVAL_CODE;
9779+ }
9780+#endif
9781
9782 EG(in_execution) = 1;
9783 if (op_array->start_op) {
9784@@ -52,6 +62,18 @@
9785 */
9786 EX(function_state).function_symbol_table = NULL;
9787 #endif
9788+#if HARDENING_PATCH
9789+ if (EX(prev_execute_data) == NULL) {
9790+ EX(execute_depth) = 0;
9791+ } else {
9792+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
9793+ }
9794+
9795+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
9796+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
9797+ zend_bailout();
9798+ }
9799+#endif
9800
9801 while (1) {
9802 {%ZEND_VM_CONTINUE_LABEL%}