summaryrefslogtreecommitdiff
path: root/0.4.11
diff options
context:
space:
mode:
Diffstat (limited to '0.4.11')
-rw-r--r--0.4.11/hardening-patch-4.4.2-0.4.11.patch8416
-rw-r--r--0.4.11/hardening-patch-5.1.4-0.4.11.patch8220
2 files changed, 16636 insertions, 0 deletions
diff --git a/0.4.11/hardening-patch-4.4.2-0.4.11.patch b/0.4.11/hardening-patch-4.4.2-0.4.11.patch
new file mode 100644
index 0000000..39c41a0
--- /dev/null
+++ b/0.4.11/hardening-patch-4.4.2-0.4.11.patch
@@ -0,0 +1,8416 @@
1diff -Nura php-4.4.2/acinclude.m4 hardening-patch-4.4.2-0.4.11/acinclude.m4
2--- php-4.4.2/acinclude.m4 2005-12-19 23:29:11.000000000 +0100
3+++ hardening-patch-4.4.2-0.4.11/acinclude.m4 2006-05-13 18:01:56.000000000 +0200
4@@ -1186,6 +1186,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.4.2/Changelog.hphp hardening-patch-4.4.2-0.4.11/Changelog.hphp
42--- php-4.4.2/Changelog.hphp 1970-01-01 01:00:00.000000000 +0100
43+++ hardening-patch-4.4.2-0.4.11/Changelog.hphp 2006-05-13 19:11:35.000000000 +0200
44@@ -0,0 +1,21 @@
45+Changelog of the Hardening-Patch
46+--------------------------------
47+
48+0.4.11 - 13. May 2006
49+
50+ PHP5:
51+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache
52+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4
53+
54+ PHP4+5:
55+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories
56+
57+
58+0.4.10 - 11. May 2006
59+
60+ PHP4:
61+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
62+
63+ PHP4+5:
64+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
65+
66diff -Nura php-4.4.2/configure hardening-patch-4.4.2-0.4.11/configure
67--- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100
68+++ hardening-patch-4.4.2-0.4.11/configure 2006-05-13 18:01:56.000000000 +0200
69@@ -402,6 +402,16 @@
70 ac_default_prefix=/usr/local
71 # Any additions from configure.in:
72 ac_help="$ac_help
73+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
74+ac_help="$ac_help
75+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
76+ac_help="$ac_help
77+ --disable-hardening-patch-inc-protect Disable include/require protection."
78+ac_help="$ac_help
79+ --disable-hardening-patch-fmt-protect Disable format string protection."
80+ac_help="$ac_help
81+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
82+ac_help="$ac_help
83
84 SAPI modules:
85 "
86@@ -854,6 +864,8 @@
87 ac_help="$ac_help
88 --disable-tokenizer Disable tokenizer support"
89 ac_help="$ac_help
90+ --disable-varfilter Disable Hardening-Patch's variable filter"
91+ac_help="$ac_help
92 --enable-wddx Enable WDDX support."
93 ac_help="$ac_help
94 --disable-xml Disable XML support using bundled expat lib"
95@@ -2942,6 +2954,157 @@
96
97
98
99+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
100+if test "${enable_hardening_patch_mm_protect+set}" = set; then
101+ enableval="$enable_hardening_patch_mm_protect"
102+
103+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
104+
105+else
106+
107+ DO_HARDENING_PATCH_MM_PROTECT=yes
108+
109+fi
110+
111+
112+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
113+if test "${enable_hardening_patch_ll_protect+set}" = set; then
114+ enableval="$enable_hardening_patch_ll_protect"
115+
116+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
117+
118+else
119+
120+ DO_HARDENING_PATCH_LL_PROTECT=yes
121+
122+fi
123+
124+
125+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
126+if test "${enable_hardening_patch_inc_protect+set}" = set; then
127+ enableval="$enable_hardening_patch_inc_protect"
128+
129+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
130+
131+else
132+
133+ DO_HARDENING_PATCH_INC_PROTECT=yes
134+
135+fi
136+
137+
138+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
139+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
140+ enableval="$enable_hardening_patch_fmt_protect"
141+
142+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
143+
144+else
145+
146+ DO_HARDENING_PATCH_FMT_PROTECT=yes
147+
148+fi
149+
150+
151+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
152+if test "${enable_hardening_patch_hash_protect+set}" = set; then
153+ enableval="$enable_hardening_patch_hash_protect"
154+
155+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
156+
157+else
158+
159+ DO_HARDENING_PATCH_HASH_PROTECT=yes
160+
161+fi
162+
163+
164+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
165+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
166+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
167+
168+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
169+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
170+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
171+
172+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
173+echo "configure:2733: checking whether to protect include/require statements" >&5
174+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
175+
176+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
177+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
178+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
179+
180+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
181+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
182+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
183+
184+
185+cat >> confdefs.h <<\EOF
186+#define HARDENING_PATCH 1
187+EOF
188+
189+
190+
191+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
192+ cat >> confdefs.h <<\EOF
193+#define HARDENING_PATCH_MM_PROTECT 1
194+EOF
195+
196+else
197+ cat >> confdefs.h <<\EOF
198+#define HARDENING_PATCH_MM_PROTECT 0
199+EOF
200+
201+fi
202+
203+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
204+ cat >> confdefs.h <<\EOF
205+#define HARDENING_PATCH_LL_PROTECT 1
206+EOF
207+
208+else
209+ cat >> confdefs.h <<\EOF
210+#define HARDENING_PATCH_LL_PROTECT 0
211+EOF
212+
213+fi
214+
215+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
216+ cat >> confdefs.h <<\EOF
217+#define HARDENING_PATCH_INC_PROTECT 1
218+EOF
219+
220+else
221+ cat >> confdefs.h <<\EOF
222+#define HARDENING_PATCH_INC_PROTECT 0
223+EOF
224+
225+fi
226+
227+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
228+ cat >> confdefs.h <<\EOF
229+#define HARDENING_PATCH_FMT_PROTECT 1
230+EOF
231+
232+else
233+ cat >> confdefs.h <<\EOF
234+#define HARDENING_PATCH_FMT_PROTECT 0
235+EOF
236+
237+fi
238+
239+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
240+ cat >> confdefs.h <<\EOF
241+#define HARDENING_PATCH_HASH_PROTECT 1
242+EOF
243+
244+else
245+ cat >> confdefs.h <<\EOF
246+#define HARDENING_PATCH_HASH_PROTECT 0
247+EOF
248+
249+fi
250
251
252
253@@ -16017,6 +16180,62 @@
254 fi
255
256
257+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
258+echo "configure:14928: checking whether realpath is broken" >&5
259+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
260+ echo $ac_n "(cached) $ac_c" 1>&6
261+else
262+
263+ if test "$cross_compiling" = yes; then
264+
265+ ac_cv_broken_realpath=no
266+
267+else
268+ cat > conftest.$ac_ext <<EOF
269+#line 14939 "configure"
270+#include "confdefs.h"
271+
272+main() {
273+ char buf[4096+1];
274+ buf[0] = 0;
275+ realpath("/etc/hosts/../passwd", buf);
276+ exit(strcmp(buf, "/etc/passwd")==0);
277+}
278+
279+EOF
280+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
281+then
282+
283+ ac_cv_broken_realpath=no
284+
285+else
286+ echo "configure: failed program was:" >&5
287+ cat conftest.$ac_ext >&5
288+ rm -fr conftest*
289+
290+ ac_cv_broken_realpath=yes
291+
292+fi
293+rm -fr conftest*
294+fi
295+
296+
297+fi
298+
299+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
300+ if test "$ac_cv_broken_realpath" = "yes"; then
301+ cat >> confdefs.h <<\EOF
302+#define PHP_BROKEN_REALPATH 1
303+EOF
304+
305+ else
306+ cat >> confdefs.h <<\EOF
307+#define PHP_BROKEN_REALPATH 0
308+EOF
309+
310+ fi
311+
312+
313 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
314 echo "configure:16022: checking for declared timezone" >&5
315 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
316@@ -86718,7 +86937,7 @@
317 if test "$ac_cv_crypt_blowfish" = "yes"; then
318 ac_result=1
319 else
320- ac_result=0
321+ ac_result=1
322 fi
323 cat >> confdefs.h <<EOF
324 #define PHP_BLOWFISH_CRYPT $ac_result
325@@ -87420,7 +87639,7 @@
326 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
327 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
328 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
329- var_unserializer.c ftok.c aggregation.c sha1.c ; do
330+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
331
332 IFS=.
333 set $ac_src
334@@ -87475,7 +87694,7 @@
335 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
336 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
337 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
338- var_unserializer.c ftok.c aggregation.c sha1.c ; do
339+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
340
341 IFS=.
342 set $ac_src
343@@ -87601,7 +87820,7 @@
344 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
345 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
346 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
347- var_unserializer.c ftok.c aggregation.c sha1.c ; do
348+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
349
350 IFS=.
351 set $ac_src
352@@ -87653,7 +87872,7 @@
353 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
354 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
355 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
356- var_unserializer.c ftok.c aggregation.c sha1.c ; do
357+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
358
359 IFS=.
360 set $ac_src
361@@ -91124,6 +91343,265 @@
362 fi
363
364
365+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
366+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
367+# Check whether --enable-varfilter or --disable-varfilter was given.
368+if test "${enable_varfilter+set}" = set; then
369+ enableval="$enable_varfilter"
370+ PHP_VARFILTER=$enableval
371+else
372+
373+ PHP_VARFILTER=yes
374+
375+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
376+ PHP_VARFILTER=$PHP_ENABLE_ALL
377+ fi
378+
379+fi
380+
381+
382+
383+ext_output="yes, shared"
384+ext_shared=yes
385+case $PHP_VARFILTER in
386+shared,*)
387+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
388+ ;;
389+shared)
390+ PHP_VARFILTER=yes
391+ ;;
392+no)
393+ ext_output=no
394+ ext_shared=no
395+ ;;
396+*)
397+ ext_output=yes
398+ ext_shared=no
399+ ;;
400+esac
401+
402+
403+
404+echo "$ac_t""$ext_output" 1>&6
405+
406+
407+
408+
409+if test "$PHP_VARFILTER" != "no"; then
410+ cat >> confdefs.h <<\EOF
411+#define HAVE_VARFILTER 1
412+EOF
413+
414+
415+ ext_builddir=ext/varfilter
416+ ext_srcdir=$abs_srcdir/ext/varfilter
417+
418+ ac_extra=
419+
420+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
421+
422+
423+
424+ case ext/varfilter in
425+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
426+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
427+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
428+ esac
429+
430+
431+
432+ b_c_pre=$php_c_pre
433+ b_cxx_pre=$php_cxx_pre
434+ b_c_meta=$php_c_meta
435+ b_cxx_meta=$php_cxx_meta
436+ b_c_post=$php_c_post
437+ b_cxx_post=$php_cxx_post
438+ b_lo=$php_lo
439+
440+
441+ old_IFS=$IFS
442+ for ac_src in varfilter.c; do
443+
444+ IFS=.
445+ set $ac_src
446+ ac_obj=$1
447+ IFS=$old_IFS
448+
449+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
450+
451+ case $ac_src in
452+ *.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" ;;
453+ *.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" ;;
454+ esac
455+
456+ cat >>Makefile.objects<<EOF
457+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
458+ $ac_comp
459+EOF
460+ done
461+
462+
463+ EXT_STATIC="$EXT_STATIC varfilter"
464+ if test "$ext_shared" != "nocli"; then
465+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
466+ fi
467+ else
468+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
469+
470+ case ext/varfilter in
471+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
472+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
473+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
474+ esac
475+
476+
477+
478+ b_c_pre=$shared_c_pre
479+ b_cxx_pre=$shared_cxx_pre
480+ b_c_meta=$shared_c_meta
481+ b_cxx_meta=$shared_cxx_meta
482+ b_c_post=$shared_c_post
483+ b_cxx_post=$shared_cxx_post
484+ b_lo=$shared_lo
485+
486+
487+ old_IFS=$IFS
488+ for ac_src in varfilter.c; do
489+
490+ IFS=.
491+ set $ac_src
492+ ac_obj=$1
493+ IFS=$old_IFS
494+
495+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
496+
497+ case $ac_src in
498+ *.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" ;;
499+ *.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" ;;
500+ esac
501+
502+ cat >>Makefile.objects<<EOF
503+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
504+ $ac_comp
505+EOF
506+ done
507+
508+
509+ install_modules="install-modules"
510+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
511+
512+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
513+
514+ cat >>Makefile.objects<<EOF
515+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
516+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
517+
518+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
519+ \$(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)
520+
521+EOF
522+
523+ cat >> confdefs.h <<EOF
524+#define COMPILE_DL_VARFILTER 1
525+EOF
526+
527+ fi
528+ fi
529+
530+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
531+ if test "$PHP_SAPI" = "cgi"; then
532+
533+
534+ case ext/varfilter in
535+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
536+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
537+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
538+ esac
539+
540+
541+
542+ b_c_pre=$php_c_pre
543+ b_cxx_pre=$php_cxx_pre
544+ b_c_meta=$php_c_meta
545+ b_cxx_meta=$php_cxx_meta
546+ b_c_post=$php_c_post
547+ b_cxx_post=$php_cxx_post
548+ b_lo=$php_lo
549+
550+
551+ old_IFS=$IFS
552+ for ac_src in varfilter.c; do
553+
554+ IFS=.
555+ set $ac_src
556+ ac_obj=$1
557+ IFS=$old_IFS
558+
559+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
560+
561+ case $ac_src in
562+ *.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" ;;
563+ *.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" ;;
564+ esac
565+
566+ cat >>Makefile.objects<<EOF
567+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
568+ $ac_comp
569+EOF
570+ done
571+
572+
573+ EXT_STATIC="$EXT_STATIC varfilter"
574+ else
575+
576+
577+ case ext/varfilter in
578+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
579+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
580+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
581+ esac
582+
583+
584+
585+ b_c_pre=$php_c_pre
586+ b_cxx_pre=$php_cxx_pre
587+ b_c_meta=$php_c_meta
588+ b_cxx_meta=$php_cxx_meta
589+ b_c_post=$php_c_post
590+ b_cxx_post=$php_cxx_post
591+ b_lo=$php_lo
592+
593+
594+ old_IFS=$IFS
595+ for ac_src in varfilter.c; do
596+
597+ IFS=.
598+ set $ac_src
599+ ac_obj=$1
600+ IFS=$old_IFS
601+
602+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
603+
604+ case $ac_src in
605+ *.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" ;;
606+ *.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" ;;
607+ esac
608+
609+ cat >>Makefile.objects<<EOF
610+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
611+ $ac_comp
612+EOF
613+ done
614+
615+
616+ fi
617+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
618+ fi
619+
620+ BUILD_DIR="$BUILD_DIR $ext_builddir"
621+
622+
623+fi
624
625
626 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
627@@ -104088,7 +104566,7 @@
628 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
629 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
630 streams.c network.c php_open_temporary_file.c php_logos.c \
631- output.c memory_streams.c user_streams.c; do
632+ output.c memory_streams.c user_streams.c hardening_patch.c; do
633
634 IFS=.
635 set $ac_src
636@@ -104273,7 +104751,7 @@
637 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
638 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
639 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
640- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
641+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
642
643 IFS=.
644 set $ac_src
645diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.11/configure.in
646--- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100
647+++ hardening-patch-4.4.2-0.4.11/configure.in 2006-05-13 18:01:56.000000000 +0200
648@@ -247,7 +247,7 @@
649 sinclude(Zend/acinclude.m4)
650 sinclude(Zend/Zend.m4)
651 sinclude(TSRM/tsrm.m4)
652-
653+sinclude(main/hardening_patch.m4)
654
655
656 divert(2)
657@@ -621,6 +621,7 @@
658 AC_FUNC_ALLOCA
659 dnl PHP_AC_BROKEN_SPRINTF
660 dnl PHP_AC_BROKEN_SNPRINTF
661+PHP_AC_BROKEN_REALPATH
662 PHP_DECLARED_TIMEZONE
663 PHP_TIME_R_TYPE
664 PHP_READDIR_R_TYPE
665@@ -1260,7 +1261,7 @@
666 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
667 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
668 streams.c network.c php_open_temporary_file.c php_logos.c \
669- output.c memory_streams.c user_streams.c)
670+ output.c memory_streams.c user_streams.c hardening_patch.c)
671 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
672 case $host_alias in
673 *netware*)
674@@ -1281,7 +1282,7 @@
675 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
676 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
677 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
678- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
679+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
680
681 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
682 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
683diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.11/ext/curl/curl.c
684--- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100
685+++ hardening-patch-4.4.2-0.4.11/ext/curl/curl.c 2006-05-13 18:01:56.000000000 +0200
686@@ -111,7 +111,7 @@
687
688 #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
689 if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
690- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
691+ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \
692 { \
693 php_url *tmp_url; \
694 \
695diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.11/ext/fbsql/php_fbsql.c
696--- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100
697+++ hardening-patch-4.4.2-0.4.11/ext/fbsql/php_fbsql.c 2006-05-13 18:01:56.000000000 +0200
698@@ -1797,8 +1797,24 @@
699 }
700 else if (fbcmdErrorsFound(md))
701 {
702+#if HARDENING_PATCH
703+ char* query_copy;
704+ int i;
705+#endif
706 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
707 char* emg = fbcemdAllErrorMessages(emd);
708+#if HARDENING_PATCH
709+ query_copy=estrdup(query_copy);
710+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
711+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
712+ efree(query_copy);
713+ if (HG(hphp_sql_bailout_on_error)) {
714+ free(emg);
715+ fbcemdRelease(emd);
716+ result = 0;
717+ zend_bailout();
718+ }
719+#endif
720 if (FB_SQL_G(generateWarnings))
721 {
722 if (emg)
723diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.11/ext/mbstring/mbstring.c
724--- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100
725+++ hardening-patch-4.4.2-0.4.11/ext/mbstring/mbstring.c 2006-05-13 18:01:56.000000000 +0200
726@@ -1488,6 +1488,7 @@
727 char *strtok_buf = NULL, **val_list;
728 zval *array_ptr = (zval *) arg;
729 int n, num, val_len, *len_list;
730+ unsigned int new_val_len;
731 enum mbfl_no_encoding from_encoding;
732 mbfl_string string, resvar, resval;
733 mbfl_encoding_detector *identd = NULL;
734@@ -1610,8 +1611,14 @@
735 val_len = len_list[n];
736 }
737 n++;
738- /* add variable to symbol table */
739- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
740+ /* we need val to be emalloc()ed */
741+ val = estrndup(val, val_len);
742+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
743+ /* add variable to symbol table */
744+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
745+ }
746+ efree(val);
747+
748 if (convd != NULL){
749 mbfl_string_clear(&resvar);
750 mbfl_string_clear(&resval);
751diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.11/ext/mysql/php_mysql.c
752--- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100
753+++ hardening-patch-4.4.2-0.4.11/ext/mysql/php_mysql.c 2006-05-13 18:01:56.000000000 +0200
754@@ -1218,6 +1218,8 @@
755 {
756 php_mysql_conn *mysql;
757 MYSQL_RES *mysql_result;
758+ char *copy_query;
759+ int i;
760
761 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
762
763@@ -1268,6 +1270,13 @@
764 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
765 }
766 }
767+ copy_query = estrdup(Z_STRVAL_PP(query));
768+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
769+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
770+ efree(copy_query);
771+ if (HG(hphp_sql_bailout_on_error)) {
772+ zend_bailout();
773+ }
774 RETURN_FALSE;
775 }
776 #else
777@@ -1275,12 +1284,20 @@
778 /* check possible error */
779 if (MySG(trace_mode)){
780 if (mysql_errno(&mysql->conn)){
781- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
782+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
783 }
784 }
785+ copy_query = estrdup(Z_STRVAL_PP(query));
786+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
787+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
788+ efree(copy_query);
789+ if (HG(hphp_sql_bailout_on_error)) {
790+ zend_bailout();
791+ }
792 RETURN_FALSE;
793 }
794 #endif
795+
796 if(use_store == MYSQL_USE_RESULT) {
797 mysql_result=mysql_use_result(&mysql->conn);
798 } else {
799diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.11/ext/pgsql/pgsql.c
800--- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100
801+++ hardening-patch-4.4.2-0.4.11/ext/pgsql/pgsql.c 2006-05-13 18:01:56.000000000 +0200
802@@ -1001,10 +1001,28 @@
803 case PGRES_EMPTY_QUERY:
804 case PGRES_BAD_RESPONSE:
805 case PGRES_NONFATAL_ERROR:
806- case PGRES_FATAL_ERROR:
807- PHP_PQ_ERROR("Query failed: %s", pgsql);
808- PQclear(pgsql_result);
809- RETURN_FALSE;
810+ case PGRES_FATAL_ERROR:
811+ {
812+#if HARDENING_PATCH
813+ int i;
814+ char *query_copy;
815+#endif
816+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
817+ PQclear(pgsql_result);
818+#if HARDENING_PATCH
819+ query_copy = estrdup(Z_STRVAL_PP(query));
820+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
821+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
822+ efree(query_copy);
823+ if (HG(hphp_sql_bailout_on_error)) {
824+ efree(msgbuf);
825+ zend_bailout();
826+ }
827+#endif
828+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
829+ efree(msgbuf);
830+ RETURN_FALSE;
831+ }
832 break;
833 case PGRES_COMMAND_OK: /* successful command that did not return rows */
834 default:
835diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.11/ext/session/mod_files.c
836--- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100
837+++ hardening-patch-4.4.2-0.4.11/ext/session/mod_files.c 2006-05-13 18:01:56.000000000 +0200
838@@ -16,7 +16,7 @@
839 +----------------------------------------------------------------------+
840 */
841
842-/* $Id: mod_files.c,v 1.83.2.9.2.2 2006/01/01 13:46:56 sniper Exp $ */
843+/* $Id: mod_files.c,v 1.83.2.9.2.3 2006/04/17 23:29:37 iliaa Exp $ */
844
845 #include "php.h"
846
847@@ -364,10 +364,12 @@
848 if (!ps_files_path_create(buf, sizeof(buf), data, key))
849 return FAILURE;
850
851- ps_files_close(data);
852+ if (data->fd != -1) {
853+ ps_files_close(data);
854
855- if (VCWD_UNLINK(buf) == -1) {
856- return FAILURE;
857+ if (VCWD_UNLINK(buf) == -1) {
858+ return FAILURE;
859+ }
860 }
861
862 return SUCCESS;
863@@ -389,6 +391,34 @@
864 return SUCCESS;
865 }
866
867+PS_VALIDATE_SID_FUNC(files)
868+{
869+ char buf[MAXPATHLEN];
870+ int fd;
871+ PS_FILES_DATA;
872+
873+ if (!ps_files_valid_key(key)) {
874+ return FAILURE;
875+ }
876+
877+ if (!PS(use_strict_mode)) {
878+ return SUCCESS;
879+ }
880+
881+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
882+ return FAILURE;
883+ }
884+
885+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
886+
887+ if (fd != -1) {
888+ close(fd);
889+ return SUCCESS;
890+ }
891+
892+ return FAILURE;
893+}
894+
895 /*
896 * Local variables:
897 * tab-width: 4
898diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.11/ext/session/mod_mm.c
899--- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100
900+++ hardening-patch-4.4.2-0.4.11/ext/session/mod_mm.c 2006-05-13 18:01:56.000000000 +0200
901@@ -425,6 +425,42 @@
902 return SUCCESS;
903 }
904
905+PS_VALIDATE_SID_FUNC(mm)
906+{
907+ PS_MM_DATA;
908+ ps_sd *sd;
909+ const char *p;
910+ char c;
911+ int ret = SUCCESS;
912+
913+ for (p = key; (c = *p); p++) {
914+ /* valid characters are a..z,A..Z,0..9 */
915+ if (!((c >= 'a' && c <= 'z')
916+ || (c >= 'A' && c <= 'Z')
917+ || (c >= '0' && c <= '9')
918+ || c == ','
919+ || c == '-')) {
920+ return FAILURE;
921+ }
922+ }
923+
924+ if (!PS(use_strict_mode)) {
925+ return SUCCESS;
926+ }
927+
928+ mm_lock(data->mm, MM_LOCK_RD);
929+
930+ sd = ps_sd_lookup(data, key, 0);
931+ if (sd) {
932+ mm_unlock(data->mm);
933+ return SUCCESS;
934+ }
935+
936+ mm_unlock(data->mm);
937+
938+ return FAILURE;
939+}
940+
941 #endif
942
943 /*
944diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.11/ext/session/mod_user.c
945--- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100
946+++ hardening-patch-4.4.2-0.4.11/ext/session/mod_user.c 2006-05-13 18:01:56.000000000 +0200
947@@ -23,7 +23,7 @@
948 #include "mod_user.h"
949
950 ps_module ps_mod_user = {
951- PS_MOD(user)
952+ PS_MOD_SID(user)
953 };
954
955 #define SESS_ZVAL_LONG(val, a) \
956@@ -174,6 +174,83 @@
957 FINISH;
958 }
959
960+PS_CREATE_SID_FUNC(user)
961+{
962+ int i;
963+ char *val = NULL;
964+ zval *retval;
965+ ps_user *mdata = PS_GET_MOD_DATA();
966+
967+ if (!mdata)
968+ return estrndup("", 0);
969+
970+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
971+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
972+ }
973+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
974+
975+ if (retval) {
976+ if (Z_TYPE_P(retval) == IS_STRING) {
977+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
978+ } else {
979+ val = estrndup("", 0);
980+ }
981+ zval_ptr_dtor(&retval);
982+ } else {
983+ val = estrndup("", 0);
984+ }
985+
986+ return val;
987+}
988+
989+static int ps_user_valid_key(const char *key TSRMLS_DC)
990+{
991+ size_t len;
992+ const char *p;
993+ char c;
994+ int ret = SUCCESS;
995+
996+ for (p = key; (c = *p); p++) {
997+ /* valid characters are a..z,A..Z,0..9 */
998+ if (!((c >= 'a' && c <= 'z')
999+ || (c >= 'A' && c <= 'Z')
1000+ || (c >= '0' && c <= '9')
1001+ || c == ','
1002+ || c == '-')) {
1003+ ret = FAILURE;
1004+ break;
1005+ }
1006+ }
1007+
1008+ len = p - key;
1009+
1010+ if (len == 0)
1011+ ret = FAILURE;
1012+
1013+ return ret;
1014+}
1015+
1016+PS_VALIDATE_SID_FUNC(user)
1017+{
1018+ zval *args[1];
1019+ STDVARS;
1020+
1021+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
1022+ return ps_user_valid_key(key TSRMLS_CC);
1023+ }
1024+ SESS_ZVAL_STRING(key, args[0]);
1025+
1026+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
1027+
1028+ if (retval) {
1029+ convert_to_long(retval);
1030+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
1031+ zval_ptr_dtor(&retval);
1032+ }
1033+
1034+ return ret;
1035+}
1036+
1037 /*
1038 * Local variables:
1039 * tab-width: 4
1040diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.11/ext/session/mod_user.h
1041--- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100
1042+++ hardening-patch-4.4.2-0.4.11/ext/session/mod_user.h 2006-05-13 18:01:56.000000000 +0200
1043@@ -22,7 +22,7 @@
1044 #define MOD_USER_H
1045
1046 typedef union {
1047- zval *names[6];
1048+ zval *names[8];
1049 struct {
1050 zval *ps_open;
1051 zval *ps_close;
1052@@ -30,6 +30,8 @@
1053 zval *ps_write;
1054 zval *ps_destroy;
1055 zval *ps_gc;
1056+ zval *ps_create;
1057+ zval *ps_validate;
1058 } name;
1059 } ps_user;
1060
1061diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.11/ext/session/php_session.h
1062--- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100
1063+++ hardening-patch-4.4.2-0.4.11/ext/session/php_session.h 2006-05-13 18:01:56.000000000 +0200
1064@@ -23,7 +23,7 @@
1065
1066 #include "ext/standard/php_var.h"
1067
1068-#define PHP_SESSION_API 20020330
1069+#define PHP_SESSION_API 20051121
1070
1071 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1072 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1073@@ -32,6 +32,7 @@
1074 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1075 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1076 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1077+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1078
1079 /* default create id function */
1080 char *php_session_create_id(PS_CREATE_SID_ARGS);
1081@@ -45,6 +46,7 @@
1082 int (*s_destroy)(PS_DESTROY_ARGS);
1083 int (*s_gc)(PS_GC_ARGS);
1084 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1085+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1086 } ps_module;
1087
1088 #define PS_GET_MOD_DATA() *mod_data
1089@@ -57,6 +59,7 @@
1090 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1091 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1092 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1093+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1094
1095 #define PS_FUNCS(x) \
1096 PS_OPEN_FUNC(x); \
1097@@ -65,11 +68,12 @@
1098 PS_WRITE_FUNC(x); \
1099 PS_DESTROY_FUNC(x); \
1100 PS_GC_FUNC(x); \
1101- PS_CREATE_SID_FUNC(x)
1102+ PS_CREATE_SID_FUNC(x); \
1103+ PS_VALIDATE_SID_FUNC(x)
1104
1105 #define PS_MOD(x) \
1106 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1107- ps_delete_##x, ps_gc_##x, php_session_create_id
1108+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1109
1110 /* SID enabled module handler definitions */
1111 #define PS_FUNCS_SID(x) \
1112@@ -79,11 +83,12 @@
1113 PS_WRITE_FUNC(x); \
1114 PS_DESTROY_FUNC(x); \
1115 PS_GC_FUNC(x); \
1116- PS_CREATE_SID_FUNC(x)
1117+ PS_CREATE_SID_FUNC(x); \
1118+ PS_VALIDATE_SID(x)
1119
1120 #define PS_MOD_SID(x) \
1121 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1122- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1123+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1124
1125 typedef enum {
1126 php_session_disabled,
1127@@ -120,6 +125,7 @@
1128 zend_bool use_only_cookies;
1129 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1130 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1131+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1132 int send_cookie;
1133 int define_sid;
1134 } php_ps_globals;
1135diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.11/ext/session/session.c
1136--- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100
1137+++ hardening-patch-4.4.2-0.4.11/ext/session/session.c 2006-05-13 18:01:56.000000000 +0200
1138@@ -17,7 +17,7 @@
1139 +----------------------------------------------------------------------+
1140 */
1141
1142-/* $Id: session.c,v 1.336.2.53.2.4 2006/01/01 13:46:56 sniper Exp $ */
1143+/* $Id: session.c,v 1.336.2.53.2.5 2006/01/15 16:52:10 iliaa Exp $ */
1144
1145 #ifdef HAVE_CONFIG_H
1146 #include "config.h"
1147@@ -155,6 +155,7 @@
1148 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1149 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1150 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1151+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1152 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1153 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1154 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1155@@ -626,6 +627,12 @@
1156 char *val;
1157 int vallen;
1158
1159+ /* check session name for invalid characters */
1160+ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
1161+ efree(PS(id));
1162+ PS(id) = NULL;
1163+ }
1164+
1165 if (!PS(mod)) {
1166 php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session.");
1167 return;
1168@@ -637,6 +644,15 @@
1169 return;
1170 }
1171
1172+ /* If there is an ID, use session module to verify it */
1173+ if (PS(id)) {
1174+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1175+ efree(PS(id));
1176+ PS(id) = NULL;
1177+ PS(send_cookie) = 1;
1178+ }
1179+ }
1180+
1181 /* If there is no ID, use session module to create one */
1182 if (!PS(id))
1183 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1184@@ -1256,22 +1272,31 @@
1185 }
1186 /* }}} */
1187
1188-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1189+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1190 Sets user-level functions */
1191 PHP_FUNCTION(session_set_save_handler)
1192 {
1193- zval **args[6];
1194- int i;
1195+ zval **args[8];
1196+ int i, numargs;
1197 ps_user *mdata;
1198 char *name;
1199
1200+ numargs = ZEND_NUM_ARGS();
1201+ args[6] = NULL;
1202+ args[7] = NULL;
1203+
1204+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1205+ WRONG_PARAM_COUNT;
1206 if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1207 WRONG_PARAM_COUNT;
1208
1209 if (PS(session_status) != php_session_none)
1210 RETURN_FALSE;
1211
1212- for (i = 0; i < 6; i++) {
1213+ for (i = 0; i < 8; i++) {
1214+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1215+ continue;
1216+ }
1217 if (!zend_is_callable(*args[i], 0, &name)) {
1218 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1219 efree(name);
1220@@ -1284,7 +1309,11 @@
1221
1222 mdata = emalloc(sizeof(*mdata));
1223
1224- for (i = 0; i < 6; i++) {
1225+ for (i = 0; i < 8; i++) {
1226+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1227+ mdata->names[i] = NULL;
1228+ continue;
1229+ }
1230 ZVAL_ADDREF(*args[i]);
1231 mdata->names[i] = *args[i];
1232 }
1233@@ -1345,8 +1374,20 @@
1234 Update the current session id with a newly generated one. */
1235 PHP_FUNCTION(session_regenerate_id)
1236 {
1237+ zend_bool del_ses = 0;
1238+
1239+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1240+ WRONG_PARAM_COUNT;
1241+ }
1242+
1243 if (PS(session_status) == php_session_active) {
1244- if (PS(id)) efree(PS(id));
1245+ if (PS(id)) {
1246+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1247+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1248+ RETURN_FALSE;
1249+ }
1250+ efree(PS(id));
1251+ }
1252
1253 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1254
1255diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.11/ext/session/tests/014.phpt
1256--- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1257+++ hardening-patch-4.4.2-0.4.11/ext/session/tests/014.phpt 2006-05-13 18:01:56.000000000 +0200
1258@@ -5,6 +5,7 @@
1259 --INI--
1260 session.use_trans_sid=1
1261 session.use_cookies=0
1262+session.use_strict_mode=0
1263 session.cache_limiter=
1264 register_globals=1
1265 session.bug_compat_42=1
1266diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.11/ext/session/tests/015.phpt
1267--- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1268+++ hardening-patch-4.4.2-0.4.11/ext/session/tests/015.phpt 2006-05-13 18:01:56.000000000 +0200
1269@@ -5,6 +5,7 @@
1270 --INI--
1271 session.use_trans_sid=1
1272 session.use_cookies=0
1273+session.use_strict_mode=0
1274 session.cache_limiter=
1275 arg_separator.output=&
1276 session.name=PHPSESSID
1277diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.11/ext/session/tests/018.phpt
1278--- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1279+++ hardening-patch-4.4.2-0.4.11/ext/session/tests/018.phpt 2006-05-13 18:01:56.000000000 +0200
1280@@ -4,6 +4,7 @@
1281 <?php include('skipif.inc'); ?>
1282 --INI--
1283 session.use_cookies=0
1284+session.use_strict_mode=0
1285 session.cache_limiter=
1286 session.use_trans_sid=1
1287 session.name=PHPSESSID
1288diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.11/ext/session/tests/020.phpt
1289--- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1290+++ hardening-patch-4.4.2-0.4.11/ext/session/tests/020.phpt 2006-05-13 18:01:56.000000000 +0200
1291@@ -4,6 +4,7 @@
1292 <?php include('skipif.inc'); ?>
1293 --INI--
1294 session.use_cookies=0
1295+session.use_strict_mode=0
1296 session.cache_limiter=
1297 session.use_trans_sid=1
1298 arg_separator.output=&amp;
1299diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.11/ext/session/tests/021.phpt
1300--- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1301+++ hardening-patch-4.4.2-0.4.11/ext/session/tests/021.phpt 2006-05-13 18:01:56.000000000 +0200
1302@@ -4,6 +4,7 @@
1303 <?php include('skipif.inc'); ?>
1304 --INI--
1305 session.use_cookies=0
1306+session.use_strict_mode=0
1307 session.cache_limiter=
1308 session.use_trans_sid=1
1309 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1310diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.11/ext/standard/array.c
1311--- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100
1312+++ hardening-patch-4.4.2-0.4.11/ext/standard/array.c 2006-05-13 18:01:56.000000000 +0200
1313@@ -1162,6 +1162,32 @@
1314 }
1315 }
1316 }
1317+
1318+ if (var_name[0] == 'H') {
1319+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1320+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1321+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1322+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1323+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1324+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1325+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1326+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1327+ return 0;
1328+ }
1329+ } else if (var_name[0] == '_') {
1330+ if ((strcmp(var_name, "_COOKIE")==0)||
1331+ (strcmp(var_name, "_ENV")==0)||
1332+ (strcmp(var_name, "_FILES")==0)||
1333+ (strcmp(var_name, "_GET")==0)||
1334+ (strcmp(var_name, "_POST")==0)||
1335+ (strcmp(var_name, "_REQUEST")==0)||
1336+ (strcmp(var_name, "_SESSION")==0)||
1337+ (strcmp(var_name, "_SERVER")==0)) {
1338+ return 0;
1339+ }
1340+ } else if (strcmp(var_name, "GLOBALS")==0) {
1341+ return 0;
1342+ }
1343
1344 return 1;
1345 }
1346diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.11/ext/standard/basic_functions.c
1347--- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100
1348+++ hardening-patch-4.4.2-0.4.11/ext/standard/basic_functions.c 2006-05-13 18:01:56.000000000 +0200
1349@@ -107,12 +107,14 @@
1350 typedef struct _php_shutdown_function_entry {
1351 zval **arguments;
1352 int arg_count;
1353+ zend_bool created_by_eval;
1354 } php_shutdown_function_entry;
1355
1356 typedef struct _user_tick_function_entry {
1357 zval **arguments;
1358 int arg_count;
1359 int calling;
1360+ zend_bool created_by_eval;
1361 } user_tick_function_entry;
1362
1363 /* some prototypes for local functions */
1364@@ -295,6 +297,8 @@
1365 PHP_FE(get_html_translation_table, NULL)
1366 PHP_FE(sha1, NULL)
1367 PHP_FE(sha1_file, NULL)
1368+ PHP_FE(sha256, NULL)
1369+ PHP_FE(sha256_file, NULL)
1370 PHP_NAMED_FE(md5,php_if_md5, NULL)
1371 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1372 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1373@@ -676,7 +680,7 @@
1374 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1375
1376 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1377- PHP_FE(realpath, NULL)
1378+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1379 #endif
1380
1381 #ifdef HAVE_FNMATCH
1382@@ -2096,6 +2100,13 @@
1383 {
1384 zval retval;
1385 char *function_name = NULL;
1386+#if HARDENING_PATCH
1387+ zend_uint orig_code_type = EG(in_code_type);
1388+
1389+ if (shutdown_function_entry->created_by_eval) {
1390+ EG(in_code_type) = ZEND_EVAL_CODE;
1391+ }
1392+#endif
1393
1394 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1395 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1396@@ -2111,6 +2122,9 @@
1397 if (function_name) {
1398 efree(function_name);
1399 }
1400+#if HARDENING_PATCH
1401+ EG(in_code_type) = orig_code_type;
1402+#endif
1403 return 0;
1404 }
1405
1406@@ -2118,6 +2132,13 @@
1407 {
1408 zval retval;
1409 zval *function = tick_fe->arguments[0];
1410+#if HARDENING_PATCH
1411+ zend_uint orig_code_type = EG(in_code_type);
1412+
1413+ if (tick_fe->created_by_eval) {
1414+ EG(in_code_type) = ZEND_EVAL_CODE;
1415+ }
1416+#endif
1417
1418 /* Prevent reentrant calls to the same user ticks function */
1419 if (! tick_fe->calling) {
1420@@ -2149,6 +2170,9 @@
1421
1422 tick_fe->calling = 0;
1423 }
1424+#if HARDENING_PATCH
1425+ EG(in_code_type) = orig_code_type;
1426+#endif
1427 }
1428
1429 static void run_user_tick_functions(int tick_count)
1430@@ -2216,6 +2240,13 @@
1431 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1432 RETURN_FALSE;
1433 }
1434+#if HARDENING_PATCH
1435+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1436+ shutdown_function_entry.created_by_eval = 1;
1437+ } else {
1438+ shutdown_function_entry.created_by_eval = 0;
1439+ }
1440+#endif
1441
1442 /* Prevent entering of anything but valid callback (syntax check only!) */
1443 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1444@@ -2753,6 +2784,13 @@
1445 }
1446
1447 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1448+#if HARDENING_PATCH
1449+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1450+ tick_fe.created_by_eval = 1;
1451+ } else {
1452+ tick_fe.created_by_eval = 0;
1453+ }
1454+#endif
1455
1456 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1457 RETURN_FALSE;
1458@@ -3050,6 +3088,35 @@
1459 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1460 }
1461
1462+ if (new_key[0] == 'H') {
1463+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1464+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1465+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1466+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1467+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1468+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1469+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1470+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1471+ efree(new_key);
1472+ return 0;
1473+ }
1474+ } else if (new_key[0] == '_') {
1475+ if ((strcmp(new_key, "_COOKIE")==0)||
1476+ (strcmp(new_key, "_ENV")==0)||
1477+ (strcmp(new_key, "_FILES")==0)||
1478+ (strcmp(new_key, "_GET")==0)||
1479+ (strcmp(new_key, "_POST")==0)||
1480+ (strcmp(new_key, "_REQUEST")==0)||
1481+ (strcmp(new_key, "_SESSION")==0)||
1482+ (strcmp(new_key, "_SERVER")==0)) {
1483+ efree(new_key);
1484+ return 0;
1485+ }
1486+ } else if (strcmp(new_key, "GLOBALS")==0) {
1487+ efree(new_key);
1488+ return 0;
1489+ }
1490+
1491 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1492 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1493
1494diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.11/ext/standard/config.m4
1495--- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1496+++ hardening-patch-4.4.2-0.4.11/ext/standard/config.m4 2006-05-13 18:01:56.000000000 +0200
1497@@ -203,7 +203,7 @@
1498 if test "$ac_cv_crypt_blowfish" = "yes"; then
1499 ac_result=1
1500 else
1501- ac_result=0
1502+ ac_result=1
1503 fi
1504 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1505 ])
1506@@ -419,6 +419,6 @@
1507 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1508 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1509 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1510- var_unserializer.c ftok.c aggregation.c sha1.c )
1511+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1512
1513 PHP_ADD_MAKEFILE_FRAGMENT
1514diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.11/ext/standard/crypt_blowfish.c
1515--- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1516+++ hardening-patch-4.4.2-0.4.11/ext/standard/crypt_blowfish.c 2006-05-13 18:01:56.000000000 +0200
1517@@ -0,0 +1,748 @@
1518+/*
1519+ * This code comes from John the Ripper password cracker, with reentrant
1520+ * and crypt(3) interfaces added, but optimizations specific to password
1521+ * cracking removed.
1522+ *
1523+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1524+ * placed in the public domain.
1525+ *
1526+ * There's absolutely no warranty.
1527+ *
1528+ * It is my intent that you should be able to use this on your system,
1529+ * as a part of a software package, or anywhere else to improve security,
1530+ * ensure compatibility, or for any other purpose. I would appreciate
1531+ * it if you give credit where it is due and keep your modifications in
1532+ * the public domain as well, but I don't require that in order to let
1533+ * you place this code and any modifications you make under a license
1534+ * of your choice.
1535+ *
1536+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1537+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1538+ * ideas. The password hashing algorithm was designed by David Mazieres
1539+ * <dm at lcs.mit.edu>.
1540+ *
1541+ * There's a paper on the algorithm that explains its design decisions:
1542+ *
1543+ * http://www.usenix.org/events/usenix99/provos.html
1544+ *
1545+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1546+ * Blowfish library (I can't be sure if I would think of something if I
1547+ * hadn't seen his code).
1548+ */
1549+
1550+#include <string.h>
1551+
1552+#include <errno.h>
1553+#ifndef __set_errno
1554+#define __set_errno(val) errno = (val)
1555+#endif
1556+
1557+#undef __CONST
1558+#ifdef __GNUC__
1559+#define __CONST __const
1560+#else
1561+#define __CONST
1562+#endif
1563+
1564+#ifdef __i386__
1565+#define BF_ASM 0
1566+#define BF_SCALE 1
1567+#elif defined(__alpha__) || defined(__hppa__)
1568+#define BF_ASM 0
1569+#define BF_SCALE 1
1570+#else
1571+#define BF_ASM 0
1572+#define BF_SCALE 0
1573+#endif
1574+
1575+typedef unsigned int BF_word;
1576+
1577+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1578+#define BF_N 16
1579+
1580+typedef BF_word BF_key[BF_N + 2];
1581+
1582+typedef struct {
1583+ BF_word S[4][0x100];
1584+ BF_key P;
1585+} BF_ctx;
1586+
1587+/*
1588+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1589+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1590+ */
1591+static BF_word BF_magic_w[6] = {
1592+ 0x4F727068, 0x65616E42, 0x65686F6C,
1593+ 0x64657253, 0x63727944, 0x6F756274
1594+};
1595+
1596+/*
1597+ * P-box and S-box tables initialized with digits of Pi.
1598+ */
1599+static BF_ctx BF_init_state = {
1600+ {
1601+ {
1602+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1603+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1604+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1605+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1606+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1607+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1608+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1609+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1610+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1611+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1612+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1613+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1614+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1615+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1616+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1617+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1618+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1619+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1620+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1621+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1622+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1623+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1624+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1625+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1626+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1627+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1628+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1629+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1630+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1631+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1632+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1633+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1634+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1635+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1636+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1637+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1638+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1639+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1640+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1641+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1642+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1643+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1644+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1645+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1646+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1647+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1648+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1649+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1650+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1651+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1652+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1653+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1654+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1655+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1656+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1657+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1658+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1659+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1660+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1661+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1662+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1663+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1664+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1665+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1666+ }, {
1667+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1668+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1669+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1670+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1671+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1672+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1673+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1674+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1675+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1676+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1677+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1678+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1679+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1680+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1681+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1682+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1683+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1684+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1685+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1686+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1687+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1688+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1689+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1690+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1691+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1692+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1693+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1694+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1695+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1696+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1697+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1698+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1699+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1700+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1701+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1702+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1703+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1704+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1705+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1706+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1707+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1708+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1709+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1710+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1711+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1712+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1713+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1714+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1715+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1716+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1717+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1718+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1719+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1720+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1721+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1722+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1723+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1724+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1725+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1726+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1727+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1728+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1729+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1730+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1731+ }, {
1732+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1733+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1734+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1735+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1736+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1737+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1738+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1739+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1740+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1741+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1742+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1743+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1744+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1745+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1746+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1747+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1748+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1749+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1750+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1751+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1752+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1753+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1754+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1755+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1756+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1757+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1758+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1759+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1760+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1761+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1762+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1763+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1764+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1765+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1766+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1767+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1768+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1769+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1770+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1771+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1772+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1773+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1774+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1775+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1776+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1777+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1778+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1779+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1780+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1781+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1782+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1783+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1784+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1785+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1786+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1787+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1788+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1789+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1790+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1791+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1792+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1793+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1794+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1795+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1796+ }, {
1797+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1798+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1799+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1800+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1801+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1802+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1803+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1804+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1805+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1806+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1807+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1808+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1809+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1810+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1811+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1812+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1813+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1814+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1815+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1816+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1817+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1818+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1819+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1820+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1821+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1822+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1823+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1824+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1825+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1826+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1827+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1828+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1829+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1830+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1831+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1832+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1833+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1834+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1835+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1836+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1837+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1838+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1839+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1840+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1841+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1842+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1843+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1844+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1845+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1846+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1847+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1848+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1849+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1850+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1851+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1852+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1853+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1854+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1855+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1856+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1857+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1858+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1859+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1860+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1861+ }
1862+ }, {
1863+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1864+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1865+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1866+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1867+ 0x9216d5d9, 0x8979fb1b
1868+ }
1869+};
1870+
1871+static unsigned char BF_itoa64[64 + 1] =
1872+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1873+
1874+static unsigned char BF_atoi64[0x60] = {
1875+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1876+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1877+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1878+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1879+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1880+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1881+};
1882+
1883+/*
1884+ * This may be optimized out if built with function inlining and no BF_ASM.
1885+ */
1886+static void clean(void *data, int size)
1887+{
1888+#if BF_ASM
1889+ extern void _BF_clean(void *data);
1890+#endif
1891+ memset(data, 0, size);
1892+#if BF_ASM
1893+ _BF_clean(data);
1894+#endif
1895+}
1896+
1897+#define BF_safe_atoi64(dst, src) \
1898+{ \
1899+ tmp = (unsigned char)(src); \
1900+ if (tmp == '$') break; \
1901+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1902+ tmp = BF_atoi64[tmp]; \
1903+ if (tmp > 63) return -1; \
1904+ (dst) = tmp; \
1905+}
1906+
1907+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1908+{
1909+ unsigned char *dptr = (unsigned char *)dst;
1910+ unsigned char *end = dptr + size;
1911+ unsigned char *sptr = (unsigned char *)src;
1912+ unsigned int tmp, c1, c2, c3, c4;
1913+
1914+ do {
1915+ BF_safe_atoi64(c1, *sptr++);
1916+ BF_safe_atoi64(c2, *sptr++);
1917+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1918+ if (dptr >= end) break;
1919+
1920+ BF_safe_atoi64(c3, *sptr++);
1921+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1922+ if (dptr >= end) break;
1923+
1924+ BF_safe_atoi64(c4, *sptr++);
1925+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1926+ } while (dptr < end);
1927+
1928+ while (dptr < end)
1929+ *dptr++ = 0;
1930+
1931+ return 0;
1932+}
1933+
1934+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1935+{
1936+ unsigned char *sptr = (unsigned char *)src;
1937+ unsigned char *end = sptr + size;
1938+ unsigned char *dptr = (unsigned char *)dst;
1939+ unsigned int c1, c2;
1940+
1941+ do {
1942+ c1 = *sptr++;
1943+ *dptr++ = BF_itoa64[c1 >> 2];
1944+ c1 = (c1 & 0x03) << 4;
1945+ if (sptr >= end) {
1946+ *dptr++ = BF_itoa64[c1];
1947+ break;
1948+ }
1949+
1950+ c2 = *sptr++;
1951+ c1 |= c2 >> 4;
1952+ *dptr++ = BF_itoa64[c1];
1953+ c1 = (c2 & 0x0f) << 2;
1954+ if (sptr >= end) {
1955+ *dptr++ = BF_itoa64[c1];
1956+ break;
1957+ }
1958+
1959+ c2 = *sptr++;
1960+ c1 |= c2 >> 6;
1961+ *dptr++ = BF_itoa64[c1];
1962+ *dptr++ = BF_itoa64[c2 & 0x3f];
1963+ } while (sptr < end);
1964+}
1965+
1966+static void BF_swap(BF_word *x, int count)
1967+{
1968+ static int endianness_check = 1;
1969+ char *is_little_endian = (char *)&endianness_check;
1970+ BF_word tmp;
1971+
1972+ if (*is_little_endian)
1973+ do {
1974+ tmp = *x;
1975+ tmp = (tmp << 16) | (tmp >> 16);
1976+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1977+ } while (--count);
1978+}
1979+
1980+#if BF_SCALE
1981+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1982+#define BF_ROUND(L, R, N) \
1983+ tmp1 = L & 0xFF; \
1984+ tmp2 = L >> 8; \
1985+ tmp2 &= 0xFF; \
1986+ tmp3 = L >> 16; \
1987+ tmp3 &= 0xFF; \
1988+ tmp4 = L >> 24; \
1989+ tmp1 = data.ctx.S[3][tmp1]; \
1990+ tmp2 = data.ctx.S[2][tmp2]; \
1991+ tmp3 = data.ctx.S[1][tmp3]; \
1992+ tmp3 += data.ctx.S[0][tmp4]; \
1993+ tmp3 ^= tmp2; \
1994+ R ^= data.ctx.P[N + 1]; \
1995+ tmp3 += tmp1; \
1996+ R ^= tmp3;
1997+#else
1998+/* Architectures with no complicated addressing modes supported */
1999+#define BF_INDEX(S, i) \
2000+ (*((BF_word *)(((unsigned char *)S) + (i))))
2001+#define BF_ROUND(L, R, N) \
2002+ tmp1 = L & 0xFF; \
2003+ tmp1 <<= 2; \
2004+ tmp2 = L >> 6; \
2005+ tmp2 &= 0x3FC; \
2006+ tmp3 = L >> 14; \
2007+ tmp3 &= 0x3FC; \
2008+ tmp4 = L >> 22; \
2009+ tmp4 &= 0x3FC; \
2010+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
2011+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
2012+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
2013+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
2014+ tmp3 ^= tmp2; \
2015+ R ^= data.ctx.P[N + 1]; \
2016+ tmp3 += tmp1; \
2017+ R ^= tmp3;
2018+#endif
2019+
2020+/*
2021+ * Encrypt one block, BF_N is hardcoded here.
2022+ */
2023+#define BF_ENCRYPT \
2024+ L ^= data.ctx.P[0]; \
2025+ BF_ROUND(L, R, 0); \
2026+ BF_ROUND(R, L, 1); \
2027+ BF_ROUND(L, R, 2); \
2028+ BF_ROUND(R, L, 3); \
2029+ BF_ROUND(L, R, 4); \
2030+ BF_ROUND(R, L, 5); \
2031+ BF_ROUND(L, R, 6); \
2032+ BF_ROUND(R, L, 7); \
2033+ BF_ROUND(L, R, 8); \
2034+ BF_ROUND(R, L, 9); \
2035+ BF_ROUND(L, R, 10); \
2036+ BF_ROUND(R, L, 11); \
2037+ BF_ROUND(L, R, 12); \
2038+ BF_ROUND(R, L, 13); \
2039+ BF_ROUND(L, R, 14); \
2040+ BF_ROUND(R, L, 15); \
2041+ tmp4 = R; \
2042+ R = L; \
2043+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2044+
2045+#if BF_ASM
2046+#define BF_body() \
2047+ _BF_body_r(&data.ctx);
2048+#else
2049+#define BF_body() \
2050+ L = R = 0; \
2051+ ptr = data.ctx.P; \
2052+ do { \
2053+ ptr += 2; \
2054+ BF_ENCRYPT; \
2055+ *(ptr - 2) = L; \
2056+ *(ptr - 1) = R; \
2057+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2058+\
2059+ ptr = data.ctx.S[0]; \
2060+ do { \
2061+ ptr += 2; \
2062+ BF_ENCRYPT; \
2063+ *(ptr - 2) = L; \
2064+ *(ptr - 1) = R; \
2065+ } while (ptr < &data.ctx.S[3][0xFF]);
2066+#endif
2067+
2068+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2069+{
2070+ __CONST char *ptr = key;
2071+ int i, j;
2072+ BF_word tmp;
2073+
2074+ for (i = 0; i < BF_N + 2; i++) {
2075+ tmp = 0;
2076+ for (j = 0; j < 4; j++) {
2077+ tmp <<= 8;
2078+ tmp |= *ptr;
2079+
2080+ if (!*ptr) ptr = key; else ptr++;
2081+ }
2082+
2083+ expanded[i] = tmp;
2084+ initial[i] = BF_init_state.P[i] ^ tmp;
2085+ }
2086+}
2087+
2088+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2089+ char *output, int size)
2090+{
2091+#if BF_ASM
2092+ extern void _BF_body_r(BF_ctx *ctx);
2093+#endif
2094+ struct {
2095+ BF_ctx ctx;
2096+ BF_key expanded_key;
2097+ union {
2098+ BF_word salt[4];
2099+ BF_word output[6];
2100+ } binary;
2101+ } data;
2102+ BF_word L, R;
2103+ BF_word tmp1, tmp2, tmp3, tmp4;
2104+ BF_word *ptr;
2105+ BF_word count;
2106+ int i;
2107+
2108+ if (size < 7 + 22 + 31 + 1) {
2109+ __set_errno(ERANGE);
2110+ return NULL;
2111+ }
2112+
2113+ if (setting[0] != '$' ||
2114+ setting[1] != '2' ||
2115+ setting[2] != 'a' ||
2116+ setting[3] != '$' ||
2117+ setting[4] < '0' || setting[4] > '3' ||
2118+ setting[5] < '0' || setting[5] > '9' ||
2119+ setting[6] != '$') {
2120+ __set_errno(EINVAL);
2121+ return NULL;
2122+ }
2123+
2124+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2125+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2126+ clean(data.binary.salt, sizeof(data.binary.salt));
2127+ __set_errno(EINVAL);
2128+ return NULL;
2129+ }
2130+
2131+ BF_swap(data.binary.salt, 4);
2132+
2133+ BF_set_key(key, data.expanded_key, data.ctx.P);
2134+
2135+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2136+
2137+ L = R = 0;
2138+ for (i = 0; i < BF_N + 2; i += 2) {
2139+ L ^= data.binary.salt[i & 2];
2140+ R ^= data.binary.salt[(i & 2) + 1];
2141+ BF_ENCRYPT;
2142+ data.ctx.P[i] = L;
2143+ data.ctx.P[i + 1] = R;
2144+ }
2145+
2146+ ptr = data.ctx.S[0];
2147+ do {
2148+ ptr += 4;
2149+ L ^= data.binary.salt[(BF_N + 2) & 3];
2150+ R ^= data.binary.salt[(BF_N + 3) & 3];
2151+ BF_ENCRYPT;
2152+ *(ptr - 4) = L;
2153+ *(ptr - 3) = R;
2154+
2155+ L ^= data.binary.salt[(BF_N + 4) & 3];
2156+ R ^= data.binary.salt[(BF_N + 5) & 3];
2157+ BF_ENCRYPT;
2158+ *(ptr - 2) = L;
2159+ *(ptr - 1) = R;
2160+ } while (ptr < &data.ctx.S[3][0xFF]);
2161+
2162+ do {
2163+ data.ctx.P[0] ^= data.expanded_key[0];
2164+ data.ctx.P[1] ^= data.expanded_key[1];
2165+ data.ctx.P[2] ^= data.expanded_key[2];
2166+ data.ctx.P[3] ^= data.expanded_key[3];
2167+ data.ctx.P[4] ^= data.expanded_key[4];
2168+ data.ctx.P[5] ^= data.expanded_key[5];
2169+ data.ctx.P[6] ^= data.expanded_key[6];
2170+ data.ctx.P[7] ^= data.expanded_key[7];
2171+ data.ctx.P[8] ^= data.expanded_key[8];
2172+ data.ctx.P[9] ^= data.expanded_key[9];
2173+ data.ctx.P[10] ^= data.expanded_key[10];
2174+ data.ctx.P[11] ^= data.expanded_key[11];
2175+ data.ctx.P[12] ^= data.expanded_key[12];
2176+ data.ctx.P[13] ^= data.expanded_key[13];
2177+ data.ctx.P[14] ^= data.expanded_key[14];
2178+ data.ctx.P[15] ^= data.expanded_key[15];
2179+ data.ctx.P[16] ^= data.expanded_key[16];
2180+ data.ctx.P[17] ^= data.expanded_key[17];
2181+
2182+ BF_body();
2183+
2184+ tmp1 = data.binary.salt[0];
2185+ tmp2 = data.binary.salt[1];
2186+ tmp3 = data.binary.salt[2];
2187+ tmp4 = data.binary.salt[3];
2188+ data.ctx.P[0] ^= tmp1;
2189+ data.ctx.P[1] ^= tmp2;
2190+ data.ctx.P[2] ^= tmp3;
2191+ data.ctx.P[3] ^= tmp4;
2192+ data.ctx.P[4] ^= tmp1;
2193+ data.ctx.P[5] ^= tmp2;
2194+ data.ctx.P[6] ^= tmp3;
2195+ data.ctx.P[7] ^= tmp4;
2196+ data.ctx.P[8] ^= tmp1;
2197+ data.ctx.P[9] ^= tmp2;
2198+ data.ctx.P[10] ^= tmp3;
2199+ data.ctx.P[11] ^= tmp4;
2200+ data.ctx.P[12] ^= tmp1;
2201+ data.ctx.P[13] ^= tmp2;
2202+ data.ctx.P[14] ^= tmp3;
2203+ data.ctx.P[15] ^= tmp4;
2204+ data.ctx.P[16] ^= tmp1;
2205+ data.ctx.P[17] ^= tmp2;
2206+
2207+ BF_body();
2208+ } while (--count);
2209+
2210+ for (i = 0; i < 6; i += 2) {
2211+ L = BF_magic_w[i];
2212+ R = BF_magic_w[i + 1];
2213+
2214+ count = 64;
2215+ do {
2216+ BF_ENCRYPT;
2217+ } while (--count);
2218+
2219+ data.binary.output[i] = L;
2220+ data.binary.output[i + 1] = R;
2221+ }
2222+
2223+ memcpy(output, setting, 7 + 22 - 1);
2224+ output[7 + 22 - 1] = BF_itoa64[(int)
2225+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2226+
2227+/* This has to be bug-compatible with the original implementation, so
2228+ * only encode 23 of the 24 bytes. :-) */
2229+ BF_swap(data.binary.output, 6);
2230+ BF_encode(&output[7 + 22], data.binary.output, 23);
2231+ output[7 + 22 + 31] = '\0';
2232+
2233+/* Overwrite the most obvious sensitive data we have on the stack. Note
2234+ * that this does not guarantee there's no sensitive data left on the
2235+ * stack and/or in registers; I'm not aware of portable code that does. */
2236+ clean(&data, sizeof(data));
2237+
2238+ return output;
2239+}
2240+
2241+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2242+ __CONST char *input, int size, char *output, int output_size)
2243+{
2244+ if (size < 16 || output_size < 7 + 22 + 1 ||
2245+ (count && (count < 4 || count > 31))) {
2246+ if (output_size > 0) output[0] = '\0';
2247+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2248+ return NULL;
2249+ }
2250+
2251+ if (!count) count = 5;
2252+
2253+ output[0] = '$';
2254+ output[1] = '2';
2255+ output[2] = 'a';
2256+ output[3] = '$';
2257+ output[4] = '0' + count / 10;
2258+ output[5] = '0' + count % 10;
2259+ output[6] = '$';
2260+
2261+ BF_encode(&output[7], (BF_word *)input, 16);
2262+ output[7 + 22] = '\0';
2263+
2264+ return output;
2265+}
2266diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.11/ext/standard/crypt.c
2267--- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100
2268+++ hardening-patch-4.4.2-0.4.11/ext/standard/crypt.c 2006-05-13 18:01:56.000000000 +0200
2269@@ -100,6 +100,8 @@
2270 return SUCCESS;
2271 }
2272
2273+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2274+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2275
2276 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2277
2278@@ -135,7 +137,14 @@
2279
2280 /* The automatic salt generation only covers standard DES and md5-crypt */
2281 if(!*salt) {
2282-#if PHP_MD5_CRYPT
2283+#if PHP_BLOWFISH_CRYPT
2284+ char randat[16];
2285+ int i;
2286+
2287+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2288+
2289+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2290+#elif PHP_MD5_CRYPT
2291 strcpy(salt, "$1$");
2292 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2293 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2294@@ -145,8 +154,24 @@
2295 salt[2] = '\0';
2296 #endif
2297 }
2298-
2299- RETVAL_STRING(crypt(str, salt), 1);
2300+
2301+ if (salt[0] == '$' &&
2302+ salt[1] == '2' &&
2303+ salt[2] == 'a' &&
2304+ salt[3] == '$' &&
2305+ salt[4] >= '0' && salt[4] <= '3' &&
2306+ salt[5] >= '0' && salt[5] <= '9' &&
2307+ salt[6] == '$') {
2308+
2309+ char output[PHP_MAX_SALT_LEN+1];
2310+
2311+ output[0] = 0;
2312+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2313+ RETVAL_STRING(output, 1);
2314+
2315+ } else {
2316+ RETVAL_STRING(crypt(str, salt), 1);
2317+ }
2318 }
2319 /* }}} */
2320 #endif
2321diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.11/ext/standard/dl.c
2322--- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100
2323+++ hardening-patch-4.4.2-0.4.11/ext/standard/dl.c 2006-05-13 18:01:56.000000000 +0200
2324@@ -160,8 +160,35 @@
2325 RETURN_FALSE;
2326 }
2327 module_entry = get_module();
2328+
2329+ /* check if Hardening-Patch is installed */
2330+ if (module_entry->zend_api < 1000000000) {
2331+ php_error_docref(NULL TSRMLS_CC, error_type,
2332+ "%s: Unable to initialize module\n"
2333+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2334+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2335+ "These options need to match\n",
2336+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2337+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2338+ DL_UNLOAD(handle);
2339+ RETURN_FALSE;
2340+ }
2341+
2342+ /* check if correct Hardening-Patch is installed */
2343+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2344+ php_error_docref(NULL TSRMLS_CC, error_type,
2345+ "%s: Unable to initialize module\n"
2346+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2347+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2348+ "These options need to match\n",
2349+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2350+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2351+ DL_UNLOAD(handle);
2352+ RETURN_FALSE;
2353+ }
2354+
2355 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2356- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2357+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2358 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2359 struct pre_4_1_0_module_entry {
2360 char *name;
2361@@ -195,7 +222,7 @@
2362 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2363 } else {
2364 name = module_entry->name;
2365- zend_api = module_entry->zend_api;
2366+ zend_api = module_entry->real_zend_api;
2367 zend_debug = module_entry->zend_debug;
2368 zts = module_entry->zts;
2369 }
2370diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.11/ext/standard/file.c
2371--- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100
2372+++ hardening-patch-4.4.2-0.4.11/ext/standard/file.c 2006-05-13 18:01:56.000000000 +0200
2373@@ -21,7 +21,7 @@
2374 +----------------------------------------------------------------------+
2375 */
2376
2377-/* $Id: file.c,v 1.279.2.70.2.3 2006/01/01 13:46:57 sniper Exp $ */
2378+/* $Id: file.c,v 1.279.2.70.2.7 2006/04/14 17:46:59 pollita Exp $ */
2379
2380 /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */
2381
2382@@ -552,7 +552,7 @@
2383 pval **arg1, **arg2;
2384 char *d;
2385 char *opened_path;
2386- char p[64];
2387+ char *p;
2388 FILE *fp;
2389
2390 if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &arg1, &arg2) == FAILURE) {
2391@@ -566,7 +566,11 @@
2392 }
2393
2394 d = estrndup(Z_STRVAL_PP(arg1), Z_STRLEN_PP(arg1));
2395- strlcpy(p, Z_STRVAL_PP(arg2), sizeof(p));
2396+
2397+ p = php_basename(Z_STRVAL_PP(arg2), Z_STRLEN_PP(arg2), NULL, 0);
2398+ if (strlen(p) > 64) {
2399+ p[63] = '\0';
2400+ }
2401
2402 if ((fp = php_open_temporary_file(d, p, &opened_path TSRMLS_CC))) {
2403 fclose(fp);
2404@@ -574,6 +578,7 @@
2405 } else {
2406 RETVAL_FALSE;
2407 }
2408+ efree(p);
2409 efree(d);
2410 }
2411 /* }}} */
2412@@ -819,7 +824,7 @@
2413
2414 /* If seconds is not set to null, build the timeval, else we wait indefinitely */
2415 if (sec != NULL) {
2416- convert_to_long_ex(&sec);
2417+ convert_to_long(sec);
2418
2419 if (usec > 999999) {
2420 tv.tv_sec = Z_LVAL_P(sec) + (usec / 1000000);
2421@@ -2196,7 +2201,7 @@
2422 safe_to_copy:
2423
2424 srcstream = php_stream_open_wrapper(src, "rb",
2425- STREAM_DISABLE_OPEN_BASEDIR | REPORT_ERRORS,
2426+ ENFORCE_SAFE_MODE | REPORT_ERRORS,
2427 NULL);
2428
2429 if (!srcstream)
2430@@ -2522,7 +2527,7 @@
2431 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2432 /* {{{ proto string realpath(string path)
2433 Return the resolved path */
2434-PHP_FUNCTION(realpath)
2435+PHP_FUNCTION(real_path)
2436 {
2437 zval **path;
2438 char resolved_path_buff[MAXPATHLEN];
2439diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.11/ext/standard/file.h
2440--- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100
2441+++ hardening-patch-4.4.2-0.4.11/ext/standard/file.h 2006-05-13 18:01:56.000000000 +0200
2442@@ -64,7 +64,7 @@
2443 PHP_FUNCTION(fd_set);
2444 PHP_FUNCTION(fd_isset);
2445 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2446-PHP_FUNCTION(realpath);
2447+PHP_FUNCTION(real_path);
2448 #endif
2449 #ifdef HAVE_FNMATCH
2450 PHP_FUNCTION(fnmatch);
2451diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.11/ext/standard/head.c
2452--- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100
2453+++ hardening-patch-4.4.2-0.4.11/ext/standard/head.c 2006-05-13 18:01:56.000000000 +0200
2454@@ -44,7 +44,7 @@
2455 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2456 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2457 return;
2458-
2459+
2460 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2461 }
2462 /* }}} */
2463diff -Nura php-4.4.2/ext/standard/html.c hardening-patch-4.4.2-0.4.11/ext/standard/html.c
2464--- php-4.4.2/ext/standard/html.c 2006-01-01 14:46:57.000000000 +0100
2465+++ hardening-patch-4.4.2-0.4.11/ext/standard/html.c 2006-05-13 18:01:56.000000000 +0200
2466@@ -18,7 +18,7 @@
2467 +----------------------------------------------------------------------+
2468 */
2469
2470-/* $Id: html.c,v 1.63.2.23.2.1 2006/01/01 13:46:57 sniper Exp $ */
2471+/* $Id: html.c,v 1.63.2.23.2.2 2006/02/25 21:33:06 rasmus Exp $ */
2472
2473 /*
2474 * HTML entity resources:
2475@@ -793,7 +793,7 @@
2476 enum entity_charset charset = determine_charset(hint_charset TSRMLS_CC);
2477 unsigned char replacement[15];
2478
2479- ret = estrdup(old);
2480+ ret = estrndup(old, oldlen);
2481 retlen = oldlen;
2482 if (!retlen) {
2483 goto empty_source;
2484diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.11/ext/standard/info.c
2485--- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100
2486+++ hardening-patch-4.4.2-0.4.11/ext/standard/info.c 2006-05-13 18:01:56.000000000 +0200
2487@@ -58,6 +58,23 @@
2488
2489 PHPAPI extern char *php_ini_opened_path;
2490 PHPAPI extern char *php_ini_scanned_files;
2491+
2492+static int php_info_write_wrapper(const char *str, uint str_length)
2493+{
2494+ int new_len, written;
2495+ char *elem_esc;
2496+
2497+ TSRMLS_FETCH();
2498+
2499+ elem_esc = php_escape_html_entities((char *)str, str_length, &new_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
2500+
2501+ written = php_body_write(elem_esc, new_len TSRMLS_CC);
2502+
2503+ efree(elem_esc);
2504+
2505+ return written;
2506+}
2507+
2508
2509 /* {{{ _display_module_info
2510 */
2511@@ -133,23 +150,12 @@
2512 PUTS(" => ");
2513 }
2514 if (Z_TYPE_PP(tmp) == IS_ARRAY) {
2515- zval *tmp3;
2516- MAKE_STD_ZVAL(tmp3);
2517 if (!sapi_module.phpinfo_as_text) {
2518 PUTS("<pre>");
2519- }
2520- php_start_ob_buffer(NULL, 4096, 1 TSRMLS_CC);
2521- zend_print_zval_r(*tmp, 0);
2522- php_ob_get_buffer(tmp3 TSRMLS_CC);
2523- php_end_ob_buffer(0, 0 TSRMLS_CC);
2524-
2525- elem_esc = php_info_html_esc(Z_STRVAL_P(tmp3) TSRMLS_CC);
2526- PUTS(elem_esc);
2527- efree(elem_esc);
2528- zval_ptr_dtor(&tmp3);
2529-
2530- if (!sapi_module.phpinfo_as_text) {
2531+ zend_print_zval_ex((zend_write_func_t) php_info_write_wrapper, *tmp, 0);
2532 PUTS("</pre>");
2533+ } else {
2534+ zend_print_zval_r(*tmp, 0);
2535 }
2536 } else if (Z_TYPE_PP(tmp) != IS_STRING) {
2537 tmp2 = **tmp;
2538@@ -408,7 +414,7 @@
2539
2540 if (flag & PHP_INFO_GENERAL) {
2541 char *zend_version = get_zend_version();
2542- char temp_api[9];
2543+ char temp_api[11];
2544
2545 php_uname = php_get_uname('a');
2546
2547@@ -430,11 +436,22 @@
2548 }
2549 }
2550
2551+#if HARDENING_PATCH
2552+ if (!sapi_module.phpinfo_as_text) {
2553+ 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);
2554+ } else {
2555+ char temp_ver[40];
2556+
2557+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2558+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2559+ }
2560+#else
2561 if (!sapi_module.phpinfo_as_text) {
2562 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2563 } else {
2564 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2565 }
2566+#endif
2567 php_info_print_box_end();
2568 php_info_print_table_start();
2569 php_info_print_table_row(2, "System", php_uname );
2570diff -Nura php-4.4.2/ext/standard/pack.c hardening-patch-4.4.2-0.4.11/ext/standard/pack.c
2571--- php-4.4.2/ext/standard/pack.c 2006-01-01 14:46:57.000000000 +0100
2572+++ hardening-patch-4.4.2-0.4.11/ext/standard/pack.c 2006-05-13 18:01:56.000000000 +0200
2573@@ -15,7 +15,7 @@
2574 | Author: Chris Schneider <cschneid@relog.ch> |
2575 +----------------------------------------------------------------------+
2576 */
2577-/* $Id: pack.c,v 1.40.2.7.2.4 2006/01/01 13:46:57 sniper Exp $ */
2578+/* $Id: pack.c,v 1.40.2.7.2.5 2006/01/26 15:47:31 iliaa Exp $ */
2579
2580 #include "php.h"
2581
2582@@ -693,7 +693,9 @@
2583 len = size * 2;
2584 }
2585
2586- len -= argb % 2;
2587+ if (argb > 0) {
2588+ len -= argb % 2;
2589+ }
2590
2591 buf = emalloc(len + 1);
2592
2593diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.11/ext/standard/php_standard.h
2594--- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100
2595+++ hardening-patch-4.4.2-0.4.11/ext/standard/php_standard.h 2006-05-13 18:01:56.000000000 +0200
2596@@ -28,6 +28,7 @@
2597 #include "php_mail.h"
2598 #include "md5.h"
2599 #include "sha1.h"
2600+#include "sha256.h"
2601 #include "html.h"
2602 #include "exec.h"
2603 #include "file.h"
2604diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.11/ext/standard/sha256.c
2605--- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2606+++ hardening-patch-4.4.2-0.4.11/ext/standard/sha256.c 2006-05-13 18:01:56.000000000 +0200
2607@@ -0,0 +1,398 @@
2608+/*
2609+ +----------------------------------------------------------------------+
2610+ | PHP Version 5 |
2611+ +----------------------------------------------------------------------+
2612+ | Copyright (c) 1997-2004 The PHP Group |
2613+ +----------------------------------------------------------------------+
2614+ | This source file is subject to version 3.0 of the PHP license, |
2615+ | that is bundled with this package in the file LICENSE, and is |
2616+ | available through the world-wide-web at the following url: |
2617+ | http://www.php.net/license/3_0.txt. |
2618+ | If you did not receive a copy of the PHP license and are unable to |
2619+ | obtain it through the world-wide-web, please send a note to |
2620+ | license@php.net so we can mail you a copy immediately. |
2621+ +----------------------------------------------------------------------+
2622+ | Author: Stefan Esser <sesser@php.net> |
2623+ +----------------------------------------------------------------------+
2624+*/
2625+
2626+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2627+
2628+#include <stdio.h>
2629+#include "php.h"
2630+
2631+/* This code is heavily based on the PHP md5/sha1 implementations */
2632+
2633+#include "sha256.h"
2634+
2635+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2636+{
2637+ int i;
2638+
2639+ for (i = 0; i < 32; i++) {
2640+ sprintf(sha256str, "%02x", digest[i]);
2641+ sha256str += 2;
2642+ }
2643+
2644+ *sha256str = '\0';
2645+}
2646+
2647+/* {{{ proto string sha256(string str [, bool raw_output])
2648+ Calculate the sha256 hash of a string */
2649+PHP_FUNCTION(sha256)
2650+{
2651+ char *arg;
2652+ int arg_len;
2653+ zend_bool raw_output = 0;
2654+ char sha256str[65];
2655+ PHP_SHA256_CTX context;
2656+ unsigned char digest[32];
2657+
2658+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2659+ return;
2660+ }
2661+
2662+ sha256str[0] = '\0';
2663+ PHP_SHA256Init(&context);
2664+ PHP_SHA256Update(&context, arg, arg_len);
2665+ PHP_SHA256Final(digest, &context);
2666+ if (raw_output) {
2667+ RETURN_STRINGL(digest, 32, 1);
2668+ } else {
2669+ make_sha256_digest(sha256str, digest);
2670+ RETVAL_STRING(sha256str, 1);
2671+ }
2672+
2673+}
2674+
2675+/* }}} */
2676+
2677+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2678+ Calculate the sha256 hash of given filename */
2679+PHP_FUNCTION(sha256_file)
2680+{
2681+ char *arg;
2682+ int arg_len;
2683+ zend_bool raw_output = 0;
2684+ char sha256str[65];
2685+ unsigned char buf[1024];
2686+ unsigned char digest[32];
2687+ PHP_SHA256_CTX context;
2688+ int n;
2689+ FILE *fp;
2690+
2691+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2692+ return;
2693+ }
2694+
2695+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2696+ RETURN_FALSE;
2697+ }
2698+
2699+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2700+ RETURN_FALSE;
2701+ }
2702+
2703+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2704+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2705+ RETURN_FALSE;
2706+ }
2707+
2708+ PHP_SHA256Init(&context);
2709+
2710+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2711+ PHP_SHA256Update(&context, buf, n);
2712+ }
2713+
2714+ PHP_SHA256Final(digest, &context);
2715+
2716+ if (ferror(fp)) {
2717+ fclose(fp);
2718+ RETURN_FALSE;
2719+ }
2720+
2721+ fclose(fp);
2722+
2723+ if (raw_output) {
2724+ RETURN_STRINGL(digest, 32, 1);
2725+ } else {
2726+ make_sha256_digest(sha256str, digest);
2727+ RETVAL_STRING(sha256str, 1);
2728+ }
2729+}
2730+/* }}} */
2731+
2732+
2733+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2734+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2735+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2736+
2737+static unsigned char PADDING[64] =
2738+{
2739+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2740+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2741+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2742+};
2743+
2744+/* F, G, H and I are basic SHA256 functions.
2745+ */
2746+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2747+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2748+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2749+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2750+
2751+/* ROTATE_RIGHT rotates x right n bits.
2752+ */
2753+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2754+
2755+/* W[i]
2756+ */
2757+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2758+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2759+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2760+
2761+/* ROUND function of sha256
2762+ */
2763+
2764+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2765+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2766+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2767+ (d) += t1; \
2768+ }
2769+
2770+
2771+/* {{{ PHP_SHA256Init
2772+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2773+ */
2774+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2775+{
2776+ context->count[0] = context->count[1] = 0;
2777+ /* Load magic initialization constants.
2778+ */
2779+ context->state[0] = 0x6a09e667;
2780+ context->state[1] = 0xbb67ae85;
2781+ context->state[2] = 0x3c6ef372;
2782+ context->state[3] = 0xa54ff53a;
2783+ context->state[4] = 0x510e527f;
2784+ context->state[5] = 0x9b05688c;
2785+ context->state[6] = 0x1f83d9ab;
2786+ context->state[7] = 0x5be0cd19;
2787+}
2788+/* }}} */
2789+
2790+/* {{{ PHP_SHA256Update
2791+ SHA256 block update operation. Continues an SHA256 message-digest
2792+ operation, processing another message block, and updating the
2793+ context.
2794+ */
2795+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2796+ unsigned int inputLen)
2797+{
2798+ unsigned int i, index, partLen;
2799+
2800+ /* Compute number of bytes mod 64 */
2801+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2802+
2803+ /* Update number of bits */
2804+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2805+ < ((php_uint32) inputLen << 3))
2806+ context->count[1]++;
2807+ context->count[1] += ((php_uint32) inputLen >> 29);
2808+
2809+ partLen = 64 - index;
2810+
2811+ /* Transform as many times as possible.
2812+ */
2813+ if (inputLen >= partLen) {
2814+ memcpy
2815+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2816+ SHA256Transform(context->state, context->buffer);
2817+
2818+ for (i = partLen; i + 63 < inputLen; i += 64)
2819+ SHA256Transform(context->state, &input[i]);
2820+
2821+ index = 0;
2822+ } else
2823+ i = 0;
2824+
2825+ /* Buffer remaining input */
2826+ memcpy
2827+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2828+ inputLen - i);
2829+}
2830+/* }}} */
2831+
2832+/* {{{ PHP_SHA256Final
2833+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2834+ the message digest and zeroizing the context.
2835+ */
2836+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2837+{
2838+ unsigned char bits[8];
2839+ unsigned int index, padLen;
2840+
2841+ /* Save number of bits */
2842+ bits[7] = context->count[0] & 0xFF;
2843+ bits[6] = (context->count[0] >> 8) & 0xFF;
2844+ bits[5] = (context->count[0] >> 16) & 0xFF;
2845+ bits[4] = (context->count[0] >> 24) & 0xFF;
2846+ bits[3] = context->count[1] & 0xFF;
2847+ bits[2] = (context->count[1] >> 8) & 0xFF;
2848+ bits[1] = (context->count[1] >> 16) & 0xFF;
2849+ bits[0] = (context->count[1] >> 24) & 0xFF;
2850+
2851+ /* Pad out to 56 mod 64.
2852+ */
2853+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2854+ padLen = (index < 56) ? (56 - index) : (120 - index);
2855+ PHP_SHA256Update(context, PADDING, padLen);
2856+
2857+ /* Append length (before padding) */
2858+ PHP_SHA256Update(context, bits, 8);
2859+
2860+ /* Store state in digest */
2861+ SHA256Encode(digest, context->state, 32);
2862+
2863+ /* Zeroize sensitive information.
2864+ */
2865+ memset((unsigned char*) context, 0, sizeof(*context));
2866+}
2867+/* }}} */
2868+
2869+/* {{{ SHA256Transform
2870+ * SHA256 basic transformation. Transforms state based on block.
2871+ */
2872+static void SHA256Transform(state, block)
2873+php_uint32 state[8];
2874+const unsigned char block[64];
2875+{
2876+ php_uint32 a = state[0], b = state[1], c = state[2];
2877+ php_uint32 d = state[3], e = state[4], f = state[5];
2878+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2879+
2880+ SHA256Decode(x, block, 64);
2881+
2882+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2883+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2884+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2885+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2886+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2887+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2888+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2889+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2890+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2891+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2892+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2893+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2894+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2895+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2896+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2897+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2898+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2899+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2900+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2901+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2902+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2903+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2904+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2905+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2906+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2907+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2908+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2909+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2910+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2911+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2912+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2913+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2914+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2915+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2916+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2917+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2918+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2919+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2920+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2921+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2922+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2923+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2924+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2925+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2926+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2927+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2928+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2929+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2930+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2931+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2932+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2933+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2934+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2935+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2936+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2937+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2938+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2939+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2940+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2941+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2942+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2943+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2944+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2945+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2946+
2947+ state[0] += a;
2948+ state[1] += b;
2949+ state[2] += c;
2950+ state[3] += d;
2951+ state[4] += e;
2952+ state[5] += f;
2953+ state[6] += g;
2954+ state[7] += h;
2955+
2956+ /* Zeroize sensitive information. */
2957+ memset((unsigned char*) x, 0, sizeof(x));
2958+}
2959+/* }}} */
2960+
2961+/* {{{ SHA256Encode
2962+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2963+ a multiple of 4.
2964+ */
2965+static void SHA256Encode(output, input, len)
2966+unsigned char *output;
2967+php_uint32 *input;
2968+unsigned int len;
2969+{
2970+ unsigned int i, j;
2971+
2972+ for (i = 0, j = 0; j < len; i++, j += 4) {
2973+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2974+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2975+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2976+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2977+ }
2978+}
2979+/* }}} */
2980+
2981+/* {{{ SHA256Decode
2982+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2983+ a multiple of 4.
2984+ */
2985+static void SHA256Decode(output, input, len)
2986+php_uint32 *output;
2987+const unsigned char *input;
2988+unsigned int len;
2989+{
2990+ unsigned int i, j;
2991+
2992+ for (i = 0, j = 0; j < len; i++, j += 4)
2993+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2994+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2995+}
2996+/* }}} */
2997+
2998+/*
2999+ * Local variables:
3000+ * tab-width: 4
3001+ * c-basic-offset: 4
3002+ * End:
3003+ * vim600: sw=4 ts=4 fdm=marker
3004+ * vim<600: sw=4 ts=4
3005+ */
3006diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.11/ext/standard/sha256.h
3007--- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
3008+++ hardening-patch-4.4.2-0.4.11/ext/standard/sha256.h 2006-05-13 18:01:56.000000000 +0200
3009@@ -0,0 +1,40 @@
3010+/*
3011+ +----------------------------------------------------------------------+
3012+ | PHP Version 5 |
3013+ +----------------------------------------------------------------------+
3014+ | Copyright (c) 1997-2004 The PHP Group |
3015+ +----------------------------------------------------------------------+
3016+ | This source file is subject to version 3.0 of the PHP license, |
3017+ | that is bundled with this package in the file LICENSE, and is |
3018+ | available through the world-wide-web at the following url: |
3019+ | http://www.php.net/license/3_0.txt. |
3020+ | If you did not receive a copy of the PHP license and are unable to |
3021+ | obtain it through the world-wide-web, please send a note to |
3022+ | license@php.net so we can mail you a copy immediately. |
3023+ +----------------------------------------------------------------------+
3024+ | Author: Stefan Esser <sesser@php.net> |
3025+ +----------------------------------------------------------------------+
3026+*/
3027+
3028+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
3029+
3030+#ifndef SHA256_H
3031+#define SHA256_H
3032+
3033+#include "ext/standard/basic_functions.h"
3034+
3035+/* SHA1 context. */
3036+typedef struct {
3037+ php_uint32 state[8]; /* state (ABCD) */
3038+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
3039+ unsigned char buffer[64]; /* input buffer */
3040+} PHP_SHA256_CTX;
3041+
3042+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
3043+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
3044+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
3045+
3046+PHP_FUNCTION(sha256);
3047+PHP_FUNCTION(sha256_file);
3048+
3049+#endif
3050diff -Nura php-4.4.2/ext/standard/string.c hardening-patch-4.4.2-0.4.11/ext/standard/string.c
3051--- php-4.4.2/ext/standard/string.c 2006-01-01 14:46:58.000000000 +0100
3052+++ hardening-patch-4.4.2-0.4.11/ext/standard/string.c 2006-05-13 18:01:56.000000000 +0200
3053@@ -18,7 +18,7 @@
3054 +----------------------------------------------------------------------+
3055 */
3056
3057-/* $Id: string.c,v 1.333.2.52.2.3 2006/01/01 13:46:58 sniper Exp $ */
3058+/* $Id: string.c,v 1.333.2.52.2.4 2006/03/13 14:41:27 iliaa Exp $ */
3059
3060 /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */
3061
3062@@ -672,15 +672,13 @@
3063 /* Multiple character line break or forced cut */
3064 if (linelength > 0) {
3065 chk = (int)(textlen/linelength + 1);
3066+ newtext = safe_emalloc(chk, breakcharlen, textlen + 1);
3067 alloced = textlen + chk * breakcharlen + 1;
3068 } else {
3069 chk = textlen;
3070+ newtext = safe_emalloc(textlen, (breakcharlen + 1), 1);
3071 alloced = textlen * (breakcharlen + 1) + 1;
3072 }
3073- if (alloced <= 0) {
3074- RETURN_FALSE;
3075- }
3076- newtext = emalloc(alloced);
3077
3078 /* now keep track of the actual new text length */
3079 newtextlen = 0;
3080diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.11/ext/standard/syslog.c
3081--- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100
3082+++ hardening-patch-4.4.2-0.4.11/ext/standard/syslog.c 2006-05-13 18:01:56.000000000 +0200
3083@@ -42,6 +42,8 @@
3084 */
3085 PHP_MINIT_FUNCTION(syslog)
3086 {
3087+
3088+#if !HARDENING_PATCH
3089 /* error levels */
3090 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
3091 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
3092@@ -97,7 +99,7 @@
3093 /* AIX doesn't have LOG_PERROR */
3094 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
3095 #endif
3096-
3097+#endif
3098 return SUCCESS;
3099 }
3100 /* }}} */
3101diff -Nura php-4.4.2/ext/standard/url.c hardening-patch-4.4.2-0.4.11/ext/standard/url.c
3102--- php-4.4.2/ext/standard/url.c 2006-01-01 14:46:58.000000000 +0100
3103+++ hardening-patch-4.4.2-0.4.11/ext/standard/url.c 2006-05-13 18:01:56.000000000 +0200
3104@@ -15,7 +15,7 @@
3105 | Author: Jim Winstead <jimw@php.net> |
3106 +----------------------------------------------------------------------+
3107 */
3108-/* $Id: url.c,v 1.58.2.21.2.2 2006/01/01 13:46:58 sniper Exp $ */
3109+/* $Id: url.c,v 1.58.2.21.2.3 2006/02/12 16:43:03 iliaa Exp $ */
3110
3111 #include <stdlib.h>
3112 #include <string.h>
3113@@ -137,7 +137,7 @@
3114 p++;
3115 }
3116
3117- if ((*p) == '\0' || *p == '/') {
3118+ if ((*p == '\0' || *p == '/') && (p - e) < 7) {
3119 goto parse_port;
3120 }
3121
3122diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.11/ext/varfilter/config.m4
3123--- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
3124+++ hardening-patch-4.4.2-0.4.11/ext/varfilter/config.m4 2006-05-13 18:01:56.000000000 +0200
3125@@ -0,0 +1,11 @@
3126+dnl
3127+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
3128+dnl
3129+
3130+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
3131+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
3132+
3133+if test "$PHP_VARFILTER" != "no"; then
3134+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
3135+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
3136+fi
3137diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.11/ext/varfilter/CREDITS
3138--- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
3139+++ hardening-patch-4.4.2-0.4.11/ext/varfilter/CREDITS 2006-05-13 18:01:56.000000000 +0200
3140@@ -0,0 +1,2 @@
3141+varfilter
3142+Stefan Esser
3143\ Kein Zeilenumbruch am Dateiende.
3144diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.11/ext/varfilter/php_varfilter.h
3145--- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
3146+++ hardening-patch-4.4.2-0.4.11/ext/varfilter/php_varfilter.h 2006-05-13 18:01:56.000000000 +0200
3147@@ -0,0 +1,144 @@
3148+/*
3149+ +----------------------------------------------------------------------+
3150+ | Hardened-PHP Project's varfilter extension |
3151+ +----------------------------------------------------------------------+
3152+ | Copyright (c) 2004-2005 Stefan Esser |
3153+ +----------------------------------------------------------------------+
3154+ | This source file is subject to version 2.02 of the PHP license, |
3155+ | that is bundled with this package in the file LICENSE, and is |
3156+ | available at through the world-wide-web at |
3157+ | http://www.php.net/license/2_02.txt. |
3158+ | If you did not receive a copy of the PHP license and are unable to |
3159+ | obtain it through the world-wide-web, please send a note to |
3160+ | license@php.net so we can mail you a copy immediately. |
3161+ +----------------------------------------------------------------------+
3162+ | Author: Stefan Esser <sesser@hardened-php.net> |
3163+ +----------------------------------------------------------------------+
3164+
3165+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
3166+*/
3167+
3168+#ifndef PHP_VARFILTER_H
3169+#define PHP_VARFILTER_H
3170+
3171+extern zend_module_entry varfilter_module_entry;
3172+#define phpext_varfilter_ptr &varfilter_module_entry
3173+
3174+#ifdef PHP_WIN32
3175+#define PHP_VARFILTER_API __declspec(dllexport)
3176+#else
3177+#define PHP_VARFILTER_API
3178+#endif
3179+
3180+#ifdef ZTS
3181+#include "TSRM.h"
3182+#endif
3183+
3184+#include "SAPI.h"
3185+
3186+#include "php_variables.h"
3187+
3188+#ifdef ZEND_ENGINE_2
3189+#define HASH_HTTP_GET_VARS 0x2095733f
3190+#define HASH_HTTP_POST_VARS 0xbfee1265
3191+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
3192+#define HASH_HTTP_ENV_VARS 0x1fe186a8
3193+#define HASH_HTTP_SERVER_VARS 0xc987afd6
3194+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
3195+#define HASH_HTTP_POST_FILES 0x98eb1ddc
3196+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
3197+#else
3198+#define HASH_HTTP_GET_VARS 0x8d8645bd
3199+#define HASH_HTTP_POST_VARS 0x7c699bf3
3200+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
3201+#define HASH_HTTP_ENV_VARS 0x84da3016
3202+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
3203+#define HASH_HTTP_SESSION_VARS 0x322906f5
3204+#define HASH_HTTP_POST_FILES 0xe4e4ce70
3205+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
3206+#endif
3207+
3208+PHP_MINIT_FUNCTION(varfilter);
3209+PHP_MSHUTDOWN_FUNCTION(varfilter);
3210+PHP_RINIT_FUNCTION(varfilter);
3211+PHP_RSHUTDOWN_FUNCTION(varfilter);
3212+PHP_MINFO_FUNCTION(varfilter);
3213+
3214+
3215+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3216+/* request variables */
3217+ long max_request_variables;
3218+ long cur_request_variables;
3219+ long max_varname_length;
3220+ long max_totalname_length;
3221+ long max_value_length;
3222+ long max_array_depth;
3223+ long max_array_index_length;
3224+ zend_bool disallow_nul;
3225+/* cookie variables */
3226+ long max_cookie_vars;
3227+ long cur_cookie_vars;
3228+ long max_cookie_name_length;
3229+ long max_cookie_totalname_length;
3230+ long max_cookie_value_length;
3231+ long max_cookie_array_depth;
3232+ long max_cookie_array_index_length;
3233+ zend_bool disallow_cookie_nul;
3234+/* get variables */
3235+ long max_get_vars;
3236+ long cur_get_vars;
3237+ long max_get_name_length;
3238+ long max_get_totalname_length;
3239+ long max_get_value_length;
3240+ long max_get_array_depth;
3241+ long max_get_array_index_length;
3242+ zend_bool disallow_get_nul;
3243+/* post variables */
3244+ long max_post_vars;
3245+ long cur_post_vars;
3246+ long max_post_name_length;
3247+ long max_post_totalname_length;
3248+ long max_post_value_length;
3249+ long max_post_array_depth;
3250+ long max_post_array_index_length;
3251+ zend_bool disallow_post_nul;
3252+/* fileupload */
3253+ long max_uploads;
3254+ long cur_uploads;
3255+ zend_bool disallow_elf_files;
3256+ char *verification_script;
3257+
3258+ zend_bool no_more_variables;
3259+ zend_bool no_more_get_variables;
3260+ zend_bool no_more_post_variables;
3261+ zend_bool no_more_cookie_variables;
3262+ zend_bool no_more_uploads;
3263+
3264+ZEND_END_MODULE_GLOBALS(varfilter)
3265+
3266+
3267+#ifdef ZTS
3268+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3269+#else
3270+#define VARFILTER_G(v) (varfilter_globals.v)
3271+#endif
3272+
3273+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3274+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3275+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3276+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3277+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3278+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3279+
3280+
3281+
3282+#endif /* PHP_VARFILTER_H */
3283+
3284+
3285+/*
3286+ * Local variables:
3287+ * tab-width: 4
3288+ * c-basic-offset: 4
3289+ * indent-tabs-mode: t
3290+ * End:
3291+ */
3292diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.11/ext/varfilter/varfilter.c
3293--- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3294+++ hardening-patch-4.4.2-0.4.11/ext/varfilter/varfilter.c 2006-05-13 18:02:25.000000000 +0200
3295@@ -0,0 +1,915 @@
3296+/*
3297+ +----------------------------------------------------------------------+
3298+ | Hardened-PHP Project's varfilter extension |
3299+ +----------------------------------------------------------------------+
3300+ | Copyright (c) 2004-2005 Stefan Esser |
3301+ +----------------------------------------------------------------------+
3302+ | This source file is subject to version 2.02 of the PHP license, |
3303+ | that is bundled with this package in the file LICENSE, and is |
3304+ | available at through the world-wide-web at |
3305+ | http://www.php.net/license/2_02.txt. |
3306+ | If you did not receive a copy of the PHP license and are unable to |
3307+ | obtain it through the world-wide-web, please send a note to |
3308+ | license@php.net so we can mail you a copy immediately. |
3309+ +----------------------------------------------------------------------+
3310+ | Author: Stefan Esser <sesser@hardened-php.net> |
3311+ +----------------------------------------------------------------------+
3312+
3313+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3314+*/
3315+
3316+#ifdef HAVE_CONFIG_H
3317+#include "config.h"
3318+#endif
3319+
3320+#include "php.h"
3321+#include "php_ini.h"
3322+#include "ext/standard/info.h"
3323+#include "php_varfilter.h"
3324+#include "hardening_patch.h"
3325+
3326+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3327+
3328+/* True global resources - no need for thread safety here */
3329+static int le_varfilter;
3330+
3331+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3332+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3333+static zend_bool hooked = 0;
3334+
3335+/* {{{ varfilter_module_entry
3336+ */
3337+zend_module_entry varfilter_module_entry = {
3338+#if ZEND_MODULE_API_NO >= 20010901
3339+ STANDARD_MODULE_HEADER,
3340+#endif
3341+ "varfilter",
3342+ NULL,
3343+ PHP_MINIT(varfilter),
3344+ PHP_MSHUTDOWN(varfilter),
3345+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3346+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3347+ PHP_MINFO(varfilter),
3348+#if ZEND_MODULE_API_NO >= 20010901
3349+ "0.4.11", /* Replace with version number for your extension */
3350+#endif
3351+ STANDARD_MODULE_PROPERTIES
3352+};
3353+/* }}} */
3354+
3355+#ifdef COMPILE_DL_VARFILTER
3356+ZEND_GET_MODULE(varfilter)
3357+#endif
3358+
3359+/* {{{ PHP_INI
3360+ */
3361+PHP_INI_BEGIN()
3362+ /* for backward compatibility */
3363+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3364+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3365+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3366+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3367+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3368+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3369+
3370+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3371+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3372+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3373+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3374+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3375+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3376+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3377+
3378+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3379+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3380+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3381+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3382+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3383+ 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)
3384+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3385+
3386+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3387+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3388+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3389+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3390+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3391+ 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)
3392+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3393+
3394+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3395+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3396+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3397+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3398+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3399+ 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)
3400+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3401+
3402+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3403+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3404+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3405+
3406+
3407+PHP_INI_END()
3408+/* }}} */
3409+
3410+/* {{{ php_varfilter_init_globals
3411+ */
3412+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3413+{
3414+ varfilter_globals->max_request_variables = 200;
3415+ varfilter_globals->max_varname_length = 64;
3416+ varfilter_globals->max_value_length = 10000;
3417+ varfilter_globals->max_array_depth = 100;
3418+ varfilter_globals->max_totalname_length = 256;
3419+ varfilter_globals->max_array_index_length = 64;
3420+ varfilter_globals->disallow_nul = 1;
3421+
3422+ varfilter_globals->max_cookie_vars = 100;
3423+ varfilter_globals->max_cookie_name_length = 64;
3424+ varfilter_globals->max_cookie_totalname_length = 256;
3425+ varfilter_globals->max_cookie_value_length = 10000;
3426+ varfilter_globals->max_cookie_array_depth = 100;
3427+ varfilter_globals->max_cookie_array_index_length = 64;
3428+ varfilter_globals->disallow_cookie_nul = 1;
3429+
3430+ varfilter_globals->max_get_vars = 100;
3431+ varfilter_globals->max_get_name_length = 64;
3432+ varfilter_globals->max_get_totalname_length = 256;
3433+ varfilter_globals->max_get_value_length = 512;
3434+ varfilter_globals->max_get_array_depth = 50;
3435+ varfilter_globals->max_get_array_index_length = 64;
3436+ varfilter_globals->disallow_get_nul = 1;
3437+
3438+ varfilter_globals->max_post_vars = 200;
3439+ varfilter_globals->max_post_name_length = 64;
3440+ varfilter_globals->max_post_totalname_length = 256;
3441+ varfilter_globals->max_post_value_length = 65000;
3442+ varfilter_globals->max_post_array_depth = 100;
3443+ varfilter_globals->max_post_array_index_length = 64;
3444+ varfilter_globals->disallow_post_nul = 1;
3445+
3446+ varfilter_globals->max_uploads = 25;
3447+ varfilter_globals->disallow_elf_files = 1;
3448+ varfilter_globals->verification_script = NULL;
3449+
3450+ varfilter_globals->no_more_variables = 0;
3451+ varfilter_globals->no_more_get_variables = 0;
3452+ varfilter_globals->no_more_post_variables = 0;
3453+ varfilter_globals->no_more_cookie_variables = 0;
3454+ varfilter_globals->no_more_uploads = 0;
3455+
3456+ varfilter_globals->cur_request_variables = 0;
3457+ varfilter_globals->cur_get_vars = 0;
3458+ varfilter_globals->cur_post_vars = 0;
3459+ varfilter_globals->cur_cookie_vars = 0;
3460+
3461+ varfilter_globals->cur_uploads = 0;
3462+
3463+}
3464+/* }}} */
3465+
3466+
3467+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3468+{
3469+ HashTable *svars;
3470+ int retval, failure=0;
3471+
3472+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3473+
3474+ svars = Z_ARRVAL_P(track_vars_array);
3475+
3476+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3477+ if (retval == SUCCESS) failure = 1;
3478+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3479+ if (retval == SUCCESS) failure = 1;
3480+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3481+ if (retval == SUCCESS) failure = 1;
3482+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3483+ if (retval == SUCCESS) failure = 1;
3484+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3485+ if (retval == SUCCESS) failure = 1;
3486+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3487+ if (retval == SUCCESS) failure = 1;
3488+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3489+ if (retval == SUCCESS) failure = 1;
3490+ 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);
3491+ if (retval == SUCCESS) failure = 1;
3492+
3493+ if (failure) {
3494+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3495+ }
3496+}
3497+
3498+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3499+{
3500+ int retval = SAPI_HEADER_ADD, i;
3501+ char *tmp;
3502+
3503+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3504+
3505+ tmp = sapi_header->header;
3506+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3507+ if (tmp[0] == 0) {
3508+ char *fname = get_active_function_name(TSRMLS_C);
3509+
3510+ if (!fname) {
3511+ fname = "unknown";
3512+ }
3513+
3514+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3515+ sapi_header->header_len = i;
3516+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3517+ char *fname = get_active_function_name(TSRMLS_C);
3518+
3519+ if (!fname) {
3520+ fname = "unknown";
3521+ }
3522+
3523+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3524+ sapi_header->header_len = i;
3525+ tmp[0] = 0;
3526+ }
3527+ }
3528+ }
3529+
3530+ if (orig_header_handler) {
3531+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3532+ }
3533+
3534+ return retval;
3535+}
3536+
3537+/* {{{ PHP_MINIT_FUNCTION
3538+ */
3539+PHP_MINIT_FUNCTION(varfilter)
3540+{
3541+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3542+ REGISTER_INI_ENTRIES();
3543+
3544+ if (!hooked) {
3545+ void *temp;
3546+ hooked = 1;
3547+
3548+ temp = (void *)sapi_module.register_server_variables;
3549+ if (temp != varfilter_register_server_variables) {
3550+ orig_register_server_variables = temp;
3551+ }
3552+ temp = (void *)sapi_module.header_handler;
3553+ if (temp != varfilter_header_handler) {
3554+ orig_header_handler = temp;
3555+ }
3556+ }
3557+
3558+ sapi_register_input_filter(varfilter_input_filter);
3559+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3560+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3561+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3562+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3563+
3564+ sapi_module.header_handler = varfilter_header_handler;
3565+ sapi_module.register_server_variables = varfilter_register_server_variables;
3566+
3567+
3568+ return SUCCESS;
3569+}
3570+/* }}} */
3571+
3572+/* {{{ PHP_MSHUTDOWN_FUNCTION
3573+ */
3574+PHP_MSHUTDOWN_FUNCTION(varfilter)
3575+{
3576+ UNREGISTER_INI_ENTRIES();
3577+
3578+ return SUCCESS;
3579+}
3580+/* }}} */
3581+
3582+/* Remove if there's nothing to do at request start */
3583+/* {{{ PHP_RINIT_FUNCTION
3584+ */
3585+PHP_RINIT_FUNCTION(varfilter)
3586+{
3587+ VARFILTER_G(cur_request_variables) = 0;
3588+ VARFILTER_G(cur_get_vars) = 0;
3589+ VARFILTER_G(cur_post_vars) = 0;
3590+ VARFILTER_G(cur_cookie_vars) = 0;
3591+
3592+ VARFILTER_G(cur_uploads) = 0;
3593+
3594+ VARFILTER_G(no_more_variables) = 0;
3595+ VARFILTER_G(no_more_get_variables) = 0;
3596+ VARFILTER_G(no_more_post_variables) = 0;
3597+ VARFILTER_G(no_more_cookie_variables) = 0;
3598+ VARFILTER_G(no_more_uploads) = 0;
3599+
3600+ return SUCCESS;
3601+}
3602+/* }}} */
3603+
3604+/* Remove if there's nothing to do at request end */
3605+/* {{{ PHP_RSHUTDOWN_FUNCTION
3606+ */
3607+PHP_RSHUTDOWN_FUNCTION(varfilter)
3608+{
3609+ return SUCCESS;
3610+}
3611+/* }}} */
3612+
3613+/* {{{ PHP_MINFO_FUNCTION
3614+ */
3615+PHP_MINFO_FUNCTION(varfilter)
3616+{
3617+ php_info_print_table_start();
3618+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3619+ php_info_print_table_end();
3620+
3621+ DISPLAY_INI_ENTRIES();
3622+}
3623+/* }}} */
3624+
3625+/* {{{ normalize_varname
3626+ */
3627+static void normalize_varname(char *varname)
3628+{
3629+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3630+
3631+ /* overjump leading space */
3632+ while (*s == ' ') {
3633+ s++;
3634+ }
3635+
3636+ /* and remove it */
3637+ if (s != varname) {
3638+ memmove(varname, s, strlen(s)+1);
3639+ }
3640+
3641+ for (p=varname; *p && *p != '['; p++) {
3642+ switch(*p) {
3643+ case ' ':
3644+ case '.':
3645+ *p='_';
3646+ break;
3647+ }
3648+ }
3649+
3650+ /* find index */
3651+ index = strchr(varname, '[');
3652+ if (index) {
3653+ index++;
3654+ s=index;
3655+ } else {
3656+ return;
3657+ }
3658+
3659+ /* done? */
3660+ while (index) {
3661+
3662+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3663+ index++;
3664+ }
3665+ indexend = strchr(index, ']');
3666+ indexend = indexend ? indexend + 1 : index + strlen(index);
3667+
3668+ if (s != index) {
3669+ memmove(s, index, strlen(index)+1);
3670+ s += indexend-index;
3671+ } else {
3672+ s = indexend;
3673+ }
3674+
3675+ if (*s == '[') {
3676+ s++;
3677+ index = s;
3678+ } else {
3679+ index = NULL;
3680+ }
3681+ }
3682+ *s++='\0';
3683+}
3684+/* }}} */
3685+
3686+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3687+ */
3688+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3689+{
3690+ char *index, *prev_index = NULL, *var;
3691+ unsigned int var_len, total_len, depth = 0;
3692+
3693+ var = estrdup(varname);
3694+
3695+ /* Normalize the variable name */
3696+ normalize_varname(var);
3697+
3698+ /* Find length of variable name */
3699+ index = strchr(var, '[');
3700+ total_len = strlen(var);
3701+ var_len = index ? index-var : total_len;
3702+
3703+ /* Drop this variable if it exceeds the varname/total length limit */
3704+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3705+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3706+ goto return_failure;
3707+ }
3708+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3709+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3710+ goto return_failure;
3711+ }
3712+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3713+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3714+
3715+ goto return_failure;
3716+ }
3717+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3718+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3719+ goto return_failure;
3720+ }
3721+
3722+ /* Find out array depth */
3723+ while (index) {
3724+ unsigned int index_length;
3725+
3726+ depth++;
3727+ index = strchr(index+1, '[');
3728+
3729+ if (prev_index) {
3730+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3731+
3732+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3733+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3734+ goto return_failure;
3735+ }
3736+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3737+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3738+ goto return_failure;
3739+ }
3740+ prev_index = index;
3741+ }
3742+
3743+ }
3744+
3745+ /* Drop this variable if it exceeds the array depth limit */
3746+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3747+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3748+ goto return_failure;
3749+ }
3750+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3751+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3752+ goto return_failure;
3753+ }
3754+
3755+
3756+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3757+ /* This is to protect several silly scripts that do globalizing themself */
3758+
3759+ switch (var_len) {
3760+ case 18:
3761+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3762+ break;
3763+ case 17:
3764+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3765+ break;
3766+ case 16:
3767+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3768+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3769+ break;
3770+ case 15:
3771+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3772+ break;
3773+ case 14:
3774+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3775+ break;
3776+ case 13:
3777+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3778+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3779+ break;
3780+ case 8:
3781+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3782+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3783+ break;
3784+ case 7:
3785+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3786+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3787+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3788+ break;
3789+ case 6:
3790+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3791+ break;
3792+ case 5:
3793+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3794+ break;
3795+ case 4:
3796+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3797+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3798+ break;
3799+ }
3800+
3801+ efree(var);
3802+ return SUCCESS;
3803+protected_varname2:
3804+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3805+return_failure:
3806+ efree(var);
3807+ return FAILURE;
3808+}
3809+/* }}} */
3810+
3811+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3812+ */
3813+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3814+{
3815+ /* Drop if no more variables flag is set */
3816+ if (VARFILTER_G(no_more_uploads)) {
3817+ return FAILURE;
3818+ }
3819+ /* Drop this fileupload if the limit is reached */
3820+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3821+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3822+ VARFILTER_G(no_more_uploads) = 1;
3823+ return FAILURE;
3824+ }
3825+
3826+ return SUCCESS;
3827+}
3828+/* }}} */
3829+
3830+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3831+ */
3832+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3833+{
3834+
3835+ if (VARFILTER_G(disallow_elf_files)) {
3836+
3837+ if (offset == 0 && buffer_len > 10) {
3838+
3839+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3840+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3841+ return FAILURE;
3842+ }
3843+ }
3844+
3845+ }
3846+
3847+ return SUCCESS;
3848+}
3849+/* }}} */
3850+
3851+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3852+ */
3853+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3854+{
3855+ int retval = SUCCESS;
3856+
3857+ if (VARFILTER_G(verification_script)) {
3858+ char cmd[8192];
3859+ FILE *in;
3860+ int first=1;
3861+
3862+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3863+
3864+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3865+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3866+ return FAILURE;
3867+ }
3868+
3869+ retval = FAILURE;
3870+
3871+ /* read and forget the result */
3872+ while (1) {
3873+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3874+ if (readbytes<=0) {
3875+ break;
3876+ }
3877+ if (first) {
3878+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3879+ first = 0;
3880+ }
3881+ }
3882+ pclose(in);
3883+ }
3884+
3885+ if (retval != SUCCESS) {
3886+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3887+ return FAILURE;
3888+ }
3889+
3890+ VARFILTER_G(cur_uploads)++;
3891+ return SUCCESS;
3892+}
3893+/* }}} */
3894+
3895+/* {{{ SAPI_INPUT_FILTER_FUNC
3896+ */
3897+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3898+{
3899+ char *index, *prev_index = NULL;
3900+ unsigned int var_len, total_len, depth = 0;
3901+
3902+ /* Drop this variable if the limit was reached */
3903+ switch (arg) {
3904+ case PARSE_GET:
3905+ if (VARFILTER_G(no_more_get_variables)) {
3906+ return 0;
3907+ }
3908+ break;
3909+ case PARSE_POST:
3910+ if (VARFILTER_G(no_more_post_variables)) {
3911+ return 0;
3912+ }
3913+ break;
3914+ case PARSE_COOKIE:
3915+ if (VARFILTER_G(no_more_cookie_variables)) {
3916+ return 0;
3917+ }
3918+ break;
3919+ default: /* we do not want to protect parse_str() and friends */
3920+ if (new_val_len) {
3921+ *new_val_len = val_len;
3922+ }
3923+ return 1;
3924+ }
3925+ if (VARFILTER_G(no_more_variables)) {
3926+ return 0;
3927+ }
3928+
3929+ /* Drop this variable if the limit is now reached */
3930+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3931+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3932+ VARFILTER_G(no_more_variables) = 1;
3933+ return 0;
3934+ }
3935+ switch (arg) {
3936+ case PARSE_GET:
3937+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3938+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3939+ VARFILTER_G(no_more_get_variables) = 1;
3940+ return 0;
3941+ }
3942+ break;
3943+ case PARSE_COOKIE:
3944+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3945+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3946+ VARFILTER_G(no_more_cookie_variables) = 1;
3947+ return 0;
3948+ }
3949+ break;
3950+ case PARSE_POST:
3951+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3952+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3953+ VARFILTER_G(no_more_post_variables) = 1;
3954+ return 0;
3955+ }
3956+ break;
3957+ }
3958+
3959+
3960+ /* Drop this variable if it exceeds the value length limit */
3961+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3962+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3963+ return 0;
3964+ }
3965+ switch (arg) {
3966+ case PARSE_GET:
3967+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3968+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3969+ return 0;
3970+ }
3971+ break;
3972+ case PARSE_COOKIE:
3973+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3974+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3975+ return 0;
3976+ }
3977+ break;
3978+ case PARSE_POST:
3979+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3980+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3981+ return 0;
3982+ }
3983+ break;
3984+ }
3985+
3986+ /* Normalize the variable name */
3987+ normalize_varname(var);
3988+
3989+ /* Find length of variable name */
3990+ index = strchr(var, '[');
3991+ total_len = strlen(var);
3992+ var_len = index ? index-var : total_len;
3993+
3994+ /* Drop this variable if it exceeds the varname/total length limit */
3995+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3996+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3997+ return 0;
3998+ }
3999+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
4000+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
4001+ return 0;
4002+ }
4003+ switch (arg) {
4004+ case PARSE_GET:
4005+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
4006+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
4007+ return 0;
4008+ }
4009+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
4010+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
4011+ return 0;
4012+ }
4013+ break;
4014+ case PARSE_COOKIE:
4015+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
4016+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
4017+ return 0;
4018+ }
4019+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
4020+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
4021+ return 0;
4022+ }
4023+ break;
4024+ case PARSE_POST:
4025+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
4026+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
4027+ return 0;
4028+ }
4029+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
4030+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
4031+ return 0;
4032+ }
4033+ break;
4034+ }
4035+
4036+ /* Find out array depth */
4037+ while (index) {
4038+ unsigned int index_length;
4039+
4040+ depth++;
4041+ index = strchr(index+1, '[');
4042+
4043+ if (prev_index) {
4044+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
4045+
4046+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
4047+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
4048+ return 0;
4049+ }
4050+ switch (arg) {
4051+ case PARSE_GET:
4052+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
4053+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
4054+ return 0;
4055+ }
4056+ break;
4057+ case PARSE_COOKIE:
4058+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
4059+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
4060+ return 0;
4061+ }
4062+ break;
4063+ case PARSE_POST:
4064+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
4065+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
4066+ return 0;
4067+ }
4068+ break;
4069+ }
4070+ prev_index = index;
4071+ }
4072+
4073+ }
4074+
4075+ /* Drop this variable if it exceeds the array depth limit */
4076+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
4077+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
4078+ return 0;
4079+ }
4080+ switch (arg) {
4081+ case PARSE_GET:
4082+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
4083+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
4084+ return 0;
4085+ }
4086+ break;
4087+ case PARSE_COOKIE:
4088+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
4089+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
4090+ return 0;
4091+ }
4092+ break;
4093+ case PARSE_POST:
4094+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
4095+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
4096+ return 0;
4097+ }
4098+ break;
4099+ }
4100+
4101+ /* Check if variable value is truncated by a \0 */
4102+
4103+ if (val && *val && val_len != strlen(*val)) {
4104+
4105+ if (VARFILTER_G(disallow_nul)) {
4106+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
4107+ return 0;
4108+ }
4109+ switch (arg) {
4110+ case PARSE_GET:
4111+ if (VARFILTER_G(disallow_get_nul)) {
4112+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
4113+ return 0;
4114+ }
4115+ break;
4116+ case PARSE_COOKIE:
4117+ if (VARFILTER_G(disallow_cookie_nul)) {
4118+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
4119+ return 0;
4120+ }
4121+ break;
4122+ case PARSE_POST:
4123+ if (VARFILTER_G(disallow_post_nul)) {
4124+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
4125+ return 0;
4126+ }
4127+ break;
4128+ }
4129+ }
4130+
4131+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
4132+ /* This is to protect several silly scripts that do globalizing themself */
4133+
4134+ switch (var_len) {
4135+ case 18:
4136+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
4137+ break;
4138+ case 17:
4139+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
4140+ break;
4141+ case 16:
4142+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
4143+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
4144+ break;
4145+ case 15:
4146+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
4147+ break;
4148+ case 14:
4149+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
4150+ break;
4151+ case 13:
4152+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
4153+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
4154+ break;
4155+ case 8:
4156+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
4157+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
4158+ break;
4159+ case 7:
4160+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
4161+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
4162+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
4163+ break;
4164+ case 6:
4165+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
4166+ break;
4167+ case 5:
4168+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
4169+ break;
4170+ case 4:
4171+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
4172+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
4173+ break;
4174+ }
4175+
4176+ /* Okay let PHP register this variable */
4177+ VARFILTER_G(cur_request_variables)++;
4178+ switch (arg) {
4179+ case PARSE_GET:
4180+ VARFILTER_G(cur_get_vars)++;
4181+ break;
4182+ case PARSE_COOKIE:
4183+ VARFILTER_G(cur_cookie_vars)++;
4184+ break;
4185+ case PARSE_POST:
4186+ VARFILTER_G(cur_post_vars)++;
4187+ break;
4188+ }
4189+
4190+ if (new_val_len) {
4191+ *new_val_len = val_len;
4192+ }
4193+
4194+ return 1;
4195+protected_varname:
4196+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
4197+ return 0;
4198+}
4199+/* }}} */
4200+
4201+/*
4202+ * Local variables:
4203+ * tab-width: 4
4204+ * c-basic-offset: 4
4205+ * End:
4206+ * vim600: noet sw=4 ts=4 fdm=marker
4207+ * vim<600: noet sw=4 ts=4
4208+ */
4209+
4210+
4211diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.11/main/fopen_wrappers.c
4212--- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100
4213+++ hardening-patch-4.4.2-0.4.11/main/fopen_wrappers.c 2006-05-13 18:01:56.000000000 +0200
4214@@ -116,14 +116,20 @@
4215 }
4216 }
4217
4218+ resolved_name_len = strlen(resolved_name);
4219 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
4220- resolved_name_len = strlen(resolved_name);
4221 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
4222 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
4223 resolved_name[++resolved_name_len] = '\0';
4224 }
4225 }
4226
4227+ if (resolved_name_len == resolved_basedir_len - 1) {
4228+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4229+ resolved_basedir_len--;
4230+ }
4231+ }
4232+
4233 /* Check the path */
4234 #ifdef PHP_WIN32
4235 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4236@@ -156,6 +162,21 @@
4237 char *pathbuf;
4238 char *ptr;
4239 char *end;
4240+ char path_copy[MAXPATHLEN];
4241+ int path_len;
4242+
4243+ /* Special case path ends with a trailing slash */
4244+ path_len = strlen(path);
4245+ if (path_len >= MAXPATHLEN) {
4246+ errno = EPERM; /* we deny permission to open it */
4247+ return -1;
4248+ }
4249+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4250+ memcpy(path_copy, path, path_len+1);
4251+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4252+ path_copy[path_len] = '\0';
4253+ path = (const char *)&path_copy;
4254+ }
4255
4256 pathbuf = estrdup(PG(open_basedir));
4257
4258diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.11/main/hardened_globals.h
4259--- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4260+++ hardening-patch-4.4.2-0.4.11/main/hardened_globals.h 2006-05-13 18:01:56.000000000 +0200
4261@@ -0,0 +1,62 @@
4262+/*
4263+ +----------------------------------------------------------------------+
4264+ | Hardening-Patch for PHP |
4265+ +----------------------------------------------------------------------+
4266+ | Copyright (c) 2004-2005 Stefan Esser |
4267+ +----------------------------------------------------------------------+
4268+ | This source file is subject to version 2.02 of the PHP license, |
4269+ | that is bundled with this package in the file LICENSE, and is |
4270+ | available at through the world-wide-web at |
4271+ | http://www.php.net/license/2_02.txt. |
4272+ | If you did not receive a copy of the PHP license and are unable to |
4273+ | obtain it through the world-wide-web, please send a note to |
4274+ | license@php.net so we can mail you a copy immediately. |
4275+ +----------------------------------------------------------------------+
4276+ | Author: Stefan Esser <sesser@hardened-php.net> |
4277+ +----------------------------------------------------------------------+
4278+ */
4279+
4280+#ifndef HARDENED_GLOBALS_H
4281+#define HARDENED_GLOBALS_H
4282+
4283+typedef struct _hardened_globals hardened_globals_struct;
4284+
4285+#ifdef ZTS
4286+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4287+extern int hardened_globals_id;
4288+#else
4289+# define HG(v) (hardened_globals.v)
4290+extern struct _hardened_globals hardened_globals;
4291+#endif
4292+
4293+
4294+struct _hardened_globals {
4295+#if HARDENING_PATCH_MM_PROTECT
4296+ unsigned int canary_1;
4297+ unsigned int canary_2;
4298+#endif
4299+#if HARDENING_PATCH_LL_PROTECT
4300+ unsigned int canary_3;
4301+ unsigned int canary_4;
4302+ unsigned int ll_canary_inited;
4303+#endif
4304+ zend_bool hphp_sql_bailout_on_error;
4305+ zend_bool hphp_multiheader;
4306+ HashTable *eval_whitelist;
4307+ HashTable *eval_blacklist;
4308+ HashTable *func_whitelist;
4309+ HashTable *func_blacklist;
4310+ HashTable *include_whitelist;
4311+ HashTable *include_blacklist;
4312+ unsigned int dummy;
4313+};
4314+
4315+
4316+#endif /* HARDENED_GLOBALS_H */
4317+
4318+/*
4319+ * Local variables:
4320+ * tab-width: 4
4321+ * c-basic-offset: 4
4322+ * End:
4323+ */
4324diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.11/main/hardening_patch.c
4325--- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4326+++ hardening-patch-4.4.2-0.4.11/main/hardening_patch.c 2006-05-13 18:01:56.000000000 +0200
4327@@ -0,0 +1,430 @@
4328+/*
4329+ +----------------------------------------------------------------------+
4330+ | Hardening Patch for PHP |
4331+ +----------------------------------------------------------------------+
4332+ | Copyright (c) 2004-2005 Stefan Esser |
4333+ +----------------------------------------------------------------------+
4334+ | This source file is subject to version 2.02 of the PHP license, |
4335+ | that is bundled with this package in the file LICENSE, and is |
4336+ | available at through the world-wide-web at |
4337+ | http://www.php.net/license/2_02.txt. |
4338+ | If you did not receive a copy of the PHP license and are unable to |
4339+ | obtain it through the world-wide-web, please send a note to |
4340+ | license@php.net so we can mail you a copy immediately. |
4341+ +----------------------------------------------------------------------+
4342+ | Author: Stefan Esser <sesser@hardened-php.net> |
4343+ +----------------------------------------------------------------------+
4344+ */
4345+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4346+
4347+#include "php.h"
4348+
4349+#include <stdio.h>
4350+#include <stdlib.h>
4351+
4352+#if HAVE_UNISTD_H
4353+#include <unistd.h>
4354+#endif
4355+#include "SAPI.h"
4356+#include "php_globals.h"
4357+
4358+#if HARDENING_PATCH
4359+
4360+#ifdef HAVE_SYS_SOCKET_H
4361+#include <sys/socket.h>
4362+#endif
4363+
4364+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4365+#undef AF_UNIX
4366+#endif
4367+
4368+#if defined(AF_UNIX)
4369+#include <sys/un.h>
4370+#endif
4371+
4372+#define SYSLOG_PATH "/dev/log"
4373+
4374+#include "snprintf.h"
4375+
4376+#include "hardening_patch.h"
4377+
4378+#ifdef ZTS
4379+#include "hardened_globals.h"
4380+int hardened_globals_id;
4381+#else
4382+struct _hardened_globals hardened_globals;
4383+#endif
4384+
4385+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4386+{
4387+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4388+}
4389+
4390+
4391+PHPAPI void hardened_startup()
4392+{
4393+#ifdef ZTS
4394+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4395+#else
4396+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4397+#endif
4398+}
4399+
4400+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4401+{
4402+ HG(canary_1) = php_canary();
4403+ HG(canary_2) = php_canary();
4404+}
4405+
4406+char *loglevel2string(int loglevel)
4407+{
4408+ switch (loglevel) {
4409+ case S_FILES:
4410+ return "FILES";
4411+ case S_INCLUDE:
4412+ return "INCLUDE";
4413+ case S_MEMORY:
4414+ return "MEMORY";
4415+ case S_MISC:
4416+ return "MISC";
4417+ case S_SQL:
4418+ return "SQL";
4419+ case S_EXECUTOR:
4420+ return "EXECUTOR";
4421+ case S_VARS:
4422+ return "VARS";
4423+ default:
4424+ return "UNKNOWN";
4425+ }
4426+}
4427+
4428+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4429+{
4430+#if defined(AF_UNIX)
4431+ int s, r, i=0;
4432+ struct sockaddr_un saun;
4433+ char buf[4096+64];
4434+ char error[4096+100];
4435+ char *ip_address;
4436+ char *fname;
4437+ int lineno;
4438+ va_list ap;
4439+ TSRMLS_FETCH();
4440+
4441+ if (EG(hphp_log_use_x_forwarded_for)) {
4442+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4443+ if (ip_address == NULL) {
4444+ ip_address = "X-FORWARDED-FOR not set";
4445+ }
4446+ } else {
4447+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4448+ if (ip_address == NULL) {
4449+ ip_address = "REMOTE_ADDR not set";
4450+ }
4451+ }
4452+
4453+
4454+ va_start(ap, fmt);
4455+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4456+ va_end(ap);
4457+ while (error[i]) {
4458+ if (error[i] < 32) error[i] = '.';
4459+ i++;
4460+ }
4461+
4462+ if (zend_is_executing(TSRMLS_C)) {
4463+ lineno = zend_get_executed_lineno(TSRMLS_C);
4464+ fname = zend_get_executed_filename(TSRMLS_C);
4465+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4466+ } else {
4467+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4468+ if (fname==NULL) {
4469+ fname = "unknown";
4470+ }
4471+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4472+ }
4473+
4474+ /* Syslog-Logging disabled? */
4475+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4476+ goto log_sapi;
4477+ }
4478+
4479+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4480+
4481+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4482+ if (s == -1) {
4483+ goto log_sapi;
4484+ }
4485+
4486+ memset(&saun, 0, sizeof(saun));
4487+ saun.sun_family = AF_UNIX;
4488+ strcpy(saun.sun_path, SYSLOG_PATH);
4489+ /*saun.sun_len = sizeof(saun);*/
4490+
4491+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4492+ if (r) {
4493+ close(s);
4494+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4495+ if (s == -1) {
4496+ goto log_sapi;
4497+ }
4498+
4499+ memset(&saun, 0, sizeof(saun));
4500+ saun.sun_family = AF_UNIX;
4501+ strcpy(saun.sun_path, SYSLOG_PATH);
4502+ /*saun.sun_len = sizeof(saun);*/
4503+
4504+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4505+ if (r) {
4506+ close(s);
4507+ goto log_sapi;
4508+ }
4509+ }
4510+ send(s, error, strlen(error), 0);
4511+
4512+ close(s);
4513+
4514+log_sapi:
4515+ /* SAPI Logging activated? */
4516+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4517+ sapi_module.log_message(buf);
4518+ }
4519+
4520+log_script:
4521+ /* script logging activaed? */
4522+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4523+ char cmd[8192], *cmdpos, *bufpos;
4524+ FILE *in;
4525+ int space;
4526+
4527+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4528+ space = sizeof(cmd) - strlen(cmd);
4529+ cmdpos = cmd + strlen(cmd);
4530+ bufpos = buf;
4531+ if (space <= 1) return;
4532+ while (space > 2 && *bufpos) {
4533+ if (*bufpos == '\'') {
4534+ if (space<=5) break;
4535+ *cmdpos++ = '\'';
4536+ *cmdpos++ = '\\';
4537+ *cmdpos++ = '\'';
4538+ *cmdpos++ = '\'';
4539+ bufpos++;
4540+ space-=4;
4541+ } else {
4542+ *cmdpos++ = *bufpos++;
4543+ space--;
4544+ }
4545+ }
4546+ *cmdpos++ = '\'';
4547+ *cmdpos = 0;
4548+
4549+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4550+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4551+ return;
4552+ }
4553+ /* read and forget the result */
4554+ while (1) {
4555+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4556+ if (readbytes<=0) {
4557+ break;
4558+ }
4559+ }
4560+ pclose(in);
4561+ }
4562+
4563+#endif
4564+}
4565+#endif
4566+
4567+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4568+
4569+/* will be replaced later with more compatible method */
4570+PHPAPI unsigned int php_canary()
4571+{
4572+ time_t t;
4573+ unsigned int canary;
4574+ int fd;
4575+
4576+ fd = open("/dev/urandom", 0);
4577+ if (fd != -1) {
4578+ int r = read(fd, &canary, sizeof(canary));
4579+ close(fd);
4580+ if (r == sizeof(canary)) {
4581+ return (canary);
4582+ }
4583+ }
4584+ /* not good but we never want to do this */
4585+ time(&t);
4586+ canary = *(unsigned int *)&t + getpid() << 16;
4587+ return (canary);
4588+}
4589+#endif
4590+
4591+#if HARDENING_PATCH_INC_PROTECT
4592+
4593+PHPAPI int php_is_valid_include(zval *z)
4594+{
4595+ char *filename;
4596+ int len, i;
4597+ TSRMLS_FETCH();
4598+
4599+ /* must be of type string */
4600+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4601+ return (0);
4602+ }
4603+
4604+ /* short cut */
4605+ filename = z->value.str.val;
4606+ len = z->value.str.len;
4607+
4608+ /* 1. must be shorter than MAXPATHLEN */
4609+ if (len > MAXPATHLEN) {
4610+ char *fname = estrndup(filename, len);
4611+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4612+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4613+ efree(fname);
4614+ return (0);
4615+ }
4616+
4617+ /* 2. must not be cutted */
4618+ if (len != strlen(filename)) {
4619+ char *fname = estrndup(filename, len);
4620+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4621+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4622+ efree(fname);
4623+ return (0);
4624+ }
4625+
4626+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4627+ if (strstr(filename, "://")) {
4628+ char *fname = estrndup(filename, len);
4629+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4630+
4631+ /* no black or whitelist then disallow all */
4632+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4633+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4634+ efree(fname);
4635+ return (0);
4636+ }
4637+
4638+ /* whitelist is stronger than blacklist */
4639+ if (HG(include_whitelist)) {
4640+ char *s, *t, *h, *index;
4641+ uint indexlen;
4642+ ulong numindex;
4643+
4644+ s = filename;
4645+
4646+ do {
4647+ zend_bool isOk = 0;
4648+ int tlen;
4649+
4650+ t = h = strstr(s, "://");
4651+ if (h == NULL) break;
4652+
4653+
4654+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4655+ t--;
4656+ }
4657+
4658+ tlen = strlen(t);
4659+
4660+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4661+ do {
4662+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4663+
4664+ if (r==HASH_KEY_NON_EXISTANT) {
4665+ break;
4666+ }
4667+ if (r==HASH_KEY_IS_STRING) {
4668+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4669+ if (strncmp(t, index, indexlen-1)==0) {
4670+ isOk = 1;
4671+ break;
4672+ }
4673+ }
4674+ }
4675+
4676+ zend_hash_move_forward(HG(include_whitelist));
4677+ } while (1);
4678+
4679+ /* not found in whitelist */
4680+ if (!isOk) {
4681+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4682+ efree(fname);
4683+ return 0;
4684+ }
4685+
4686+ s = h + 3;
4687+ } while (1);
4688+ } else {
4689+ /* okay then handle the blacklist */
4690+ char *s, *t, *h, *index;
4691+ uint indexlen;
4692+ ulong numindex;
4693+
4694+ s = filename;
4695+
4696+ do {
4697+ int tlen;
4698+
4699+ t = h = strstr(s, "://");
4700+ if (h == NULL) break;
4701+
4702+
4703+ while (t > s) {
4704+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4705+ }
4706+
4707+ tlen = strlen(t);
4708+
4709+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4710+ do {
4711+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4712+
4713+ if (r==HASH_KEY_NON_EXISTANT) {
4714+ break;
4715+ }
4716+ if (r==HASH_KEY_IS_STRING) {
4717+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4718+ if (strncmp(t, index, indexlen-1)==0) {
4719+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4720+ efree(fname);
4721+ return 0;
4722+ }
4723+ }
4724+ }
4725+
4726+ zend_hash_move_forward(HG(include_blacklist));
4727+ } while (1);
4728+
4729+ s = h + 3;
4730+ } while (1);
4731+ }
4732+
4733+ efree(fname);
4734+ }
4735+
4736+ /* 4. must not be an uploaded file */
4737+ if (SG(rfc1867_uploaded_files)) {
4738+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4739+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4740+ return (0);
4741+ }
4742+ }
4743+
4744+ /* passed all tests */
4745+ return (1);
4746+}
4747+
4748+#endif
4749+
4750+/*
4751+ * Local variables:
4752+ * tab-width: 4
4753+ * c-basic-offset: 4
4754+ * End:
4755+ * vim600: sw=4 ts=4 fdm=marker
4756+ * vim<600: sw=4 ts=4
4757+ */
4758diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.11/main/hardening_patch.h
4759--- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4760+++ hardening-patch-4.4.2-0.4.11/main/hardening_patch.h 2006-05-13 18:02:13.000000000 +0200
4761@@ -0,0 +1,46 @@
4762+/*
4763+ +----------------------------------------------------------------------+
4764+ | Hardening Patch for PHP |
4765+ +----------------------------------------------------------------------+
4766+ | Copyright (c) 2004-2005 Stefan Esser |
4767+ +----------------------------------------------------------------------+
4768+ | This source file is subject to version 2.02 of the PHP license, |
4769+ | that is bundled with this package in the file LICENSE, and is |
4770+ | available at through the world-wide-web at |
4771+ | http://www.php.net/license/2_02.txt. |
4772+ | If you did not receive a copy of the PHP license and are unable to |
4773+ | obtain it through the world-wide-web, please send a note to |
4774+ | license@php.net so we can mail you a copy immediately. |
4775+ +----------------------------------------------------------------------+
4776+ | Author: Stefan Esser <sesser@hardened-php.net> |
4777+ +----------------------------------------------------------------------+
4778+ */
4779+
4780+#ifndef HARDENING_PATCH_H
4781+#define HARDENING_PATCH_H
4782+
4783+#include "zend.h"
4784+
4785+#if HARDENING_PATCH
4786+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4787+PHPAPI void hardened_startup();
4788+#define HARDENING_PATCH_VERSION "0.4.11"
4789+
4790+#endif
4791+
4792+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4793+PHPAPI unsigned int php_canary();
4794+#endif
4795+
4796+#if HARDENING_PATCH_INC_PROTECT
4797+PHPAPI int php_is_valid_include(zval *z);
4798+#endif
4799+
4800+#endif /* HARDENING_PATCH_H */
4801+
4802+/*
4803+ * Local variables:
4804+ * tab-width: 4
4805+ * c-basic-offset: 4
4806+ * End:
4807+ */
4808diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.11/main/hardening_patch.m4
4809--- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4810+++ hardening-patch-4.4.2-0.4.11/main/hardening_patch.m4 2006-05-13 18:01:56.000000000 +0200
4811@@ -0,0 +1,95 @@
4812+dnl
4813+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4814+dnl
4815+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4816+dnl
4817+
4818+AC_ARG_ENABLE(hardening-patch-mm-protect,
4819+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4820+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4821+],[
4822+ DO_HARDENING_PATCH_MM_PROTECT=yes
4823+])
4824+
4825+AC_ARG_ENABLE(hardening-patch-ll-protect,
4826+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4827+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4828+],[
4829+ DO_HARDENING_PATCH_LL_PROTECT=yes
4830+])
4831+
4832+AC_ARG_ENABLE(hardening-patch-inc-protect,
4833+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4834+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4835+],[
4836+ DO_HARDENING_PATCH_INC_PROTECT=yes
4837+])
4838+
4839+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4840+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4841+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4842+],[
4843+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4844+])
4845+
4846+AC_ARG_ENABLE(hardening-patch-hash-protect,
4847+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4848+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4849+],[
4850+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4851+])
4852+
4853+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4854+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4855+
4856+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4857+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4858+
4859+AC_MSG_CHECKING(whether to protect include/require statements)
4860+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4861+
4862+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4863+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4864+
4865+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4866+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4867+
4868+
4869+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4870+
4871+
4872+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4873+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4874+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4875+else
4876+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4877+fi
4878+
4879+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4880+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4881+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4882+else
4883+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4884+fi
4885+
4886+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4887+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4888+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4889+else
4890+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4891+fi
4892+
4893+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4894+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4895+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4896+else
4897+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4898+fi
4899+
4900+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4901+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4902+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4903+else
4904+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4905+fi
4906+
4907diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.11/main/main.c
4908--- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100
4909+++ hardening-patch-4.4.2-0.4.11/main/main.c 2006-05-13 18:01:56.000000000 +0200
4910@@ -92,6 +92,10 @@
4911 PHPAPI int core_globals_id;
4912 #endif
4913
4914+#if HARDENING_PATCH
4915+#include "hardened_globals.h"
4916+#endif
4917+
4918 #define ERROR_BUF_LEN 1024
4919
4920 typedef struct {
4921@@ -142,10 +146,33 @@
4922 */
4923 static PHP_INI_MH(OnChangeMemoryLimit)
4924 {
4925+#if HARDENING_PATCH
4926+ long orig_memory_limit;
4927+
4928+ if (entry->modified) {
4929+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4930+ } else {
4931+ orig_memory_limit = 1<<30;
4932+ }
4933+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4934+ orig_memory_limit = 1<<30;
4935+ }
4936+#endif
4937 if (new_value) {
4938 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4939+#if HARDENING_PATCH
4940+ if (PG(memory_limit) > orig_memory_limit) {
4941+ PG(memory_limit) = orig_memory_limit;
4942+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4943+ return FAILURE;
4944+ }
4945+#endif
4946 } else {
4947+#if HARDENING_PATCH
4948+ PG(memory_limit) = orig_memory_limit;
4949+#else
4950 PG(memory_limit) = 1<<30; /* effectively, no limit */
4951+#endif
4952 }
4953 return zend_set_memory_limit(PG(memory_limit));
4954 }
4955@@ -1008,6 +1035,9 @@
4956
4957 zend_try {
4958 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4959+#if HARDENING_PATCH
4960+ hardened_clear_mm_canaries(TSRMLS_C);
4961+#endif
4962 } zend_end_try();
4963
4964 zend_try {
4965@@ -1098,6 +1128,10 @@
4966 tsrm_ls = ts_resource(0);
4967 #endif
4968
4969+#if HARDENING_PATCH
4970+ hardened_startup();
4971+#endif
4972+
4973 sapi_initialize_empty_request(TSRMLS_C);
4974 sapi_activate(TSRMLS_C);
4975
4976@@ -1110,6 +1144,12 @@
4977 php_output_startup();
4978 php_output_activate(TSRMLS_C);
4979
4980+#if HARDENING_PATCH_INC_PROTECT
4981+ zuf.is_valid_include = php_is_valid_include;
4982+#endif
4983+#if HARDENING_PATCH
4984+ zuf.security_log_function = php_security_log;
4985+#endif
4986 zuf.error_function = php_error_cb;
4987 zuf.printf_function = php_printf;
4988 zuf.write_function = php_body_write_wrapper;
4989@@ -1211,6 +1251,10 @@
4990 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4991 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);
4992 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4993+#if HARDENING_PATCH
4994+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4995+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4996+#endif
4997 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4998 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4999 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
5000@@ -1318,7 +1362,7 @@
5001 */
5002 static inline void php_register_server_variables(TSRMLS_D)
5003 {
5004- zval *array_ptr=NULL;
5005+ zval *array_ptr=NULL, *vptr;
5006
5007 ALLOC_ZVAL(array_ptr);
5008 array_init(array_ptr);
5009diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.11/main/php_config.h.in
5010--- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100
5011+++ hardening-patch-4.4.2-0.4.11/main/php_config.h.in 2006-05-13 18:01:56.000000000 +0200
5012@@ -865,6 +865,39 @@
5013 /* Enabling BIND8 compatibility for Panther */
5014 #undef BIND_8_COMPAT
5015
5016+/* Hardening-Patch */
5017+#undef HARDENING_PATCH
5018+
5019+/* Memory Manager Protection */
5020+#undef HARDENING_PATCH_MM_PROTECT
5021+
5022+/* Memory Manager Protection */
5023+#undef HARDENING_PATCH_MM_PROTECT
5024+
5025+/* Linked List Protection */
5026+#undef HARDENING_PATCH_LL_PROTECT
5027+
5028+/* Linked List Protection */
5029+#undef HARDENING_PATCH_LL_PROTECT
5030+
5031+/* Include/Require Protection */
5032+#undef HARDENING_PATCH_INC_PROTECT
5033+
5034+/* Include/Require Protection */
5035+#undef HARDENING_PATCH_INC_PROTECT
5036+
5037+/* Fmt String Protection */
5038+#undef HARDENING_PATCH_FMT_PROTECT
5039+
5040+/* Fmt String Protection */
5041+#undef HARDENING_PATCH_FMT_PROTECT
5042+
5043+/* HashTable DTOR Protection */
5044+#undef HARDENING_PATCH_HASH_PROTECT
5045+
5046+/* HashTable DTOR Protection */
5047+#undef HARDENING_PATCH_HASH_PROTECT
5048+
5049 /* Whether you have AOLserver */
5050 #undef HAVE_AOLSERVER
5051
5052@@ -1148,6 +1181,12 @@
5053 /* Define if you have the getaddrinfo function */
5054 #undef HAVE_GETADDRINFO
5055
5056+/* Whether realpath is broken */
5057+#undef PHP_BROKEN_REALPATH
5058+
5059+/* Whether realpath is broken */
5060+#undef PHP_BROKEN_REALPATH
5061+
5062 /* Whether system headers declare timezone */
5063 #undef HAVE_DECLARED_TIMEZONE
5064
5065diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.11/main/php_content_types.c
5066--- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100
5067+++ hardening-patch-4.4.2-0.4.11/main/php_content_types.c 2006-05-13 18:01:56.000000000 +0200
5068@@ -77,6 +77,7 @@
5069 sapi_register_post_entries(php_post_entries);
5070 sapi_register_default_post_reader(php_default_post_reader);
5071 sapi_register_treat_data(php_default_treat_data);
5072+ sapi_register_input_filter(php_default_input_filter);
5073 return SUCCESS;
5074 }
5075 /* }}} */
5076diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.11/main/php.h
5077--- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100
5078+++ hardening-patch-4.4.2-0.4.11/main/php.h 2006-05-13 18:01:56.000000000 +0200
5079@@ -35,11 +35,19 @@
5080 #include "zend_qsort.h"
5081 #include "php_compat.h"
5082
5083+
5084 #include "zend_API.h"
5085
5086 #undef sprintf
5087 #define sprintf php_sprintf
5088
5089+#if HARDENING_PATCH
5090+#if HAVE_REALPATH
5091+#undef realpath
5092+#define realpath php_realpath
5093+#endif
5094+#endif
5095+
5096 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
5097 #undef PHP_DEBUG
5098 #define PHP_DEBUG ZEND_DEBUG
5099@@ -409,6 +417,10 @@
5100 #endif
5101 #endif /* !XtOffsetOf */
5102
5103+#if HARDENING_PATCH
5104+#include "hardening_patch.h"
5105+#endif
5106+
5107 #endif
5108
5109 /*
5110diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.11/main/php_variables.c
5111--- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100
5112+++ hardening-patch-4.4.2-0.4.11/main/php_variables.c 2006-05-13 18:01:56.000000000 +0200
5113@@ -236,17 +236,28 @@
5114 while (var) {
5115 val = strchr(var, '=');
5116 if (val) { /* have a value */
5117- int val_len;
5118+ unsigned int val_len, new_val_len;
5119
5120 *val++ = '\0';
5121 php_url_decode(var, strlen(var));
5122 val_len = php_url_decode(val, strlen(val));
5123- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5124+ val = estrndup(val, val_len);
5125+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5126+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5127+ }
5128+ efree(val);
5129 }
5130 var = php_strtok_r(NULL, "&", &strtok_buf);
5131 }
5132 }
5133
5134+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
5135+{
5136+ /* TODO: check .ini setting here and apply user-defined input filter */
5137+ *new_val_len = val_len;
5138+ return 1;
5139+}
5140+
5141 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
5142 {
5143 char *res = NULL, *var, *val, *separator=NULL;
5144@@ -324,15 +335,26 @@
5145 while (var) {
5146 val = strchr(var, '=');
5147 if (val) { /* have a value */
5148- int val_len;
5149+ unsigned int val_len, new_val_len;
5150
5151 *val++ = '\0';
5152 php_url_decode(var, strlen(var));
5153 val_len = php_url_decode(val, strlen(val));
5154- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
5155+ val = estrndup(val, val_len);
5156+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5157+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5158+ }
5159+ efree(val);
5160 } else {
5161+ unsigned int val_len, new_val_len;
5162+
5163 php_url_decode(var, strlen(var));
5164- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
5165+ val_len = 0;
5166+ val = estrndup("", 0);
5167+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
5168+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
5169+ }
5170+ efree(val);
5171 }
5172 var = php_strtok_r(NULL, separator, &strtok_buf);
5173 }
5174diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.11/main/rfc1867.c
5175--- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100
5176+++ hardening-patch-4.4.2-0.4.11/main/rfc1867.c 2006-05-13 18:01:56.000000000 +0200
5177@@ -128,6 +128,8 @@
5178 #define UPLOAD_ERROR_D 4 /* No file uploaded */
5179 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
5180 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
5181+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
5182+
5183
5184 void php_rfc1867_register_constants(TSRMLS_D)
5185 {
5186@@ -138,6 +140,7 @@
5187 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
5188 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
5189 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
5190+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
5191 }
5192
5193 static void normalize_protected_variable(char *varname TSRMLS_DC)
5194@@ -849,6 +852,7 @@
5195 char buff[FILLUNIT];
5196 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
5197 int blen=0, wlen=0;
5198+ unsigned long offset;
5199
5200 zend_llist_clean(&header);
5201
5202@@ -897,21 +901,24 @@
5203 if (!filename && param) {
5204
5205 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
5206+ unsigned int new_val_len; /* Dummy variable */
5207
5208 if (!value) {
5209 value = estrdup("");
5210 }
5211
5212+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
5213 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
5214- if (php_mb_encoding_translation(TSRMLS_C)) {
5215- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5216- &num_vars, &num_vars_max TSRMLS_CC);
5217- } else {
5218- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5219- }
5220+ if (php_mb_encoding_translation(TSRMLS_C)) {
5221+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
5222+ &num_vars, &num_vars_max TSRMLS_CC);
5223+ } else {
5224+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5225+ }
5226 #else
5227- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5228+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
5229 #endif
5230+ }
5231 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
5232 max_file_size = atol(value);
5233 }
5234@@ -963,7 +970,11 @@
5235 tmp++;
5236 }
5237 }
5238-
5239+
5240+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
5241+ skip_upload = 1;
5242+ }
5243+
5244 total_bytes = cancel_upload = 0;
5245
5246 if (!skip_upload) {
5247@@ -987,6 +998,11 @@
5248 cancel_upload = UPLOAD_ERROR_D;
5249 }
5250
5251+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
5252+ cancel_upload = UPLOAD_ERROR_X;
5253+ }
5254+
5255+ offset = 0;
5256 end = 0;
5257 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
5258 {
5259@@ -997,6 +1013,11 @@
5260 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
5261 cancel_upload = UPLOAD_ERROR_B;
5262 } else if (blen > 0) {
5263+
5264+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
5265+ cancel_upload = UPLOAD_ERROR_X;
5266+ }
5267+
5268 wlen = write(fd, buff, blen);
5269
5270 if (wlen < blen) {
5271@@ -1004,6 +1025,7 @@
5272 cancel_upload = UPLOAD_ERROR_F;
5273 } else {
5274 total_bytes += wlen;
5275+ offset += wlen;
5276 }
5277 }
5278 }
5279@@ -1025,6 +1047,10 @@
5280 }
5281 #endif
5282
5283+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
5284+ cancel_upload = UPLOAD_ERROR_X;
5285+ }
5286+
5287 if (cancel_upload) {
5288 if (temp_filename) {
5289 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5290diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.11/main/SAPI.c
5291--- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100
5292+++ hardening-patch-4.4.2-0.4.11/main/SAPI.c 2006-05-13 18:01:56.000000000 +0200
5293@@ -854,6 +854,37 @@
5294 return SUCCESS;
5295 }
5296
5297+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))
5298+{
5299+ sapi_module.input_filter = input_filter;
5300+ return SUCCESS;
5301+}
5302+
5303+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5304+{
5305+ sapi_module.upload_varname_filter = upload_varname_filter;
5306+ return SUCCESS;
5307+}
5308+
5309+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5310+{
5311+ sapi_module.pre_upload_filter = pre_upload_filter;
5312+ return SUCCESS;
5313+}
5314+
5315+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))
5316+{
5317+ sapi_module.upload_content_filter = upload_content_filter;
5318+ return SUCCESS;
5319+}
5320+
5321+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5322+{
5323+ sapi_module.post_upload_filter = post_upload_filter;
5324+ return SUCCESS;
5325+}
5326+
5327+
5328
5329 SAPI_API int sapi_flush(TSRMLS_D)
5330 {
5331diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.11/main/SAPI.h
5332--- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100
5333+++ hardening-patch-4.4.2-0.4.11/main/SAPI.h 2006-05-13 18:01:56.000000000 +0200
5334@@ -101,9 +101,10 @@
5335 char *current_user;
5336 int current_user_length;
5337
5338- /* this is necessary for CLI module */
5339- int argc;
5340- char **argv;
5341+ /* this is necessary for CLI module */
5342+ int argc;
5343+ char **argv;
5344+
5345 } sapi_request_info;
5346
5347
5348@@ -177,6 +178,10 @@
5349 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5350 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5351 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5352+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));
5353+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5354+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));
5355+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5356
5357 SAPI_API int sapi_flush(TSRMLS_D);
5358 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5359@@ -238,8 +243,16 @@
5360 int (*get_target_uid)(uid_t * TSRMLS_DC);
5361 int (*get_target_gid)(gid_t * TSRMLS_DC);
5362
5363+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5364+
5365+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5366+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5367+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5368+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5369+
5370 void (*ini_defaults)(HashTable *configuration_hash);
5371 int phpinfo_as_text;
5372+
5373 };
5374
5375
5376@@ -262,16 +275,27 @@
5377
5378 #define SAPI_DEFAULT_MIMETYPE "text/html"
5379 #define SAPI_DEFAULT_CHARSET ""
5380+
5381+#if HARDENING_PATCH
5382+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5383+#else
5384 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5385+#endif
5386
5387 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5388 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5389
5390 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5391+#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)
5392+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5393+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5394+#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)
5395+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5396
5397 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5398 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5399 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5400+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5401
5402 #define STANDARD_SAPI_MODULE_PROPERTIES
5403
5404diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.11/main/snprintf.c
5405--- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100
5406+++ hardening-patch-4.4.2-0.4.11/main/snprintf.c 2006-05-13 18:01:56.000000000 +0200
5407@@ -1014,7 +1014,11 @@
5408
5409
5410 case 'n':
5411+#if HARDENING_PATCH_FMT_PROTECT
5412+ php_security_log(S_MISC, "'n' specifier within format string");
5413+#else
5414 *(va_arg(ap, int *)) = cc;
5415+#endif
5416 break;
5417
5418 /*
5419diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.11/main/spprintf.c
5420--- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100
5421+++ hardening-patch-4.4.2-0.4.11/main/spprintf.c 2006-05-13 18:01:56.000000000 +0200
5422@@ -630,7 +630,11 @@
5423
5424
5425 case 'n':
5426+#if HARDENING_PATCH_FMT_PROTECT
5427+ php_security_log(S_MISC, "'n' specifier within format string");
5428+#else
5429 *(va_arg(ap, int *)) = xbuf->len;
5430+#endif
5431 break;
5432
5433 /*
5434diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.11/php.ini-dist
5435--- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100
5436+++ hardening-patch-4.4.2-0.4.11/php.ini-dist 2006-05-13 18:01:56.000000000 +0200
5437@@ -1114,6 +1114,209 @@
5438 ;exif.decode_jis_motorola = JIS
5439 ;exif.decode_jis_intel = JIS
5440
5441+[hardening-patch]
5442+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5443+; Hardening-Patch's logging ;
5444+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5445+
5446+;
5447+; hphp.log.syslog - Configures level for alerts reported through syslog
5448+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5449+; hphp.log.script - Configures level for alerts reported through external script
5450+;
5451+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5452+; Or each number up to get desired Hardening-Patch's reporting level
5453+;
5454+; S_ALL - All alerts
5455+; S_MEMORY - All canary violations and the safe unlink protection use this class
5456+; S_VARS - All variable filters trigger this class
5457+; S_FILES - All violation of uploaded files filter use this class
5458+; S_INCLUDE - The protection against malicious include filenames use this class
5459+; S_SQL - Failed SQL queries in MySQL are logged with this class
5460+; S_EXECUTOR - The execution depth protection uses this logging class
5461+; S_MISC - All other log messages (f.e. format string protection) use this class
5462+;
5463+; Example:
5464+;
5465+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5466+; memory alerts through syslog and SQL+Include alerts fo the script
5467+;
5468+;hphp.log.syslog = S_MEMORY
5469+;hphp.log.sapi = S_ALL & ~S_MEMORY
5470+;hphp.log.script = S_INCLUDE | S_SQL
5471+;
5472+; Syslog logging:
5473+;
5474+; - Facility configuration: one of the following facilities
5475+;
5476+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5477+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5478+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5479+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5480+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5481+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5482+; LOG_PERROR
5483+;
5484+; - Priority configuration: one of the followinf priorities
5485+;
5486+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5487+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5488+;
5489+hphp.log.syslog.priority = LOG_ALERT
5490+hphp.log.syslog.facility = LOG_USER
5491+;
5492+; Script logging:
5493+;
5494+;hphp.log.script.name = /home/hphp/log_script
5495+;
5496+; Alert configuration:
5497+;
5498+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5499+;
5500+;hphp.log.use-x-forwarded-for = On
5501+;
5502+
5503+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5504+; Hardening-Patch's Executor options ;
5505+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5506+
5507+; Execution depth limit
5508+;hphp.executor.max_depth = 8000
5509+
5510+; White-/blacklist for function calls during normal execution
5511+;hphp.executor.func.whitelist = ord,chr
5512+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5513+
5514+; White-/blacklist for function calls during eval() execution
5515+;hphp.executor.eval.whitelist = ord,chr
5516+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5517+
5518+; White-/blacklist for URLs allowes in include filenames
5519+;
5520+; - When both options are not set all URLs are forbidden
5521+;
5522+; - When both options are set whitelist is taken and blacklist ignored
5523+;
5524+; - An entry in the lists is either a URL sheme like: http, https
5525+; or the beginning of an URL like: php://input
5526+;
5527+;hphp.executor.include.whitelist = cookietest
5528+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5529+
5530+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5531+; Hardening-Patch's REQUEST variable filters ;
5532+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5533+
5534+; Limits the number of REQUEST variables
5535+hphp.request.max_vars = 200
5536+
5537+; Limits the length of variable names (without indices)
5538+hphp.request.max_varname_length = 64
5539+
5540+; Limits the length of complete variable names (with indices)
5541+hphp.request.max_totalname_length = 256
5542+
5543+; Limits the length of array indices
5544+hphp.request.max_array_index_length = 64
5545+
5546+; Limits the depth of arrays
5547+hphp.request.max_array_depth = 100
5548+
5549+; Limits the length of variable values
5550+hphp.request.max_value_length = 65000
5551+
5552+; Disallow ASCII-NUL characters in input
5553+hphp.request.disallow_nul = 1
5554+
5555+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5556+; Hardening-Patch's COOKIE variable filters ;
5557+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5558+
5559+; Limits the number of COOKIE variables
5560+hphp.cookie.max_vars = 100
5561+
5562+; Limits the length of variable names (without indices)
5563+hphp.cookie.max_name_length = 64
5564+
5565+; Limits the length of complete variable names (with indices)
5566+hphp.cookie.max_totalname_length = 256
5567+
5568+; Limits the length of array indices
5569+hphp.cookie.max_array_index_length = 64
5570+
5571+; Limits the depth of arrays
5572+hphp.cookie.max_array_depth = 100
5573+
5574+; Limits the length of variable values
5575+hphp.cookie.max_value_length = 10000
5576+
5577+; Disallow ASCII-NUL characters in input
5578+hphp.cookie.disallow_nul = 1
5579+
5580+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5581+; Hardening-Patch's GET variable filters ;
5582+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5583+
5584+; Limits the number of COOKIE variables
5585+hphp.get.max_vars = 100
5586+
5587+; Limits the length of variable names (without indices)
5588+hphp.get.max_name_length = 64
5589+
5590+; Limits the length of complete variable names (with indices)
5591+hphp.get.max_totalname_length = 256
5592+
5593+; Limits the length of array indices
5594+hphp.get.max_array_index_length = 64
5595+
5596+; Limits the depth of arrays
5597+hphp.get.max_array_depth = 50
5598+
5599+; Limits the length of variable values
5600+hphp.get.max_value_length = 512
5601+
5602+; Disallow ASCII-NUL characters in input
5603+hphp.get.disallow_nul = 1
5604+
5605+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5606+; Hardening-Patch's POST variable filters ;
5607+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5608+
5609+; Limits the number of POST variables
5610+hphp.post.max_vars = 200
5611+
5612+; Limits the length of variable names (without indices)
5613+hphp.post.max_name_length = 64
5614+
5615+; Limits the length of complete variable names (with indices)
5616+hphp.post.max_totalname_length = 256
5617+
5618+; Limits the length of array indices
5619+hphp.post.max_array_index_length = 64
5620+
5621+; Limits the depth of arrays
5622+hphp.post.max_array_depth = 100
5623+
5624+; Limits the length of variable values
5625+hphp.post.max_value_length = 65000
5626+
5627+; Disallow ASCII-NUL characters in input
5628+hphp.post.disallow_nul = 1
5629+
5630+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5631+; Hardening-Patch's fileupload variable filters ;
5632+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5633+
5634+; Limits the number of uploadable files
5635+hphp.upload.max_uploads = 25
5636+
5637+; Filter out the upload of ELF executables
5638+hphp.upload.disallow_elf_files = On
5639+
5640+; External filterscript for upload verification
5641+;hphp.upload.verification_script = /home/hphp/verify_script
5642+
5643+
5644 ; Local Variables:
5645 ; tab-width: 4
5646 ; End:
5647diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.11/php.ini-recommended
5648--- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100
5649+++ hardening-patch-4.4.2-0.4.11/php.ini-recommended 2006-05-13 18:01:56.000000000 +0200
5650@@ -1112,6 +1112,209 @@
5651 ;exif.decode_jis_motorola = JIS
5652 ;exif.decode_jis_intel = JIS
5653
5654+[hardening-patch]
5655+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5656+; Hardening-Patch's logging ;
5657+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5658+
5659+;
5660+; hphp.log.syslog - Configures level for alerts reported through syslog
5661+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5662+; hphp.log.script - Configures level for alerts reported through external script
5663+;
5664+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5665+; Or each number up to get desired Hardening-Patch's reporting level
5666+;
5667+; S_ALL - All alerts
5668+; S_MEMORY - All canary violations and the safe unlink protection use this class
5669+; S_VARS - All variable filters trigger this class
5670+; S_FILES - All violation of uploaded files filter use this class
5671+; S_INCLUDE - The protection against malicious include filenames use this class
5672+; S_SQL - Failed SQL queries in MySQL are logged with this class
5673+; S_EXECUTOR - The execution depth protection uses this logging class
5674+; S_MISC - All other log messages (f.e. format string protection) use this class
5675+;
5676+; Example:
5677+;
5678+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5679+; memory alerts through syslog and SQL+Include alerts fo the script
5680+;
5681+;hphp.log.syslog = S_MEMORY
5682+;hphp.log.sapi = S_ALL & ~S_MEMORY
5683+;hphp.log.script = S_INCLUDE | S_SQL
5684+;
5685+; Syslog logging:
5686+;
5687+; - Facility configuration: one of the following facilities
5688+;
5689+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5690+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5691+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5692+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5693+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5694+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5695+; LOG_PERROR
5696+;
5697+; - Priority configuration: one of the followinf priorities
5698+;
5699+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5700+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5701+;
5702+hphp.log.syslog.priority = LOG_ALERT
5703+hphp.log.syslog.facility = LOG_USER
5704+;
5705+; Script logging:
5706+;
5707+;hphp.log.script.name = /home/hphp/log_script
5708+;
5709+; Alert configuration:
5710+;
5711+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5712+;
5713+;hphp.log.use-x-forwarded-for = On
5714+;
5715+
5716+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5717+; Hardening-Patch's Executor options ;
5718+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5719+
5720+; Execution depth limit
5721+;hphp.executor.max_depth = 8000
5722+
5723+; White-/blacklist for function calls during normal execution
5724+;hphp.executor.func.whitelist = ord,chr
5725+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5726+
5727+; White-/blacklist for function calls during eval() execution
5728+;hphp.executor.eval.whitelist = ord,chr
5729+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5730+
5731+; White-/blacklist for URLs allowes in include filenames
5732+;
5733+; - When both options are not set all URLs are forbidden
5734+;
5735+; - When both options are set whitelist is taken and blacklist ignored
5736+;
5737+; - An entry in the lists is either a URL sheme like: http, https
5738+; or the beginning of an URL like: php://input
5739+;
5740+;hphp.executor.include.whitelist = cookietest
5741+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5742+
5743+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5744+; Hardening-Patch's REQUEST variable filters ;
5745+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5746+
5747+; Limits the number of REQUEST variables
5748+hphp.request.max_vars = 200
5749+
5750+; Limits the length of variable names (without indices)
5751+hphp.request.max_varname_length = 64
5752+
5753+; Limits the length of complete variable names (with indices)
5754+hphp.request.max_totalname_length = 256
5755+
5756+; Limits the length of array indices
5757+hphp.request.max_array_index_length = 64
5758+
5759+; Limits the depth of arrays
5760+hphp.request.max_array_depth = 100
5761+
5762+; Limits the length of variable values
5763+hphp.request.max_value_length = 65000
5764+
5765+; Disallow ASCII-NUL characters in input
5766+hphp.request.disallow_nul = 1
5767+
5768+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5769+; Hardening-Patch's COOKIE variable filters ;
5770+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5771+
5772+; Limits the number of COOKIE variables
5773+hphp.cookie.max_vars = 100
5774+
5775+; Limits the length of variable names (without indices)
5776+hphp.cookie.max_name_length = 64
5777+
5778+; Limits the length of complete variable names (with indices)
5779+hphp.cookie.max_totalname_length = 256
5780+
5781+; Limits the length of array indices
5782+hphp.cookie.max_array_index_length = 64
5783+
5784+; Limits the depth of arrays
5785+hphp.cookie.max_array_depth = 100
5786+
5787+; Limits the length of variable values
5788+hphp.cookie.max_value_length = 10000
5789+
5790+; Disallow ASCII-NUL characters in input
5791+hphp.cookie.disallow_nul = 1
5792+
5793+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5794+; Hardening-Patch's GET variable filters ;
5795+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5796+
5797+; Limits the number of COOKIE variables
5798+hphp.get.max_vars = 100
5799+
5800+; Limits the length of variable names (without indices)
5801+hphp.get.max_name_length = 64
5802+
5803+; Limits the length of complete variable names (with indices)
5804+hphp.get.max_totalname_length = 256
5805+
5806+; Limits the length of array indices
5807+hphp.get.max_array_index_length = 64
5808+
5809+; Limits the depth of arrays
5810+hphp.get.max_array_depth = 50
5811+
5812+; Limits the length of variable values
5813+hphp.get.max_value_length = 512
5814+
5815+; Disallow ASCII-NUL characters in input
5816+hphp.get.disallow_nul = 1
5817+
5818+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5819+; Hardening-Patch's POST variable filters ;
5820+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5821+
5822+; Limits the number of POST variables
5823+hphp.post.max_vars = 200
5824+
5825+; Limits the length of variable names (without indices)
5826+hphp.post.max_name_length = 64
5827+
5828+; Limits the length of complete variable names (with indices)
5829+hphp.post.max_totalname_length = 256
5830+
5831+; Limits the length of array indices
5832+hphp.post.max_array_index_length = 64
5833+
5834+; Limits the depth of arrays
5835+hphp.post.max_array_depth = 100
5836+
5837+; Limits the length of variable values
5838+hphp.post.max_value_length = 65000
5839+
5840+; Disallow ASCII-NUL characters in input
5841+hphp.post.disallow_nul = 1
5842+
5843+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5844+; Hardening-Patch's fileupload variable filters ;
5845+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5846+
5847+; Limits the number of uploadable files
5848+hphp.upload.max_uploads = 25
5849+
5850+; Filter out the upload of ELF executables
5851+hphp.upload.disallow_elf_files = On
5852+
5853+; External filterscript for upload verification
5854+;hphp.upload.verification_script = /home/hphp/verify_script
5855+
5856+
5857 ; Local Variables:
5858 ; tab-width: 4
5859 ; End:
5860diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.11/README.input_filter
5861--- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5862+++ hardening-patch-4.4.2-0.4.11/README.input_filter 2006-05-13 18:01:56.000000000 +0200
5863@@ -0,0 +1,193 @@
5864+Input Filter Support ported from PHP 5
5865+--------------------------------------
5866+
5867+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5868+and can be quite difficult to prevent. Whenever you accept user data
5869+and somehow display this data back to users, you are likely vulnerable
5870+to XSS hacks.
5871+
5872+The Input Filter support in PHP 5 is aimed at providing the framework
5873+through which a company-wide or site-wide security policy can be
5874+enforced. It is implemented as a SAPI hook and is called from the
5875+treat_data and post handler functions. To implement your own security
5876+policy you will need to write a standard PHP extension.
5877+
5878+A simple implementation might look like the following. This stores the
5879+original raw user data and adds a my_get_raw() function while the normal
5880+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5881+data. In this simple example all I am doing is calling strip_tags() on
5882+the data. If register_globals is turned on, the default globals that
5883+are created will be stripped ($foo) while a $RAW_foo is created with the
5884+original user input.
5885+
5886+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5887+ zval *post_array;
5888+ zval *get_array;
5889+ zval *cookie_array;
5890+ZEND_END_MODULE_GLOBALS(my_input_filter)
5891+
5892+#ifdef ZTS
5893+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5894+#else
5895+#define IF_G(v) (my_input_filter_globals.v)
5896+#endif
5897+
5898+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5899+
5900+function_entry my_input_filter_functions[] = {
5901+ PHP_FE(my_get_raw, NULL)
5902+ {NULL, NULL, NULL}
5903+};
5904+
5905+zend_module_entry my_input_filter_module_entry = {
5906+ STANDARD_MODULE_HEADER,
5907+ "my_input_filter",
5908+ my_input_filter_functions,
5909+ PHP_MINIT(my_input_filter),
5910+ PHP_MSHUTDOWN(my_input_filter),
5911+ NULL,
5912+ PHP_RSHUTDOWN(my_input_filter),
5913+ PHP_MINFO(my_input_filter),
5914+ "0.1",
5915+ STANDARD_MODULE_PROPERTIES
5916+};
5917+
5918+PHP_MINIT_FUNCTION(my_input_filter)
5919+{
5920+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5921+
5922+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5923+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5924+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5925+
5926+ sapi_register_input_filter(my_sapi_input_filter);
5927+ return SUCCESS;
5928+}
5929+
5930+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5931+{
5932+ if(IF_G(get_array)) {
5933+ zval_ptr_dtor(&IF_G(get_array));
5934+ IF_G(get_array) = NULL;
5935+ }
5936+ if(IF_G(post_array)) {
5937+ zval_ptr_dtor(&IF_G(post_array));
5938+ IF_G(post_array) = NULL;
5939+ }
5940+ if(IF_G(cookie_array)) {
5941+ zval_ptr_dtor(&IF_G(cookie_array));
5942+ IF_G(cookie_array) = NULL;
5943+ }
5944+ return SUCCESS;
5945+}
5946+
5947+PHP_MINFO_FUNCTION(my_input_filter)
5948+{
5949+ php_info_print_table_start();
5950+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5951+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5952+ php_info_print_table_end();
5953+}
5954+
5955+/* The filter handler. If you return 1 from it, then PHP also registers the
5956+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5957+ * you can use this if your filter already registers the variable under a
5958+ * different name, or if you just don't want the variable registered at all. */
5959+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5960+{
5961+ zval new_var;
5962+ zval *array_ptr = NULL;
5963+ char *raw_var;
5964+ int var_len;
5965+
5966+ assert(*val != NULL);
5967+
5968+ switch(arg) {
5969+ case PARSE_GET:
5970+ if(!IF_G(get_array)) {
5971+ ALLOC_ZVAL(array_ptr);
5972+ array_init(array_ptr);
5973+ INIT_PZVAL(array_ptr);
5974+ }
5975+ IF_G(get_array) = array_ptr;
5976+ break;
5977+ case PARSE_POST:
5978+ if(!IF_G(post_array)) {
5979+ ALLOC_ZVAL(array_ptr);
5980+ array_init(array_ptr);
5981+ INIT_PZVAL(array_ptr);
5982+ }
5983+ IF_G(post_array) = array_ptr;
5984+ break;
5985+ case PARSE_COOKIE:
5986+ if(!IF_G(cookie_array)) {
5987+ ALLOC_ZVAL(array_ptr);
5988+ array_init(array_ptr);
5989+ INIT_PZVAL(array_ptr);
5990+ }
5991+ IF_G(cookie_array) = array_ptr;
5992+ break;
5993+ }
5994+ Z_STRLEN(new_var) = val_len;
5995+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5996+ Z_TYPE(new_var) = IS_STRING;
5997+
5998+ var_len = strlen(var);
5999+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
6000+ strcpy(raw_var, "RAW_");
6001+ strlcat(raw_var,var,var_len+5);
6002+
6003+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
6004+
6005+ php_strip_tags(*val, val_len, NULL, NULL, 0);
6006+
6007+ *new_val_len = strlen(*val);
6008+ return 1;
6009+}
6010+
6011+PHP_FUNCTION(my_get_raw)
6012+{
6013+ long arg;
6014+ char *var;
6015+ int var_len;
6016+ zval **tmp;
6017+ zval *array_ptr = NULL;
6018+ HashTable *hash_ptr;
6019+ char *raw_var;
6020+
6021+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
6022+ return;
6023+ }
6024+
6025+ switch(arg) {
6026+ case PARSE_GET:
6027+ array_ptr = IF_G(get_array);
6028+ break;
6029+ case PARSE_POST:
6030+ array_ptr = IF_G(post_array);
6031+ break;
6032+ case PARSE_COOKIE:
6033+ array_ptr = IF_G(post_array);
6034+ break;
6035+ }
6036+
6037+ if(!array_ptr) RETURN_FALSE;
6038+
6039+ /*
6040+ * I'm changing the variable name here because when running with register_globals on,
6041+ * the variable will end up in the global symbol table
6042+ */
6043+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
6044+ strcpy(raw_var, "RAW_");
6045+ strlcat(raw_var,var,var_len+5);
6046+ hash_ptr = HASH_OF(array_ptr);
6047+
6048+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
6049+ *return_value = **tmp;
6050+ zval_copy_ctor(return_value);
6051+ } else {
6052+ RETVAL_FALSE;
6053+ }
6054+ efree(raw_var);
6055+}
6056+
6057diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.11/run-tests.php
6058--- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100
6059+++ hardening-patch-4.4.2-0.4.11/run-tests.php 2006-05-13 18:01:56.000000000 +0200
6060@@ -152,6 +152,10 @@
6061 'error_reporting=2047',
6062 'display_errors=1',
6063 'log_errors=0',
6064+ 'hphp.executor.include.whitelist=cookietest',
6065+ 'hphp.log.syslog=0',
6066+ 'hphp.log.sapi=0',
6067+ 'hphp.log.script=0',
6068 'html_errors=0',
6069 'track_errors=1',
6070 'report_memleaks=1',
6071diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.11/sapi/apache/mod_php4.c
6072--- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100
6073+++ hardening-patch-4.4.2-0.4.11/sapi/apache/mod_php4.c 2006-05-13 18:01:56.000000000 +0200
6074@@ -452,7 +452,7 @@
6075 sapi_apache_get_fd,
6076 sapi_apache_force_http_10,
6077 sapi_apache_get_target_uid,
6078- sapi_apache_get_target_gid
6079+ sapi_apache_get_target_gid,
6080 };
6081 /* }}} */
6082
6083@@ -898,7 +898,11 @@
6084 {
6085 TSRMLS_FETCH();
6086 if (PG(expose_php)) {
6087+#if HARDENING_PATCH
6088+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
6089+#else
6090 ap_add_version_component("PHP/" PHP_VERSION);
6091+#endif
6092 }
6093 }
6094 #endif
6095diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.11/sapi/apache2filter/sapi_apache2.c
6096--- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6097+++ hardening-patch-4.4.2-0.4.11/sapi/apache2filter/sapi_apache2.c 2006-05-13 18:01:56.000000000 +0200
6098@@ -562,7 +562,11 @@
6099 {
6100 TSRMLS_FETCH();
6101 if (PG(expose_php)) {
6102+#if HARDENING_PATCH
6103+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6104+#else
6105 ap_add_version_component(p, "PHP/" PHP_VERSION);
6106+#endif
6107 }
6108 }
6109
6110diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.11/sapi/apache2handler/sapi_apache2.c
6111--- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
6112+++ hardening-patch-4.4.2-0.4.11/sapi/apache2handler/sapi_apache2.c 2006-05-13 18:01:56.000000000 +0200
6113@@ -340,7 +340,11 @@
6114 {
6115 TSRMLS_FETCH();
6116 if (PG(expose_php)) {
6117+#if HARDENING_PATCH
6118+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
6119+#else
6120 ap_add_version_component(p, "PHP/" PHP_VERSION);
6121+#endif
6122 }
6123 }
6124
6125diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.11/sapi/cgi/cgi_main.c
6126--- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100
6127+++ hardening-patch-4.4.2-0.4.11/sapi/cgi/cgi_main.c 2006-05-13 18:01:56.000000000 +0200
6128@@ -1432,11 +1432,19 @@
6129 SG(headers_sent) = 1;
6130 SG(request_info).no_headers = 1;
6131 }
6132+#if HARDENING_PATCH
6133+#if ZEND_DEBUG
6134+ 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());
6135+#else
6136+ 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());
6137+#endif
6138+#else
6139 #if ZEND_DEBUG
6140 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());
6141 #else
6142 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());
6143 #endif
6144+#endif
6145 php_end_ob_buffers(1 TSRMLS_CC);
6146 exit(0);
6147 break;
6148diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.11/sapi/cli/php_cli.c
6149--- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100
6150+++ hardening-patch-4.4.2-0.4.11/sapi/cli/php_cli.c 2006-05-13 18:01:56.000000000 +0200
6151@@ -654,11 +654,19 @@
6152 if (php_request_startup(TSRMLS_C)==FAILURE) {
6153 goto err;
6154 }
6155+#if HARDENING_PATCH
6156+#if ZEND_DEBUG
6157+ 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());
6158+#else
6159+ 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());
6160+#endif
6161+#else
6162 #if ZEND_DEBUG
6163 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());
6164 #else
6165 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());
6166 #endif
6167+#endif
6168 php_end_ob_buffers(1 TSRMLS_CC);
6169 exit_status=0;
6170 goto out;
6171diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.11/TSRM/TSRM.h
6172--- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
6173+++ hardening-patch-4.4.2-0.4.11/TSRM/TSRM.h 2006-05-13 18:01:56.000000000 +0200
6174@@ -33,6 +33,13 @@
6175 # define TSRM_API
6176 #endif
6177
6178+#if HARDENING_PATCH
6179+# if HAVE_REALPATH
6180+# undef realpath
6181+# define realpath php_realpath
6182+# endif
6183+#endif
6184+
6185 /* Only compile multi-threading functions if we're in ZTS mode */
6186 #ifdef ZTS
6187
6188@@ -84,6 +91,7 @@
6189
6190 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
6191
6192+
6193 #ifdef __cplusplus
6194 extern "C" {
6195 #endif
6196diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.11/TSRM/tsrm_virtual_cwd.c
6197--- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100
6198+++ hardening-patch-4.4.2-0.4.11/TSRM/tsrm_virtual_cwd.c 2006-05-13 18:03:04.000000000 +0200
6199@@ -179,6 +179,178 @@
6200 return p;
6201 }
6202
6203+#if HARDENING_PATCH
6204+CWD_API char *php_realpath(const char *path, char *resolved)
6205+{
6206+ struct stat sb;
6207+ char *p, *q, *s;
6208+ size_t left_len, resolved_len;
6209+ unsigned symlinks;
6210+ int serrno, slen;
6211+ int is_dir = 1;
6212+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
6213+
6214+ serrno = errno;
6215+ symlinks = 0;
6216+ if (path[0] == '/') {
6217+ resolved[0] = '/';
6218+ resolved[1] = '\0';
6219+ if (path[1] == '\0')
6220+ return (resolved);
6221+ resolved_len = 1;
6222+ left_len = strlcpy(left, path + 1, sizeof(left));
6223+ } else {
6224+ if (getcwd(resolved, PATH_MAX) == NULL) {
6225+ strlcpy(resolved, ".", PATH_MAX);
6226+ return (NULL);
6227+ }
6228+ resolved_len = strlen(resolved);
6229+ left_len = strlcpy(left, path, sizeof(left));
6230+ }
6231+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
6232+ errno = ENAMETOOLONG;
6233+ return (NULL);
6234+ }
6235+
6236+ /*
6237+ * Iterate over path components in `left'.
6238+ */
6239+ while (left_len != 0) {
6240+ /*
6241+ * Extract the next path component and adjust `left'
6242+ * and its length.
6243+ */
6244+ p = strchr(left, '/');
6245+ s = p ? p : left + left_len;
6246+ if (s - left >= sizeof(next_token)) {
6247+ errno = ENAMETOOLONG;
6248+ return (NULL);
6249+ }
6250+ memcpy(next_token, left, s - left);
6251+ next_token[s - left] = '\0';
6252+ left_len -= s - left;
6253+ if (p != NULL)
6254+ memmove(left, s + 1, left_len + 1);
6255+ if (resolved[resolved_len - 1] != '/') {
6256+ if (resolved_len + 1 >= PATH_MAX) {
6257+ errno = ENAMETOOLONG;
6258+ return (NULL);
6259+ }
6260+ resolved[resolved_len++] = '/';
6261+ resolved[resolved_len] = '\0';
6262+ }
6263+ if (next_token[0] == '\0')
6264+ continue;
6265+ else if (strcmp(next_token, ".") == 0)
6266+ continue;
6267+ else if (strcmp(next_token, "..") == 0) {
6268+ /*
6269+ * Strip the last path component except when we have
6270+ * single "/"
6271+ */
6272+ if (!is_dir) {
6273+ errno = ENOENT;
6274+ return (NULL);
6275+ }
6276+ if (resolved_len > 1) {
6277+ resolved[resolved_len - 1] = '\0';
6278+ q = strrchr(resolved, '/');
6279+ *q = '\0';
6280+ resolved_len = q - resolved;
6281+ }
6282+ continue;
6283+ }
6284+
6285+ /*
6286+ * Append the next path component and lstat() it. If
6287+ * lstat() fails we still can return successfully if
6288+ * there are no more path components left.
6289+ */
6290+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
6291+ if (resolved_len >= PATH_MAX) {
6292+ errno = ENAMETOOLONG;
6293+ return (NULL);
6294+ }
6295+ if (lstat(resolved, &sb) != 0) {
6296+ if (errno == ENOENT) {
6297+ if (p == NULL) {
6298+ errno = serrno;
6299+ return (resolved);
6300+ } else
6301+ /* dirty hack to support a vanilla PHP feature */
6302+ if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
6303+ resolved_len = strlcat(resolved, "/", PATH_MAX);
6304+ resolved_len = strlcat(resolved, left, PATH_MAX);
6305+ if (resolved_len >= PATH_MAX) {
6306+ errno = ENAMETOOLONG;
6307+ return (NULL);
6308+ }
6309+ errno = serrno;
6310+ return (resolved);
6311+ }
6312+ }
6313+ return (NULL);
6314+ }
6315+ if (S_ISLNK(sb.st_mode)) {
6316+ if (symlinks++ > MAXSYMLINKS) {
6317+ errno = ELOOP;
6318+ return (NULL);
6319+ }
6320+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6321+ if (slen < 0)
6322+ return (NULL);
6323+ symlink[slen] = '\0';
6324+ if (symlink[0] == '/') {
6325+ resolved[1] = 0;
6326+ resolved_len = 1;
6327+ } else if (resolved_len > 1) {
6328+ /* Strip the last path component. */
6329+ resolved[resolved_len - 1] = '\0';
6330+ q = strrchr(resolved, '/');
6331+ *q = '\0';
6332+ resolved_len = q - resolved;
6333+ }
6334+
6335+ /*
6336+ * If there are any path components left, then
6337+ * append them to symlink. The result is placed
6338+ * in `left'.
6339+ */
6340+ if (p != NULL) {
6341+ if (symlink[slen - 1] != '/') {
6342+ if (slen + 1 >= sizeof(symlink)) {
6343+ errno = ENAMETOOLONG;
6344+ return (NULL);
6345+ }
6346+ symlink[slen] = '/';
6347+ symlink[slen + 1] = 0;
6348+ }
6349+ left_len = strlcat(symlink, left, sizeof(left));
6350+ if (left_len >= sizeof(left)) {
6351+ errno = ENAMETOOLONG;
6352+ return (NULL);
6353+ }
6354+ }
6355+ left_len = strlcpy(left, symlink, sizeof(left));
6356+ } else {
6357+ if (S_ISDIR(sb.st_mode)) {
6358+ is_dir = 1;
6359+ } else {
6360+ is_dir = 0;
6361+ }
6362+ }
6363+ }
6364+
6365+ /*
6366+ * Remove trailing slash except when the resolved pathname
6367+ * is a single "/".
6368+ */
6369+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6370+ resolved[resolved_len - 1] = '\0';
6371+ return (resolved);
6372+}
6373+#endif
6374+
6375 CWD_API void virtual_cwd_startup(void)
6376 {
6377 char cwd[MAXPATHLEN];
6378@@ -300,8 +472,11 @@
6379
6380 if (path_length == 0)
6381 return (0);
6382- if (path_length >= MAXPATHLEN)
6383+ if (path_length >= MAXPATHLEN) {
6384+ state->cwd[0] = 0;
6385+ state->cwd_length = 0;
6386 return (1);
6387+ }
6388
6389 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6390 /* cwd_length can be 0 when getcwd() fails.
6391@@ -313,8 +488,9 @@
6392 path = resolved_path;
6393 path_length = strlen(path);
6394 } else {
6395- /* disable for now
6396- return 1; */
6397+ state->cwd[0] = 0;
6398+ state->cwd_length = 0;
6399+ return 1;
6400 }
6401 }
6402 } else { /* Concat current directory with relative path and then run realpath() on it */
6403@@ -323,6 +499,8 @@
6404
6405 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6406 if (!tmp) {
6407+ state->cwd[0] = 0;
6408+ state->cwd_length = 0;
6409 return 1;
6410 }
6411 memcpy(ptr, state->cwd, state->cwd_length);
6412@@ -332,6 +510,8 @@
6413 ptr += path_length;
6414 *ptr = '\0';
6415 if (strlen(tmp) >= MAXPATHLEN) {
6416+ state->cwd[0] = 0;
6417+ state->cwd_length = 0;
6418 free(tmp);
6419 return 1;
6420 }
6421@@ -340,9 +520,10 @@
6422 path = resolved_path;
6423 path_length = strlen(path);
6424 } else {
6425- /* disable for now
6426+ state->cwd[0] = 0;
6427+ state->cwd_length = 0;
6428 free(tmp);
6429- return 1; */
6430+ return 1;
6431 }
6432 }
6433 free(tmp);
6434diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.11/TSRM/tsrm_virtual_cwd.h
6435--- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100
6436+++ hardening-patch-4.4.2-0.4.11/TSRM/tsrm_virtual_cwd.h 2006-05-13 18:01:56.000000000 +0200
6437@@ -128,6 +128,22 @@
6438
6439 typedef int (*verify_path_func)(const cwd_state *);
6440
6441+#ifndef HAVE_STRLCPY
6442+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6443+#undef strlcpy
6444+#define strlcpy php_strlcpy
6445+#endif
6446+
6447+#ifndef HAVE_STRLCAT
6448+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6449+#undef strlcat
6450+#define strlcat php_strlcat
6451+#endif
6452+
6453+
6454+#if HARDENING_PATCH
6455+CWD_API char *php_realpath(const char *path, char *resolved);
6456+#endif
6457 CWD_API void virtual_cwd_startup(void);
6458 CWD_API void virtual_cwd_shutdown(void);
6459 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6460diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.11/Zend/zend_alloc.c
6461--- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100
6462+++ hardening-patch-4.4.2-0.4.11/Zend/zend_alloc.c 2006-05-13 18:01:56.000000000 +0200
6463@@ -56,6 +56,11 @@
6464 # define END_MAGIC_SIZE 0
6465 #endif
6466
6467+#if HARDENING_PATCH_MM_PROTECT
6468+# define CANARY_SIZE sizeof(unsigned int)
6469+#else
6470+# define CANARY_SIZE 0
6471+#endif
6472
6473 # if MEMORY_LIMIT
6474 # if ZEND_DEBUG
6475@@ -96,9 +101,17 @@
6476 if (p==AG(head)) { \
6477 AG(head) = p->pNext; \
6478 } else { \
6479+ if (p != p->pLast->pNext) { \
6480+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6481+ exit(1); \
6482+ } \
6483 p->pLast->pNext = p->pNext; \
6484 } \
6485 if (p->pNext) { \
6486+ if (p != p->pNext->pLast) { \
6487+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6488+ exit(1); \
6489+ } \
6490 p->pNext->pLast = p->pLast; \
6491 }
6492
6493@@ -130,6 +143,12 @@
6494 DECLARE_CACHE_VARS();
6495 TSRMLS_FETCH();
6496
6497+#if HARDENING_PATCH_MM_PROTECT
6498+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6499+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6500+ exit(1);
6501+ }
6502+#endif
6503 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6504
6505 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6506@@ -147,6 +166,10 @@
6507 AG(cache_stats)[CACHE_INDEX][1]++;
6508 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6509 #endif
6510+#if HARDENING_PATCH_MM_PROTECT
6511+ p->canary = HG(canary_1);
6512+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6513+#endif
6514 p->cached = 0;
6515 p->size = size;
6516 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6517@@ -162,7 +185,7 @@
6518 AG(allocated_memory_peak) = AG(allocated_memory);
6519 }
6520 #endif
6521- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6522+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6523 }
6524
6525 HANDLE_BLOCK_INTERRUPTIONS();
6526@@ -192,7 +215,10 @@
6527 # endif
6528 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6529 #endif
6530-
6531+#if HARDENING_PATCH_MM_PROTECT
6532+ p->canary = HG(canary_1);
6533+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6534+#endif
6535 HANDLE_UNBLOCK_INTERRUPTIONS();
6536 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6537 }
6538@@ -219,17 +245,36 @@
6539 return emalloc_rel(lval + offset);
6540 }
6541 }
6542-
6543+
6544+#if HARDENING_PATCH
6545+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6546+#endif
6547 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6548 return 0;
6549 }
6550
6551 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6552 {
6553+#if HARDENING_PATCH_MM_PROTECT
6554+ unsigned int canary_2;
6555+#endif
6556 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6557 DECLARE_CACHE_VARS();
6558 TSRMLS_FETCH();
6559
6560+#if HARDENING_PATCH_MM_PROTECT
6561+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6562+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6563+ if (canary_2 != HG(canary_2)) {
6564+efree_canary_mismatch:
6565+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6566+ exit(1);
6567+ }
6568+ /* to catch double efree()s */
6569+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6570+ p->canary = 0;
6571+#endif
6572+
6573 #if defined(ZTS) && TSRM_DEBUG
6574 if (p->thread_id != tsrm_thread_id()) {
6575 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6576@@ -274,6 +319,9 @@
6577 size_t _size = nmemb * size;
6578
6579 if (nmemb && (_size/nmemb!=size)) {
6580+#if HARDENING_PATCH
6581+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6582+#endif
6583 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6584 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6585 kill(getpid(), SIGSEGV);
6586@@ -293,6 +341,9 @@
6587
6588 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6589 {
6590+#if HARDENING_PATCH_MM_PROTECT
6591+ unsigned int canary_2;
6592+#endif
6593 zend_mem_header *p;
6594 zend_mem_header *orig;
6595 DECLARE_CACHE_VARS();
6596@@ -304,6 +355,16 @@
6597
6598 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6599
6600+#if HARDENING_PATCH_MM_PROTECT
6601+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6602+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6603+ if (canary_2 != HG(canary_2)) {
6604+erealloc_canary_mismatch:
6605+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6606+ exit(1);
6607+ }
6608+#endif
6609+
6610 #if defined(ZTS) && TSRM_DEBUG
6611 if (p->thread_id != tsrm_thread_id()) {
6612 void *new_p;
6613@@ -327,7 +388,7 @@
6614 }
6615 #endif
6616 REMOVE_POINTER_FROM_LIST(p);
6617- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6618+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6619 if (!p) {
6620 if (!allow_failure) {
6621 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6622@@ -349,6 +410,9 @@
6623 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6624 #endif
6625
6626+#if HARDENING_PATCH_MM_PROTECT
6627+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6628+#endif
6629 p->size = size;
6630
6631 HANDLE_UNBLOCK_INTERRUPTIONS();
6632@@ -423,6 +487,10 @@
6633 {
6634 AG(head) = NULL;
6635
6636+#if HARDENING_PATCH_MM_PROTECT
6637+ HG(canary_1) = zend_canary();
6638+ HG(canary_2) = zend_canary();
6639+#endif
6640 #if MEMORY_LIMIT
6641 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6642 AG(allocated_memory) = 0;
6643diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.11/Zend/zend_alloc.h
6644--- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100
6645+++ hardening-patch-4.4.2-0.4.11/Zend/zend_alloc.h 2006-05-13 18:01:56.000000000 +0200
6646@@ -32,6 +32,9 @@
6647 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6648
6649 typedef struct _zend_mem_header {
6650+#if HARDENING_PATCH_MM_PROTECT
6651+ unsigned int canary;
6652+#endif
6653 #if ZEND_DEBUG
6654 long magic;
6655 char *filename;
6656diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.11/Zend/zend_builtin_functions.c
6657--- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100
6658+++ hardening-patch-4.4.2-0.4.11/Zend/zend_builtin_functions.c 2006-05-13 18:01:56.000000000 +0200
6659@@ -49,6 +49,9 @@
6660 static ZEND_FUNCTION(crash);
6661 #endif
6662 #endif
6663+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6664+static ZEND_FUNCTION(heap_overflow);
6665+#endif
6666 static ZEND_FUNCTION(get_included_files);
6667 static ZEND_FUNCTION(is_subclass_of);
6668 static ZEND_FUNCTION(is_a);
6669@@ -101,6 +104,9 @@
6670 ZEND_FE(crash, NULL)
6671 #endif
6672 #endif
6673+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6674+ ZEND_FE(heap_overflow, NULL)
6675+#endif
6676 ZEND_FE(get_included_files, NULL)
6677 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6678 ZEND_FE(is_subclass_of, NULL)
6679@@ -805,6 +811,19 @@
6680
6681 #endif /* ZEND_DEBUG */
6682
6683+
6684+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6685+ZEND_FUNCTION(heap_overflow)
6686+{
6687+ char *nowhere = emalloc(10);
6688+
6689+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6690+
6691+ efree(nowhere);
6692+}
6693+#endif
6694+
6695+
6696 /* {{{ proto array get_included_files(void)
6697 Returns an array with the file names that were include_once()'d */
6698 ZEND_FUNCTION(get_included_files)
6699diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.11/Zend/zend.c
6700--- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100
6701+++ hardening-patch-4.4.2-0.4.11/Zend/zend.c 2006-05-13 18:01:56.000000000 +0200
6702@@ -53,6 +53,12 @@
6703 ZEND_API void (*zend_unblock_interruptions)(void);
6704 ZEND_API void (*zend_ticks_function)(int ticks);
6705 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6706+#if HARDENING_PATCH
6707+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6708+#endif
6709+#if HARDENING_PATCH_INC_PROTECT
6710+ZEND_API int (*zend_is_valid_include)(zval *z);
6711+#endif
6712
6713 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6714
6715@@ -70,9 +76,390 @@
6716 return SUCCESS;
6717 }
6718
6719+#if HARDENING_PATCH
6720+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6721+{
6722+ if (!new_value) {
6723+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6724+ } else {
6725+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6726+ }
6727+ return SUCCESS;
6728+}
6729+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6730+{
6731+ if (!new_value) {
6732+ EG(hphp_log_syslog_facility) = LOG_USER;
6733+ } else {
6734+ EG(hphp_log_syslog_facility) = atoi(new_value);
6735+ }
6736+ return SUCCESS;
6737+}
6738+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6739+{
6740+ if (!new_value) {
6741+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6742+ } else {
6743+ EG(hphp_log_syslog_priority) = atoi(new_value);
6744+ }
6745+ return SUCCESS;
6746+}
6747+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6748+{
6749+ if (!new_value) {
6750+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6751+ } else {
6752+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6753+ }
6754+ return SUCCESS;
6755+}
6756+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6757+{
6758+ if (!new_value) {
6759+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6760+ } else {
6761+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6762+ }
6763+ return SUCCESS;
6764+}
6765+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6766+{
6767+ if (EG(hphp_log_scriptname)) {
6768+ pefree(EG(hphp_log_scriptname),1);
6769+ }
6770+ EG(hphp_log_scriptname) = NULL;
6771+ if (new_value) {
6772+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6773+ }
6774+ return SUCCESS;
6775+}
6776+
6777+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6778+{
6779+ char *s = NULL, *e, *val;
6780+ unsigned long dummy = 1;
6781+
6782+ if (!new_value) {
6783+include_whitelist_destroy:
6784+ if (HG(include_whitelist)) {
6785+ zend_hash_destroy(HG(include_whitelist));
6786+ pefree(HG(include_whitelist),1);
6787+ }
6788+ HG(include_whitelist) = NULL;
6789+ return SUCCESS;
6790+ }
6791+ if (!(*new_value)) {
6792+ goto include_whitelist_destroy;
6793+ }
6794+
6795+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6796+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6797+
6798+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6799+ e = val;
6800+
6801+ while (*e) {
6802+ switch (*e) {
6803+ case ' ':
6804+ case ',':
6805+ if (s) {
6806+ *e = '\0';
6807+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6808+ s = NULL;
6809+ }
6810+ break;
6811+ default:
6812+ if (!s) {
6813+ s = e;
6814+ }
6815+ break;
6816+ }
6817+ e++;
6818+ }
6819+ if (s) {
6820+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6821+ }
6822+ efree(val);
6823+
6824+ return SUCCESS;
6825+}
6826+
6827+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6828+{
6829+ char *s = NULL, *e, *val;
6830+ unsigned long dummy = 1;
6831+
6832+ if (!new_value) {
6833+include_blacklist_destroy:
6834+ if (HG(include_blacklist)) {
6835+ zend_hash_destroy(HG(include_blacklist));
6836+ pefree(HG(include_blacklist),1);
6837+ }
6838+ HG(include_blacklist) = NULL;
6839+ return SUCCESS;
6840+ }
6841+ if (!(*new_value)) {
6842+ goto include_blacklist_destroy;
6843+ }
6844+
6845+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6846+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6847+
6848+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6849+ e = val;
6850+
6851+ while (*e) {
6852+ switch (*e) {
6853+ case ' ':
6854+ case ',':
6855+ if (s) {
6856+ *e = '\0';
6857+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6858+ s = NULL;
6859+ }
6860+ break;
6861+ default:
6862+ if (!s) {
6863+ s = e;
6864+ }
6865+ break;
6866+ }
6867+ e++;
6868+ }
6869+ if (s) {
6870+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6871+ }
6872+ efree(val);
6873+
6874+ return SUCCESS;
6875+}
6876+
6877+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6878+{
6879+ char *s = NULL, *e, *val;
6880+ unsigned long dummy = 1;
6881+
6882+ if (!new_value) {
6883+eval_whitelist_destroy:
6884+ if (HG(eval_whitelist)) {
6885+ zend_hash_destroy(HG(eval_whitelist));
6886+ pefree(HG(eval_whitelist),1);
6887+ }
6888+ HG(eval_whitelist) = NULL;
6889+ return SUCCESS;
6890+ }
6891+ if (!(*new_value)) {
6892+ goto eval_whitelist_destroy;
6893+ }
6894+
6895+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6896+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6897+
6898+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6899+ e = val;
6900+
6901+ while (*e) {
6902+ switch (*e) {
6903+ case ' ':
6904+ case ',':
6905+ if (s) {
6906+ *e = '\0';
6907+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6908+ s = NULL;
6909+ }
6910+ break;
6911+ default:
6912+ if (!s) {
6913+ s = e;
6914+ }
6915+ break;
6916+ }
6917+ e++;
6918+ }
6919+ if (s) {
6920+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6921+ }
6922+ efree(val);
6923+
6924+ return SUCCESS;
6925+}
6926+
6927+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6928+{
6929+ char *s = NULL, *e, *val;
6930+ unsigned long dummy = 1;
6931+
6932+ if (!new_value) {
6933+eval_blacklist_destroy:
6934+ if (HG(eval_blacklist)) {
6935+ zend_hash_destroy(HG(eval_blacklist));
6936+ pefree(HG(eval_blacklist), 1);
6937+ }
6938+ HG(eval_blacklist) = NULL;
6939+ return SUCCESS;
6940+ }
6941+ if (!(*new_value)) {
6942+ goto eval_blacklist_destroy;
6943+ }
6944+
6945+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6946+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6947+
6948+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6949+ e = val;
6950+
6951+ while (*e) {
6952+ switch (*e) {
6953+ case ' ':
6954+ case ',':
6955+ if (s) {
6956+ *e = '\0';
6957+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6958+ s = NULL;
6959+ }
6960+ break;
6961+ default:
6962+ if (!s) {
6963+ s = e;
6964+ }
6965+ break;
6966+ }
6967+ e++;
6968+ }
6969+ if (s) {
6970+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6971+ }
6972+ efree(val);
6973+
6974+
6975+ return SUCCESS;
6976+}
6977+
6978+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6979+{
6980+ char *s = NULL, *e, *val;
6981+ unsigned long dummy = 1;
6982+
6983+ if (!new_value) {
6984+func_whitelist_destroy:
6985+ if (HG(func_whitelist)) {
6986+ zend_hash_destroy(HG(func_whitelist));
6987+ pefree(HG(func_whitelist),1);
6988+ }
6989+ HG(func_whitelist) = NULL;
6990+ return SUCCESS;
6991+ }
6992+ if (!(*new_value)) {
6993+ goto func_whitelist_destroy;
6994+ }
6995+
6996+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6997+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6998+
6999+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7000+ e = val;
7001+
7002+ while (*e) {
7003+ switch (*e) {
7004+ case ' ':
7005+ case ',':
7006+ if (s) {
7007+ *e = '\0';
7008+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7009+ s = NULL;
7010+ }
7011+ break;
7012+ default:
7013+ if (!s) {
7014+ s = e;
7015+ }
7016+ break;
7017+ }
7018+ e++;
7019+ }
7020+ if (s) {
7021+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7022+ }
7023+ efree(val);
7024+
7025+ return SUCCESS;
7026+}
7027+
7028+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
7029+{
7030+ char *s = NULL, *e, *val;
7031+ unsigned long dummy = 1;
7032+
7033+ if (!new_value) {
7034+func_blacklist_destroy:
7035+ if (HG(func_blacklist)) {
7036+ zend_hash_destroy(HG(func_blacklist));
7037+ pefree(HG(func_blacklist),1);
7038+ }
7039+ HG(func_blacklist) = NULL;
7040+ return SUCCESS;
7041+ }
7042+ if (!(*new_value)) {
7043+ goto func_blacklist_destroy;
7044+ }
7045+
7046+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
7047+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
7048+
7049+ val = zend_str_tolower_dup(new_value, strlen(new_value));
7050+ e = val;
7051+
7052+ while (*e) {
7053+ switch (*e) {
7054+ case ' ':
7055+ case ',':
7056+ if (s) {
7057+ *e = '\0';
7058+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7059+ s = NULL;
7060+ }
7061+ break;
7062+ default:
7063+ if (!s) {
7064+ s = e;
7065+ }
7066+ break;
7067+ }
7068+ e++;
7069+ }
7070+ if (s) {
7071+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
7072+ }
7073+ efree(val);
7074+
7075+
7076+ return SUCCESS;
7077+}
7078+
7079+#endif
7080
7081 ZEND_INI_BEGIN()
7082 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
7083+#if HARDENING_PATCH
7084+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
7085+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
7086+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
7087+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
7088+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
7089+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
7090+ 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)
7091+
7092+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
7093+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
7094+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
7095+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
7096+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
7097+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
7098+
7099+ 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)
7100+ 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)
7101+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
7102+#endif
7103 ZEND_INI_END()
7104
7105
7106@@ -354,8 +741,12 @@
7107 zend_init_rsrc_plist(TSRMLS_C);
7108 EG(lambda_count)=0;
7109 EG(user_error_handler) = NULL;
7110+ EG(in_code_type) = 0;
7111 EG(in_execution) = 0;
7112 EG(current_execute_data) = NULL;
7113+#if HARDENING_PATCH
7114+ EG(hphp_log_scriptname) = NULL;
7115+#endif
7116 }
7117
7118
7119@@ -420,6 +811,14 @@
7120 extern zend_scanner_globals language_scanner_globals;
7121 #endif
7122
7123+ /* Set up Hardening-Patch utility functions first */
7124+#if HARDENING_PATCH
7125+ zend_security_log = utility_functions->security_log_function;
7126+#endif
7127+#if HARDENING_PATCH_INC_PROTECT
7128+ zend_is_valid_include = utility_functions->is_valid_include;
7129+#endif
7130+
7131 #ifdef ZTS
7132 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
7133 #else
7134@@ -619,6 +1018,7 @@
7135 }
7136 CG(unclean_shutdown) = 1;
7137 CG(in_compilation) = EG(in_execution) = 0;
7138+ EG(in_code_type) = 0;
7139 EG(current_execute_data) = NULL;
7140 longjmp(EG(bailout), FAILURE);
7141 }
7142diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.11/Zend/zend_canary.c
7143--- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
7144+++ hardening-patch-4.4.2-0.4.11/Zend/zend_canary.c 2006-05-13 18:01:56.000000000 +0200
7145@@ -0,0 +1,58 @@
7146+/*
7147+ +----------------------------------------------------------------------+
7148+ | Hardening-Patch for PHP |
7149+ +----------------------------------------------------------------------+
7150+ | Copyright (c) 2004-2005 Stefan Esser |
7151+ +----------------------------------------------------------------------+
7152+ | This source file is subject to version 2.02 of the PHP license, |
7153+ | that is bundled with this package in the file LICENSE, and is |
7154+ | available at through the world-wide-web at |
7155+ | http://www.php.net/license/2_02.txt. |
7156+ | If you did not receive a copy of the PHP license and are unable to |
7157+ | obtain it through the world-wide-web, please send a note to |
7158+ | license@php.net so we can mail you a copy immediately. |
7159+ +----------------------------------------------------------------------+
7160+ | Author: Stefan Esser <sesser@hardened-php.net> |
7161+ +----------------------------------------------------------------------+
7162+ */
7163+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
7164+
7165+#include "zend.h"
7166+
7167+#include <stdio.h>
7168+#include <stdlib.h>
7169+
7170+
7171+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7172+
7173+/* will be replaced later with more compatible method */
7174+ZEND_API unsigned int zend_canary()
7175+{
7176+ time_t t;
7177+ unsigned int canary;
7178+ int fd;
7179+
7180+ fd = open("/dev/urandom", 0);
7181+ if (fd != -1) {
7182+ int r = read(fd, &canary, sizeof(canary));
7183+ close(fd);
7184+ if (r == sizeof(canary)) {
7185+ return (canary);
7186+ }
7187+ }
7188+ /* not good but we never want to do this */
7189+ time(&t);
7190+ canary = *(unsigned int *)&t + getpid() << 16;
7191+ return (canary);
7192+}
7193+#endif
7194+
7195+
7196+/*
7197+ * Local variables:
7198+ * tab-width: 4
7199+ * c-basic-offset: 4
7200+ * End:
7201+ * vim600: sw=4 ts=4 fdm=marker
7202+ * vim<600: sw=4 ts=4
7203+ */
7204diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.11/Zend/zend_compile.c
7205--- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100
7206+++ hardening-patch-4.4.2-0.4.11/Zend/zend_compile.c 2006-05-13 18:01:56.000000000 +0200
7207@@ -768,6 +768,13 @@
7208 op_array.function_name = name;
7209 op_array.arg_types = NULL;
7210 op_array.return_reference = return_reference;
7211+#if HARDENING_PATCH
7212+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7213+ op_array.created_by_eval = 1;
7214+ } else {
7215+ op_array.created_by_eval = 0;
7216+ }
7217+#endif
7218
7219 if (is_method) {
7220 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
7221diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.11/Zend/zend_compile.h
7222--- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100
7223+++ hardening-patch-4.4.2-0.4.11/Zend/zend_compile.h 2006-05-13 18:01:56.000000000 +0200
7224@@ -106,6 +106,9 @@
7225 char *filename;
7226
7227 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
7228+#if HARDENING_PATCH
7229+ zend_bool created_by_eval;
7230+#endif
7231 };
7232
7233
7234@@ -549,6 +552,7 @@
7235 #define ZEND_USER_FUNCTION 2
7236 #define ZEND_OVERLOADED_FUNCTION 3
7237 #define ZEND_EVAL_CODE 4
7238+#define ZEND_SANDBOX_CODE 6
7239
7240 #define ZEND_INTERNAL_CLASS 1
7241 #define ZEND_USER_CLASS 2
7242diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.11/Zend/zend_constants.c
7243--- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100
7244+++ hardening-patch-4.4.2-0.4.11/Zend/zend_constants.c 2006-05-13 18:01:56.000000000 +0200
7245@@ -111,6 +111,73 @@
7246 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
7247
7248 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
7249+#if HARDENING_PATCH
7250+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
7251+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
7252+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
7253+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
7254+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
7255+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
7256+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
7257+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
7258+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
7259+
7260+ /* error levels */
7261+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
7262+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
7263+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
7264+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
7265+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
7266+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
7267+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
7268+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
7269+ /* facility: type of program logging the message */
7270+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
7271+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
7272+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
7273+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
7274+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
7275+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
7276+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
7277+#ifdef LOG_NEWS
7278+ /* No LOG_NEWS on HP-UX */
7279+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
7280+#endif
7281+#ifdef LOG_UUCP
7282+ /* No LOG_UUCP on HP-UX */
7283+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
7284+#endif
7285+#ifdef LOG_CRON
7286+ /* apparently some systems don't have this one */
7287+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
7288+#endif
7289+#ifdef LOG_AUTHPRIV
7290+ /* AIX doesn't have LOG_AUTHPRIV */
7291+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
7292+#endif
7293+#if !defined(PHP_WIN32) && !defined(NETWARE)
7294+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
7295+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
7296+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
7297+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
7298+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
7299+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
7300+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
7301+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
7302+#endif
7303+ /* options */
7304+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
7305+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
7306+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
7307+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
7308+#ifdef LOG_NOWAIT
7309+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7310+#endif
7311+#ifdef LOG_PERROR
7312+ /* AIX doesn't have LOG_PERROR */
7313+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7314+#endif
7315+#endif
7316
7317 /* true/false constants */
7318 {
7319diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.11/Zend/zend_errors.h
7320--- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100
7321+++ hardening-patch-4.4.2-0.4.11/Zend/zend_errors.h 2006-05-13 18:01:56.000000000 +0200
7322@@ -36,5 +36,17 @@
7323 #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)
7324 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7325
7326+#if HARDENING_PATCH
7327+#define S_MEMORY (1<<0L)
7328+#define S_VARS (1<<1L)
7329+#define S_FILES (1<<2L)
7330+#define S_INCLUDE (1<<3L)
7331+#define S_SQL (1<<4L)
7332+#define S_EXECUTOR (1<<5L)
7333+#define S_MISC (1<<30L)
7334+#define S_INTERNAL (1<<29L)
7335+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
7336+#endif
7337+
7338 #endif /* ZEND_ERRORS_H */
7339
7340diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.11/Zend/zend_execute_API.c
7341--- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100
7342+++ hardening-patch-4.4.2-0.4.11/Zend/zend_execute_API.c 2006-05-13 18:01:56.000000000 +0200
7343@@ -142,6 +142,7 @@
7344 EG(class_table) = CG(class_table);
7345
7346 EG(in_execution) = 0;
7347+ EG(in_code_type) = 0;
7348
7349 zend_ptr_stack_init(&EG(argument_stack));
7350
7351@@ -431,12 +432,14 @@
7352 zend_execute_data execute_data;
7353
7354 /* Initialize execute_data */
7355+ memset(&execute_data, 0, sizeof(execute_data));
7356 EX(fbc) = NULL;
7357 EX(object).ptr = NULL;
7358 EX(ce) = NULL;
7359 EX(Ts) = NULL;
7360 EX(op_array) = NULL;
7361 EX(opline) = NULL;
7362+ EX(execute_depth) = 0;
7363
7364 *retval_ptr_ptr = NULL;
7365
7366@@ -494,6 +497,39 @@
7367 zval_dtor(&function_name_copy);
7368 return FAILURE;
7369 }
7370+#if HARDENING_PATCH
7371+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7372+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7373+ if (HG(eval_whitelist) != NULL) {
7374+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7375+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7376+ zval_dtor(&function_name_copy);
7377+ zend_bailout();
7378+ }
7379+ } else if (HG(eval_blacklist) != NULL) {
7380+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7381+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7382+ zval_dtor(&function_name_copy);
7383+ zend_bailout();
7384+ }
7385+ }
7386+ }
7387+
7388+ if (HG(func_whitelist) != NULL) {
7389+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7390+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7391+ zval_dtor(&function_name_copy);
7392+ zend_bailout();
7393+ }
7394+ } else if (HG(func_blacklist) != NULL) {
7395+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7396+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7397+ zval_dtor(&function_name_copy);
7398+ zend_bailout();
7399+ }
7400+ }
7401+ }
7402+#endif
7403 zval_dtor(&function_name_copy);
7404
7405 for (i=0; i<param_count; i++) {
7406@@ -606,8 +642,7 @@
7407 return SUCCESS;
7408 }
7409
7410-
7411-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7412+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7413 {
7414 zval pv;
7415 zend_op_array *new_op_array;
7416@@ -640,6 +675,7 @@
7417 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7418 zend_op **original_opline_ptr = EG(opline_ptr);
7419
7420+ new_op_array->type = type;
7421 EG(return_value_ptr_ptr) = &local_retval_ptr;
7422 EG(active_op_array) = new_op_array;
7423 EG(no_extensions)=1;
7424@@ -673,6 +709,10 @@
7425 return retval;
7426 }
7427
7428+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7429+{
7430+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7431+}
7432
7433 void execute_new_code(TSRMLS_D)
7434 {
7435diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.11/Zend/zend_execute.c
7436--- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100
7437+++ hardening-patch-4.4.2-0.4.11/Zend/zend_execute.c 2006-05-13 18:01:56.000000000 +0200
7438@@ -1042,6 +1042,7 @@
7439 zend_execute_data execute_data;
7440
7441 /* Initialize execute_data */
7442+ memset(&execute_data, 0, sizeof(execute_data));
7443 EX(fbc) = NULL;
7444 EX(ce) = NULL;
7445 EX(object).ptr = NULL;
7446@@ -1053,9 +1054,21 @@
7447 }
7448 EX(prev_execute_data) = EG(current_execute_data);
7449 EX(original_in_execution)=EG(in_execution);
7450+ EX(original_in_code_type)=EG(in_code_type);
7451
7452 EG(current_execute_data) = &execute_data;
7453
7454+#if HARDENING_PATCH
7455+ EX(execute_depth) = 0;
7456+
7457+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7458+ EG(in_code_type) = ZEND_EVAL_CODE;
7459+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7460+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7461+ op_array->type = ZEND_EVAL_CODE;
7462+ }
7463+#endif
7464+
7465 EG(in_execution) = 1;
7466 if (op_array->start_op) {
7467 EX(opline) = op_array->start_op;
7468@@ -1087,6 +1100,19 @@
7469 }
7470 }
7471
7472+#if HARDENING_PATCH
7473+ if (EX(prev_execute_data) == NULL) {
7474+ EX(execute_depth) = 0;
7475+ } else {
7476+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7477+ }
7478+
7479+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7480+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7481+ zend_bailout();
7482+ }
7483+#endif
7484+
7485 while (1) {
7486 #ifdef ZEND_WIN32
7487 if (EG(timed_out)) {
7488@@ -1634,6 +1660,36 @@
7489 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7490 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7491 }
7492+#if HARDENING_PATCH
7493+ if (active_function_table == EG(function_table)) {
7494+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7495+ if (HG(eval_whitelist) != NULL) {
7496+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7497+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7498+ zend_bailout();
7499+ }
7500+ } else if (HG(eval_blacklist) != NULL) {
7501+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7502+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7503+ zend_bailout();
7504+ }
7505+ }
7506+ }
7507+
7508+ if (HG(func_whitelist) != NULL) {
7509+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7510+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7511+ zend_bailout();
7512+ }
7513+ } else if (HG(func_blacklist) != NULL) {
7514+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7515+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7516+ zend_bailout();
7517+ }
7518+ }
7519+ }
7520+#endif
7521+
7522 zval_dtor(&tmp);
7523 EX(fbc) = function;
7524 overloaded_function_call_cont:
7525@@ -1649,6 +1705,35 @@
7526 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7527 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7528 }
7529+#if HARDENING_PATCH
7530+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7531+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7532+ if (HG(eval_whitelist) != NULL) {
7533+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7534+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7535+ zend_bailout();
7536+ }
7537+ } else if (HG(eval_blacklist) != NULL) {
7538+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7539+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7540+ zend_bailout();
7541+ }
7542+ }
7543+ }
7544+
7545+ if (HG(func_whitelist) != NULL) {
7546+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7547+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7548+ zend_bailout();
7549+ }
7550+ } else if (HG(func_blacklist) != NULL) {
7551+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7552+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7553+ zend_bailout();
7554+ }
7555+ }
7556+ }
7557+#endif
7558 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7559 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7560 EX(object).ptr = NULL;
7561@@ -1821,6 +1906,7 @@
7562 efree(EX(Ts));
7563 }
7564 EG(in_execution) = EX(original_in_execution);
7565+ EG(in_code_type) = EX(original_in_code_type);
7566 EG(current_execute_data) = EX(prev_execute_data);
7567 return;
7568 }
7569@@ -2210,7 +2296,12 @@
7570 int dummy = 1;
7571 zend_file_handle file_handle = {0};
7572
7573+#if HARDENING_PATCH_INC_PROTECT
7574+ if (zend_is_valid_include(inc_filename)
7575+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7576+#else
7577 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7578+#endif
7579 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7580
7581 file_handle.filename = inc_filename->value.str.val;
7582@@ -2239,6 +2330,11 @@
7583 break;
7584 case ZEND_INCLUDE:
7585 case ZEND_REQUIRE:
7586+#if HARDENING_PATCH_INC_PROTECT
7587+ if (!zend_is_valid_include(inc_filename)) {
7588+ break;
7589+ }
7590+#endif
7591 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7592 break;
7593 case ZEND_EVAL: {
7594diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.11/Zend/zend_execute_globals.h
7595--- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100
7596+++ hardening-patch-4.4.2-0.4.11/Zend/zend_execute_globals.h 2006-05-13 18:01:56.000000000 +0200
7597@@ -60,6 +60,8 @@
7598 object_info object;
7599 temp_variable *Ts;
7600 zend_bool original_in_execution;
7601+ zend_uint original_in_code_type;
7602+ zend_uint execute_depth;
7603 zend_op_array *op_array;
7604 struct _zend_execute_data *prev_execute_data;
7605 } zend_execute_data;
7606diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.11/Zend/zend_extensions.c
7607--- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100
7608+++ hardening-patch-4.4.2-0.4.11/Zend/zend_extensions.c 2006-05-13 18:01:56.000000000 +0200
7609@@ -54,23 +54,44 @@
7610 return FAILURE;
7611 }
7612
7613+ /* check if module is compiled against Hardening-Patch */
7614+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7615+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7616+ "The Hardening-Patch version %d is installed.\n\n",
7617+ new_extension->name,
7618+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7619+ DL_UNLOAD(handle);
7620+ return FAILURE;
7621+ }
7622+
7623+
7624+ /* check if module is compiled against correct Hardening-Patch version */
7625+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7626+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7627+ "The Hardening-Patch version %d is installed.\n\n",
7628+ new_extension->name,
7629+ extension_version_info->zend_extension_api_no,
7630+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7631+ DL_UNLOAD(handle);
7632+ return FAILURE;
7633+ }
7634
7635 /* allow extension to proclaim compatibility with any Zend version */
7636- 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)) {
7637- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7638+ 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)) {
7639+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7640 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7641 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7642 new_extension->name,
7643- extension_version_info->zend_extension_api_no,
7644+ extension_version_info->real_zend_extension_api_no,
7645 ZEND_EXTENSION_API_NO);
7646 DL_UNLOAD(handle);
7647 return FAILURE;
7648- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7649+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7650 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7651 "The Zend Engine API version %d which is installed, is newer.\n"
7652 "Contact %s at %s for a later version of %s.\n\n",
7653 new_extension->name,
7654- extension_version_info->zend_extension_api_no,
7655+ extension_version_info->real_zend_extension_api_no,
7656 ZEND_EXTENSION_API_NO,
7657 new_extension->author,
7658 new_extension->URL,
7659diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.11/Zend/zend_extensions.h
7660--- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100
7661+++ hardening-patch-4.4.2-0.4.11/Zend/zend_extensions.h 2006-05-13 18:01:56.000000000 +0200
7662@@ -23,6 +23,9 @@
7663
7664 #include "zend_compile.h"
7665
7666+/* Create own API version number for Hardening-Patch */
7667+
7668+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7669 #define ZEND_EXTENSION_API_NO 20050606
7670
7671 typedef struct _zend_extension_version_info {
7672@@ -30,6 +33,7 @@
7673 char *required_zend_version;
7674 unsigned char thread_safe;
7675 unsigned char debug;
7676+ int real_zend_extension_api_no;
7677 } zend_extension_version_info;
7678
7679
7680@@ -96,7 +100,7 @@
7681
7682
7683 #define ZEND_EXTENSION() \
7684- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7685+ 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 }
7686
7687 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7688 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7689diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.11/Zend/zend_globals.h
7690--- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100
7691+++ hardening-patch-4.4.2-0.4.11/Zend/zend_globals.h 2006-05-13 18:01:56.000000000 +0200
7692@@ -163,6 +163,16 @@
7693
7694 int error_reporting;
7695 int orig_error_reporting;
7696+#if HARDENING_PATCH
7697+ int hphp_log_syslog;
7698+ int hphp_log_syslog_facility;
7699+ int hphp_log_syslog_priority;
7700+ int hphp_log_sapi;
7701+ int hphp_log_script;
7702+ char *hphp_log_scriptname;
7703+ zend_bool hphp_log_use_x_forwarded_for;
7704+ long hphp_executor_max_depth;
7705+#endif
7706 int exit_status;
7707
7708 zend_op_array *active_op_array;
7709@@ -176,6 +186,7 @@
7710 int ticks_count;
7711
7712 zend_bool in_execution;
7713+ zend_uint in_code_type;
7714 zend_bool bailout_set;
7715 zend_bool full_tables_cleanup;
7716
7717diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.11/Zend/zend.h
7718--- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100
7719+++ hardening-patch-4.4.2-0.4.11/Zend/zend.h 2006-05-13 18:01:56.000000000 +0200
7720@@ -274,9 +274,10 @@
7721 struct _zval_struct {
7722 /* Variable information */
7723 zvalue_value value; /* value */
7724+ zend_uint refcount;
7725+ zend_ushort flags;
7726 zend_uchar type; /* active type */
7727 zend_uchar is_ref;
7728- zend_ushort refcount;
7729 };
7730
7731
7732@@ -337,6 +338,12 @@
7733 void (*ticks_function)(int ticks);
7734 void (*on_timeout)(int seconds TSRMLS_DC);
7735 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7736+#if HARDENING_PATCH
7737+ void (*security_log_function)(int loglevel, char *fmt, ...);
7738+#endif
7739+#if HARDENING_PATCH_INC_PROTECT
7740+ int (*is_valid_include)(zval *z);
7741+#endif
7742 } zend_utility_functions;
7743
7744
7745@@ -468,7 +475,16 @@
7746 extern ZEND_API void (*zend_ticks_function)(int ticks);
7747 extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
7748 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7749+#if HARDENING_PATCH
7750+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7751+#endif
7752+#if HARDENING_PATCH_INC_PROTECT
7753+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7754+#endif
7755
7756+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7757+ZEND_API unsigned int zend_canary(void);
7758+#endif
7759
7760 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7761
7762@@ -575,6 +591,11 @@
7763
7764 #define ZEND_MAX_RESERVED_RESOURCES 4
7765
7766+#if HARDENING_PATCH
7767+#include "hardened_globals.h"
7768+#include "php_syslog.h"
7769+#endif
7770+
7771 #endif /* ZEND_H */
7772
7773 /*
7774diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.11/Zend/zend_hash.c
7775--- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100
7776+++ hardening-patch-4.4.2-0.4.11/Zend/zend_hash.c 2006-05-13 18:01:56.000000000 +0200
7777@@ -26,6 +26,17 @@
7778 # include <stdlib.h>
7779 #endif
7780
7781+#if HARDENING_PATCH_HASH_PROTECT
7782+ unsigned int zend_hash_canary = 0x1234567;
7783+ zend_bool zend_hash_canary_inited = 0;
7784+#endif
7785+
7786+#define CHECK_HASH_CANARY(hash) \
7787+ if (zend_hash_canary != (hash)->canary) { \
7788+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7789+ exit(1); \
7790+ }
7791+
7792 #define HANDLE_NUMERIC(key, length, func) { \
7793 register char *tmp=key; \
7794 \
7795@@ -175,6 +186,9 @@
7796 {
7797 uint i = 3;
7798 Bucket **tmp;
7799+#if HARDENING_PATCH_HASH_PROTECT
7800+ TSRMLS_FETCH();
7801+#endif
7802
7803 SET_INCONSISTENT(HT_OK);
7804
7805@@ -184,6 +198,13 @@
7806
7807 ht->nTableSize = 1 << i;
7808 ht->nTableMask = ht->nTableSize - 1;
7809+#if HARDENING_PATCH_HASH_PROTECT
7810+ if (zend_hash_canary_inited==0) {
7811+ zend_hash_canary = zend_canary();
7812+ zend_hash_canary_inited = 1;
7813+ }
7814+ ht->canary = zend_hash_canary;
7815+#endif
7816 ht->pDestructor = pDestructor;
7817 ht->pListHead = NULL;
7818 ht->pListTail = NULL;
7819@@ -259,6 +280,9 @@
7820 }
7821 #endif
7822 if (ht->pDestructor) {
7823+#if HARDENING_PATCH_HASH_PROTECT
7824+ CHECK_HASH_CANARY(ht);
7825+#endif
7826 ht->pDestructor(p->pData);
7827 }
7828 UPDATE_DATA(ht, p, pData, nDataSize);
7829@@ -327,6 +351,9 @@
7830 }
7831 #endif
7832 if (ht->pDestructor) {
7833+#if HARDENING_PATCH_HASH_PROTECT
7834+ CHECK_HASH_CANARY(ht);
7835+#endif
7836 ht->pDestructor(p->pData);
7837 }
7838 UPDATE_DATA(ht, p, pData, nDataSize);
7839@@ -402,6 +429,9 @@
7840 }
7841 #endif
7842 if (ht->pDestructor) {
7843+#if HARDENING_PATCH_HASH_PROTECT
7844+ CHECK_HASH_CANARY(ht);
7845+#endif
7846 ht->pDestructor(p->pData);
7847 }
7848 UPDATE_DATA(ht, p, pData, nDataSize);
7849@@ -450,7 +480,7 @@
7850 IS_CONSISTENT(ht);
7851
7852 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7853- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7854+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7855 if (t) {
7856 HANDLE_BLOCK_INTERRUPTIONS();
7857 ht->arBuckets = t;
7858@@ -460,6 +490,7 @@
7859 HANDLE_UNBLOCK_INTERRUPTIONS();
7860 return SUCCESS;
7861 }
7862+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7863 return FAILURE;
7864 }
7865 return SUCCESS;
7866@@ -491,15 +522,17 @@
7867 IS_CONSISTENT(ht);
7868
7869 if (flag == HASH_DEL_KEY) {
7870- HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX));
7871+ HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, NULL, 0, idx, HASH_DEL_INDEX));
7872 h = zend_inline_hash_func(arKey, nKeyLength);
7873 }
7874 nIndex = h & ht->nTableMask;
7875
7876 p = ht->arBuckets[nIndex];
7877 while (p != NULL) {
7878- if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric index */
7879- ((p->nKeyLength == nKeyLength) && (!memcmp(p->arKey, arKey, nKeyLength))))) {
7880+ if ((p->h == h)
7881+ && (p->nKeyLength == nKeyLength)
7882+ && ((p->nKeyLength == 0) /* Numeric index (short circuits the memcmp() check) */
7883+ || !memcmp(p->arKey, arKey, nKeyLength))) { /* String index */
7884 HANDLE_BLOCK_INTERRUPTIONS();
7885 if (p == ht->arBuckets[nIndex]) {
7886 ht->arBuckets[nIndex] = p->pNext;
7887@@ -524,6 +557,9 @@
7888 ht->pInternalPointer = p->pListNext;
7889 }
7890 if (ht->pDestructor) {
7891+#if HARDENING_PATCH_HASH_PROTECT
7892+ CHECK_HASH_CANARY(ht);
7893+#endif
7894 ht->pDestructor(p->pData);
7895 }
7896 if (!p->pDataPtr) {
7897@@ -553,6 +589,9 @@
7898 q = p;
7899 p = p->pListNext;
7900 if (ht->pDestructor) {
7901+#if HARDENING_PATCH_HASH_PROTECT
7902+ CHECK_HASH_CANARY(ht);
7903+#endif
7904 ht->pDestructor(q->pData);
7905 }
7906 if (!q->pDataPtr && q->pData) {
7907@@ -579,6 +618,9 @@
7908 q = p;
7909 p = p->pListNext;
7910 if (ht->pDestructor) {
7911+#if HARDENING_PATCH_HASH_PROTECT
7912+ CHECK_HASH_CANARY(ht);
7913+#endif
7914 ht->pDestructor(q->pData);
7915 }
7916 if (!q->pDataPtr && q->pData) {
7917@@ -608,6 +650,9 @@
7918 HANDLE_BLOCK_INTERRUPTIONS();
7919
7920 if (ht->pDestructor) {
7921+#if HARDENING_PATCH_HASH_PROTECT
7922+ CHECK_HASH_CANARY(ht);
7923+#endif
7924 ht->pDestructor(p->pData);
7925 }
7926 if (!p->pDataPtr) {
7927diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.11/Zend/zend_hash.h
7928--- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100
7929+++ hardening-patch-4.4.2-0.4.11/Zend/zend_hash.h 2006-05-13 18:01:56.000000000 +0200
7930@@ -54,6 +54,9 @@
7931 } Bucket;
7932
7933 typedef struct _hashtable {
7934+#if HARDENING_PATCH_HASH_PROTECT
7935+ unsigned int canary;
7936+#endif
7937 uint nTableSize;
7938 uint nTableMask;
7939 uint nNumOfElements;
7940diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.11/Zend/zend_ini.h
7941--- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7942+++ hardening-patch-4.4.2-0.4.11/Zend/zend_ini.h 2006-05-13 18:01:56.000000000 +0200
7943@@ -174,6 +174,7 @@
7944 /* Standard message handlers */
7945 BEGIN_EXTERN_C()
7946 ZEND_API ZEND_INI_MH(OnUpdateBool);
7947+#define OnUpdateLong OnUpdateInt
7948 ZEND_API ZEND_INI_MH(OnUpdateInt);
7949 ZEND_API ZEND_INI_MH(OnUpdateReal);
7950 ZEND_API ZEND_INI_MH(OnUpdateString);
7951diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.11/Zend/zend_language_scanner.l
7952--- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100
7953+++ hardening-patch-4.4.2-0.4.11/Zend/zend_language_scanner.l 2006-05-13 18:01:56.000000000 +0200
7954@@ -393,6 +393,13 @@
7955 compilation_successful=0;
7956 } else {
7957 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7958+#if HARDENING_PATCH
7959+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7960+ op_array->created_by_eval = 1;
7961+ } else {
7962+ op_array->created_by_eval = 0;
7963+ }
7964+#endif
7965 CG(in_compilation) = 1;
7966 CG(active_op_array) = op_array;
7967 compiler_result = zendparse(TSRMLS_C);
7968diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.11/Zend/zend_language_scanner.c
7969--- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100
7970+++ hardening-patch-4.4.2-0.4.11/Zend/zend_language_scanner.c 2006-05-13 18:01:56.000000000 +0200
7971@@ -3036,6 +3036,13 @@
7972 compilation_successful=0;
7973 } else {
7974 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7975+#if HARDENING_PATCH
7976+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7977+ op_array->created_by_eval = 1;
7978+ } else {
7979+ op_array->created_by_eval = 0;
7980+ }
7981+#endif
7982 CG(in_compilation) = 1;
7983 CG(active_op_array) = op_array;
7984 compiler_result = zendparse(TSRMLS_C);
7985diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.11/Zend/zend_llist.c
7986--- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100
7987+++ hardening-patch-4.4.2-0.4.11/Zend/zend_llist.c 2006-05-13 18:01:56.000000000 +0200
7988@@ -21,9 +21,49 @@
7989 #include "zend.h"
7990 #include "zend_llist.h"
7991 #include "zend_qsort.h"
7992+#include "zend_globals.h"
7993+
7994+#if HARDENING_PATCH_LL_PROTECT
7995+ unsigned int zend_llist_canary_1 = 0x1234567;
7996+ unsigned int zend_llist_canary_2 = 0x1553425;
7997+ zend_bool zend_llist_canary_inited = 0;
7998+#endif
7999+
8000+#define CHECK_LIST_CANARY(list) \
8001+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
8002+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
8003+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
8004+ exit(1); \
8005+ }
8006+
8007+#define CHECK_LISTELEMENT_CANARY(elem, list) \
8008+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
8009+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
8010+ exit(1); \
8011+ }
8012+
8013
8014 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
8015 {
8016+#if HARDENING_PATCH_LL_PROTECT
8017+ TSRMLS_FETCH();
8018+
8019+ if (persistent) {
8020+ if (!zend_llist_canary_inited) {
8021+ /* do not change order to ensure thread safety */
8022+ zend_llist_canary_1 = zend_canary();
8023+ zend_llist_canary_2 = zend_canary();
8024+ zend_llist_canary_inited = 1;
8025+ }
8026+ } else
8027+ if (!HG(ll_canary_inited)) {
8028+ HG(canary_3) = zend_canary();
8029+ HG(canary_4) = zend_canary();
8030+ HG(ll_canary_inited) = 1;
8031+ }
8032+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
8033+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
8034+#endif
8035 l->head = NULL;
8036 l->tail = NULL;
8037 l->count = 0;
8038@@ -37,6 +77,11 @@
8039 {
8040 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8041
8042+#if HARDENING_PATCH_LL_PROTECT
8043+ TSRMLS_FETCH();
8044+ CHECK_LIST_CANARY(l)
8045+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8046+#endif
8047 tmp->prev = l->tail;
8048 tmp->next = NULL;
8049 if (l->tail) {
8050@@ -55,6 +100,11 @@
8051 {
8052 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
8053
8054+#if HARDENING_PATCH_LL_PROTECT
8055+ TSRMLS_FETCH();
8056+ CHECK_LIST_CANARY(l)
8057+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
8058+#endif
8059 tmp->next = l->head;
8060 tmp->prev = NULL;
8061 if (l->head) {
8062@@ -91,10 +141,20 @@
8063 zend_llist_element *current=l->head;
8064 zend_llist_element *next;
8065
8066+#if HARDENING_PATCH_LL_PROTECT
8067+ TSRMLS_FETCH();
8068+ CHECK_LIST_CANARY(l)
8069+#endif
8070 while (current) {
8071+#if HARDENING_PATCH_LL_PROTECT
8072+ CHECK_LISTELEMENT_CANARY(current, l)
8073+#endif
8074 next = current->next;
8075 if (compare(current->data, element)) {
8076 DEL_LLIST_ELEMENT(current, l);
8077+#if HARDENING_PATCH_LL_PROTECT
8078+ current->canary = 0;
8079+#endif
8080 break;
8081 }
8082 current = next;
8083@@ -106,7 +166,14 @@
8084 {
8085 zend_llist_element *current=l->head, *next;
8086
8087+#if HARDENING_PATCH_LL_PROTECT
8088+ TSRMLS_FETCH();
8089+ CHECK_LIST_CANARY(l)
8090+#endif
8091 while (current) {
8092+#if HARDENING_PATCH_LL_PROTECT
8093+ CHECK_LISTELEMENT_CANARY(current, l)
8094+#endif
8095 next = current->next;
8096 if (l->dtor) {
8097 l->dtor(current->data);
8098@@ -131,7 +198,14 @@
8099 zend_llist_element *old_tail;
8100 void *data;
8101
8102+#if HARDENING_PATCH_LL_PROTECT
8103+ TSRMLS_FETCH();
8104+ CHECK_LIST_CANARY(l)
8105+#endif
8106 if ((old_tail = l->tail)) {
8107+#if HARDENING_PATCH_LL_PROTECT
8108+ CHECK_LISTELEMENT_CANARY(old_tail, l)
8109+#endif
8110 if (l->tail->prev) {
8111 l->tail->prev->next = NULL;
8112 }
8113@@ -157,9 +231,16 @@
8114 {
8115 zend_llist_element *ptr;
8116
8117+#if HARDENING_PATCH_LL_PROTECT
8118+ TSRMLS_FETCH();
8119+ CHECK_LIST_CANARY(src)
8120+#endif
8121 zend_llist_init(dst, src->size, src->dtor, src->persistent);
8122 ptr = src->head;
8123 while (ptr) {
8124+#if HARDENING_PATCH_LL_PROTECT
8125+ CHECK_LISTELEMENT_CANARY(ptr, src)
8126+#endif
8127 zend_llist_add_element(dst, ptr->data);
8128 ptr = ptr->next;
8129 }
8130@@ -170,11 +251,21 @@
8131 {
8132 zend_llist_element *element, *next;
8133
8134+#if HARDENING_PATCH_LL_PROTECT
8135+ TSRMLS_FETCH();
8136+ CHECK_LIST_CANARY(l)
8137+#endif
8138 element=l->head;
8139 while (element) {
8140+#if HARDENING_PATCH_LL_PROTECT
8141+ CHECK_LISTELEMENT_CANARY(element, l)
8142+#endif
8143 next = element->next;
8144 if (func(element->data)) {
8145 DEL_LLIST_ELEMENT(element, l);
8146+#if HARDENING_PATCH_LL_PROTECT
8147+ element->canary = 0;
8148+#endif
8149 }
8150 element = next;
8151 }
8152@@ -185,7 +276,13 @@
8153 {
8154 zend_llist_element *element;
8155
8156+#if HARDENING_PATCH_LL_PROTECT
8157+ CHECK_LIST_CANARY(l)
8158+#endif
8159 for (element=l->head; element; element=element->next) {
8160+#if HARDENING_PATCH_LL_PROTECT
8161+ CHECK_LISTELEMENT_CANARY(element, l)
8162+#endif
8163 func(element->data TSRMLS_CC);
8164 }
8165 }
8166@@ -197,6 +294,9 @@
8167 zend_llist_element **elements;
8168 zend_llist_element *element, **ptr;
8169
8170+#if HARDENING_PATCH_LL_PROTECT
8171+ CHECK_LIST_CANARY(l)
8172+#endif
8173 if (l->count <= 0) {
8174 return;
8175 }
8176@@ -206,6 +306,9 @@
8177 ptr = &elements[0];
8178
8179 for (element=l->head; element; element=element->next) {
8180+#if HARDENING_PATCH_LL_PROTECT
8181+ CHECK_LISTELEMENT_CANARY(element, l)
8182+#endif
8183 *ptr++ = element;
8184 }
8185
8186@@ -228,7 +331,13 @@
8187 {
8188 zend_llist_element *element;
8189
8190+#if HARDENING_PATCH_LL_PROTECT
8191+ CHECK_LIST_CANARY(l)
8192+#endif
8193 for (element=l->head; element; element=element->next) {
8194+#if HARDENING_PATCH_LL_PROTECT
8195+ CHECK_LISTELEMENT_CANARY(element, l)
8196+#endif
8197 func(element->data, arg TSRMLS_CC);
8198 }
8199 }
8200@@ -239,8 +348,14 @@
8201 zend_llist_element *element;
8202 va_list args;
8203
8204+#if HARDENING_PATCH_LL_PROTECT
8205+ CHECK_LIST_CANARY(l)
8206+#endif
8207 va_start(args, num_args);
8208 for (element=l->head; element; element=element->next) {
8209+#if HARDENING_PATCH_LL_PROTECT
8210+ CHECK_LISTELEMENT_CANARY(element, l)
8211+#endif
8212 func(element->data, num_args, args TSRMLS_CC);
8213 }
8214 va_end(args);
8215@@ -249,6 +364,10 @@
8216
8217 ZEND_API int zend_llist_count(zend_llist *l)
8218 {
8219+#if HARDENING_PATCH_LL_PROTECT
8220+ TSRMLS_FETCH();
8221+ CHECK_LIST_CANARY(l)
8222+#endif
8223 return l->count;
8224 }
8225
8226@@ -256,8 +375,15 @@
8227 {
8228 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8229
8230+#if HARDENING_PATCH_LL_PROTECT
8231+ TSRMLS_FETCH();
8232+ CHECK_LIST_CANARY(l)
8233+#endif
8234 *current = l->head;
8235 if (*current) {
8236+#if HARDENING_PATCH_LL_PROTECT
8237+ CHECK_LISTELEMENT_CANARY(*current, l)
8238+#endif
8239 return (*current)->data;
8240 } else {
8241 return NULL;
8242@@ -269,8 +395,15 @@
8243 {
8244 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8245
8246+#if HARDENING_PATCH_LL_PROTECT
8247+ TSRMLS_FETCH();
8248+ CHECK_LIST_CANARY(l)
8249+#endif
8250 *current = l->tail;
8251 if (*current) {
8252+#if HARDENING_PATCH_LL_PROTECT
8253+ CHECK_LISTELEMENT_CANARY(*current, l)
8254+#endif
8255 return (*current)->data;
8256 } else {
8257 return NULL;
8258@@ -282,9 +415,19 @@
8259 {
8260 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8261
8262+#if HARDENING_PATCH_LL_PROTECT
8263+ TSRMLS_FETCH();
8264+ CHECK_LIST_CANARY(l)
8265+#endif
8266 if (*current) {
8267+#if HARDENING_PATCH_LL_PROTECT
8268+ CHECK_LISTELEMENT_CANARY(*current, l)
8269+#endif
8270 *current = (*current)->next;
8271 if (*current) {
8272+#if HARDENING_PATCH_LL_PROTECT
8273+ CHECK_LISTELEMENT_CANARY(*current, l)
8274+#endif
8275 return (*current)->data;
8276 }
8277 }
8278@@ -296,9 +439,19 @@
8279 {
8280 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
8281
8282+#if HARDENING_PATCH_LL_PROTECT
8283+ TSRMLS_FETCH();
8284+ CHECK_LIST_CANARY(l)
8285+#endif
8286 if (*current) {
8287+#if HARDENING_PATCH_LL_PROTECT
8288+ CHECK_LISTELEMENT_CANARY(*current, l)
8289+#endif
8290 *current = (*current)->prev;
8291 if (*current) {
8292+#if HARDENING_PATCH_LL_PROTECT
8293+ CHECK_LISTELEMENT_CANARY(*current, l)
8294+#endif
8295 return (*current)->data;
8296 }
8297 }
8298diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.11/Zend/zend_llist.h
8299--- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100
8300+++ hardening-patch-4.4.2-0.4.11/Zend/zend_llist.h 2006-05-13 18:01:56.000000000 +0200
8301@@ -24,6 +24,9 @@
8302 #include <stdlib.h>
8303
8304 typedef struct _zend_llist_element {
8305+#if HARDENING_PATCH_LL_PROTECT
8306+ unsigned int canary, padding;
8307+#endif
8308 struct _zend_llist_element *next;
8309 struct _zend_llist_element *prev;
8310 char data[1]; /* Needs to always be last in the struct */
8311@@ -36,6 +39,9 @@
8312 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
8313
8314 typedef struct _zend_llist {
8315+#if HARDENING_PATCH_LL_PROTECT
8316+ unsigned int canary_h; /* head */
8317+#endif
8318 zend_llist_element *head;
8319 zend_llist_element *tail;
8320 size_t size;
8321@@ -43,6 +49,9 @@
8322 llist_dtor_func_t dtor;
8323 unsigned char persistent;
8324 zend_llist_element *traverse_ptr;
8325+#if HARDENING_PATCH_LL_PROTECT
8326+ unsigned int canary_t; /* tail */
8327+#endif
8328 } zend_llist;
8329
8330 typedef zend_llist_element* zend_llist_position;
8331diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.11/Zend/zend_modules.h
8332--- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100
8333+++ hardening-patch-4.4.2-0.4.11/Zend/zend_modules.h 2006-05-13 18:01:56.000000000 +0200
8334@@ -34,6 +34,7 @@
8335 ZEND_API extern unsigned char second_arg_force_ref[];
8336 ZEND_API extern unsigned char third_arg_force_ref[];
8337
8338+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8339 #define ZEND_MODULE_API_NO 20020429
8340 #ifdef ZTS
8341 #define USING_ZTS 1
8342@@ -41,9 +42,9 @@
8343 #define USING_ZTS 0
8344 #endif
8345
8346-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8347+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8348
8349-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8350+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8351
8352 #define STANDARD_MODULE_PROPERTIES \
8353 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8354@@ -75,6 +76,7 @@
8355 unsigned char type;
8356 void *handle;
8357 int module_number;
8358+ unsigned int real_zend_api;
8359 };
8360
8361
8362diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.11/Zend/zend_opcode.c
8363--- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100
8364+++ hardening-patch-4.4.2-0.4.11/Zend/zend_opcode.c 2006-05-13 18:01:56.000000000 +0200
8365@@ -88,6 +88,9 @@
8366 op_array->done_pass_two = 0;
8367
8368 op_array->start_op = NULL;
8369+#if HARDENING_PATCH
8370+ op_array->created_by_eval = 0;
8371+#endif
8372
8373 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8374 }
8375diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.11/Zend/zend_operators.c
8376--- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100
8377+++ hardening-patch-4.4.2-0.4.11/Zend/zend_operators.c 2006-05-13 18:01:56.000000000 +0200
8378@@ -1604,6 +1604,20 @@
8379 return (op->value.lval ? 1 : 0);
8380 }
8381
8382+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8383+{
8384+ register unsigned char *str = (unsigned char*)source;
8385+ register unsigned char *result = (unsigned char*)dest;
8386+ register unsigned char *end = str + length;
8387+
8388+ while (str < end) {
8389+ *result++ = tolower((int)*str++);
8390+ }
8391+ *result = *end;
8392+
8393+ return dest;
8394+}
8395+
8396 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8397 {
8398 register char *p=str, *end=p+length;
8399diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.11/Zend/zend_operators.h
8400--- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100
8401+++ hardening-patch-4.4.2-0.4.11/Zend/zend_operators.h 2006-05-13 18:01:56.000000000 +0200
8402@@ -174,6 +174,14 @@
8403 #endif
8404
8405 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8406+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8407+
8408+static inline char *
8409+zend_str_tolower_dup(const char *source, unsigned int length)
8410+{
8411+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8412+}
8413+
8414 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8415 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8416 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
diff --git a/0.4.11/hardening-patch-5.1.4-0.4.11.patch b/0.4.11/hardening-patch-5.1.4-0.4.11.patch
new file mode 100644
index 0000000..2631450
--- /dev/null
+++ b/0.4.11/hardening-patch-5.1.4-0.4.11.patch
@@ -0,0 +1,8220 @@
1diff -Nura php-5.1.4/Changelog.hphp hardening-patch-5.1.4-0.4.11/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.11/Changelog.hphp 2006-05-13 19:11:35.000000000 +0200
4@@ -0,0 +1,21 @@
5+Changelog of the Hardening-Patch
6+--------------------------------
7+
8+0.4.11 - 13. May 2006
9+
10+ PHP5:
11+ [+] tsrm_virtual_cwd.c: close open_basedir, safe_mode hole introduced by realpath() cache
12+ [+] install-pear-nozlib.phar: bundle in full package download of 5.1.4
13+
14+ PHP4+5:
15+ [+] tsrm_virtual_cwd.c: realpath() hotfix to solve problems with non existing directories
16+
17+
18+0.4.10 - 11. May 2006
19+
20+ PHP4:
21+ [+] info.c: backport from 5.1.4 contained TSRMLS macro that had to be removed
22+
23+ PHP4+5:
24+ [+] fopen_wrappers.c: fix for a trailing slash problem with open_basedir
25+
26diff -Nura php-5.1.4/configure hardening-patch-5.1.4-0.4.11/configure
27--- php-5.1.4/configure 2006-05-04 01:31:32.000000000 +0200
28+++ hardening-patch-5.1.4-0.4.11/configure 2006-05-13 15:39:35.000000000 +0200
29@@ -942,6 +942,16 @@
30 ac_help="$ac_help
31 --with-libdir=NAME Look for libraries in .../NAME rather than .../lib"
32 ac_help="$ac_help
33+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
34+ac_help="$ac_help
35+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
36+ac_help="$ac_help
37+ --disable-hardening-patch-inc-protect Disable include/require protection."
38+ac_help="$ac_help
39+ --disable-hardening-patch-fmt-protect Disable format string protection."
40+ac_help="$ac_help
41+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
42+ac_help="$ac_help
43
44 SAPI modules:
45 "
46@@ -1410,6 +1420,8 @@
47 ac_help="$ac_help
48 --enable-wddx Enable WDDX support"
49 ac_help="$ac_help
50+ --disable-varfilter Disable Hardening-Patch's variable filter"
51+ac_help="$ac_help
52 --disable-xml Disable XML support"
53 ac_help="$ac_help
54 --with-libxml-dir=DIR XML: libxml2 install prefix"
55@@ -3618,6 +3630,157 @@
56
57
58
59+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
60+if test "${enable_hardening_patch_mm_protect+set}" = set; then
61+ enableval="$enable_hardening_patch_mm_protect"
62+
63+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
64+
65+else
66+
67+ DO_HARDENING_PATCH_MM_PROTECT=yes
68+
69+fi
70+
71+
72+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
73+if test "${enable_hardening_patch_ll_protect+set}" = set; then
74+ enableval="$enable_hardening_patch_ll_protect"
75+
76+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
77+
78+else
79+
80+ DO_HARDENING_PATCH_LL_PROTECT=yes
81+
82+fi
83+
84+
85+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
86+if test "${enable_hardening_patch_inc_protect+set}" = set; then
87+ enableval="$enable_hardening_patch_inc_protect"
88+
89+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
90+
91+else
92+
93+ DO_HARDENING_PATCH_INC_PROTECT=yes
94+
95+fi
96+
97+
98+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
99+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
100+ enableval="$enable_hardening_patch_fmt_protect"
101+
102+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
103+
104+else
105+
106+ DO_HARDENING_PATCH_FMT_PROTECT=yes
107+
108+fi
109+
110+
111+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
112+if test "${enable_hardening_patch_hash_protect+set}" = set; then
113+ enableval="$enable_hardening_patch_hash_protect"
114+
115+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
116+
117+else
118+
119+ DO_HARDENING_PATCH_HASH_PROTECT=yes
120+
121+fi
122+
123+
124+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
125+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
126+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
127+
128+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
129+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
130+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
131+
132+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
133+echo "configure:2733: checking whether to protect include/require statements" >&5
134+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
135+
136+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
137+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
138+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
139+
140+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
141+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
142+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
143+
144+
145+cat >> confdefs.h <<\EOF
146+#define HARDENING_PATCH 1
147+EOF
148+
149+
150+
151+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
152+ cat >> confdefs.h <<\EOF
153+#define HARDENING_PATCH_MM_PROTECT 1
154+EOF
155+
156+else
157+ cat >> confdefs.h <<\EOF
158+#define HARDENING_PATCH_MM_PROTECT 0
159+EOF
160+
161+fi
162+
163+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
164+ cat >> confdefs.h <<\EOF
165+#define HARDENING_PATCH_LL_PROTECT 1
166+EOF
167+
168+else
169+ cat >> confdefs.h <<\EOF
170+#define HARDENING_PATCH_LL_PROTECT 0
171+EOF
172+
173+fi
174+
175+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
176+ cat >> confdefs.h <<\EOF
177+#define HARDENING_PATCH_INC_PROTECT 1
178+EOF
179+
180+else
181+ cat >> confdefs.h <<\EOF
182+#define HARDENING_PATCH_INC_PROTECT 0
183+EOF
184+
185+fi
186+
187+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
188+ cat >> confdefs.h <<\EOF
189+#define HARDENING_PATCH_FMT_PROTECT 1
190+EOF
191+
192+else
193+ cat >> confdefs.h <<\EOF
194+#define HARDENING_PATCH_FMT_PROTECT 0
195+EOF
196+
197+fi
198+
199+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
200+ cat >> confdefs.h <<\EOF
201+#define HARDENING_PATCH_HASH_PROTECT 1
202+EOF
203+
204+else
205+ cat >> confdefs.h <<\EOF
206+#define HARDENING_PATCH_HASH_PROTECT 0
207+EOF
208+
209+fi
210
211
212
213@@ -18607,6 +18770,62 @@
214 fi
215
216
217+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
218+echo "configure:14928: checking whether realpath is broken" >&5
219+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
220+ echo $ac_n "(cached) $ac_c" 1>&6
221+else
222+
223+ if test "$cross_compiling" = yes; then
224+
225+ ac_cv_broken_realpath=no
226+
227+else
228+ cat > conftest.$ac_ext <<EOF
229+#line 14939 "configure"
230+#include "confdefs.h"
231+
232+main() {
233+ char buf[4096+1];
234+ buf[0] = 0;
235+ realpath("/etc/hosts/../passwd", buf);
236+ exit(strcmp(buf, "/etc/passwd")==0);
237+}
238+
239+EOF
240+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
241+then
242+
243+ ac_cv_broken_realpath=no
244+
245+else
246+ echo "configure: failed program was:" >&5
247+ cat conftest.$ac_ext >&5
248+ rm -fr conftest*
249+
250+ ac_cv_broken_realpath=yes
251+
252+fi
253+rm -fr conftest*
254+fi
255+
256+
257+fi
258+
259+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
260+ if test "$ac_cv_broken_realpath" = "yes"; then
261+ cat >> confdefs.h <<\EOF
262+#define PHP_BROKEN_REALPATH 1
263+EOF
264+
265+ else
266+ cat >> confdefs.h <<\EOF
267+#define PHP_BROKEN_REALPATH 0
268+EOF
269+
270+ fi
271+
272+
273 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
274 echo "configure:18612: checking for declared timezone" >&5
275 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
276@@ -89422,7 +89641,7 @@
277 if test "$ac_cv_crypt_blowfish" = "yes"; then
278 ac_result=1
279 else
280- ac_result=0
281+ ac_result=1
282 fi
283 cat >> confdefs.h <<EOF
284 #define PHP_BLOWFISH_CRYPT $ac_result
285@@ -92022,7 +92241,7 @@
286 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
287 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
288 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
289- filters.c proc_open.c streamsfuncs.c http.c; do
290+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
291
292 IFS=.
293 set $ac_src
294@@ -92081,7 +92300,7 @@
295 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
296 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
297 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
298- filters.c proc_open.c streamsfuncs.c http.c; do
299+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
300
301 IFS=.
302 set $ac_src
303@@ -92211,7 +92430,7 @@
304 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
305 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
306 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
307- filters.c proc_open.c streamsfuncs.c http.c; do
308+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
309
310 IFS=.
311 set $ac_src
312@@ -92266,7 +92485,7 @@
313 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
314 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
315 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
316- filters.c proc_open.c streamsfuncs.c http.c; do
317+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
318
319 IFS=.
320 set $ac_src
321@@ -96101,6 +96320,265 @@
322 fi
323
324
325+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
326+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
327+# Check whether --enable-varfilter or --disable-varfilter was given.
328+if test "${enable_varfilter+set}" = set; then
329+ enableval="$enable_varfilter"
330+ PHP_VARFILTER=$enableval
331+else
332+
333+ PHP_VARFILTER=yes
334+
335+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
336+ PHP_VARFILTER=$PHP_ENABLE_ALL
337+ fi
338+
339+fi
340+
341+
342+
343+ext_output="yes, shared"
344+ext_shared=yes
345+case $PHP_VARFILTER in
346+shared,*)
347+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
348+ ;;
349+shared)
350+ PHP_VARFILTER=yes
351+ ;;
352+no)
353+ ext_output=no
354+ ext_shared=no
355+ ;;
356+*)
357+ ext_output=yes
358+ ext_shared=no
359+ ;;
360+esac
361+
362+
363+
364+echo "$ac_t""$ext_output" 1>&6
365+
366+
367+
368+
369+if test "$PHP_VARFILTER" != "no"; then
370+ cat >> confdefs.h <<\EOF
371+#define HAVE_VARFILTER 1
372+EOF
373+
374+
375+ ext_builddir=ext/varfilter
376+ ext_srcdir=$abs_srcdir/ext/varfilter
377+
378+ ac_extra=
379+
380+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
381+
382+
383+
384+ case ext/varfilter in
385+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
386+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
387+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
388+ esac
389+
390+
391+
392+ b_c_pre=$php_c_pre
393+ b_cxx_pre=$php_cxx_pre
394+ b_c_meta=$php_c_meta
395+ b_cxx_meta=$php_cxx_meta
396+ b_c_post=$php_c_post
397+ b_cxx_post=$php_cxx_post
398+ b_lo=$php_lo
399+
400+
401+ old_IFS=$IFS
402+ for ac_src in varfilter.c; do
403+
404+ IFS=.
405+ set $ac_src
406+ ac_obj=$1
407+ IFS=$old_IFS
408+
409+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
410+
411+ case $ac_src in
412+ *.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" ;;
413+ *.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" ;;
414+ esac
415+
416+ cat >>Makefile.objects<<EOF
417+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
418+ $ac_comp
419+EOF
420+ done
421+
422+
423+ EXT_STATIC="$EXT_STATIC varfilter"
424+ if test "$ext_shared" != "nocli"; then
425+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
426+ fi
427+ else
428+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
429+
430+ case ext/varfilter in
431+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
432+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
433+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
434+ esac
435+
436+
437+
438+ b_c_pre=$shared_c_pre
439+ b_cxx_pre=$shared_cxx_pre
440+ b_c_meta=$shared_c_meta
441+ b_cxx_meta=$shared_cxx_meta
442+ b_c_post=$shared_c_post
443+ b_cxx_post=$shared_cxx_post
444+ b_lo=$shared_lo
445+
446+
447+ old_IFS=$IFS
448+ for ac_src in varfilter.c; do
449+
450+ IFS=.
451+ set $ac_src
452+ ac_obj=$1
453+ IFS=$old_IFS
454+
455+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
456+
457+ case $ac_src in
458+ *.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" ;;
459+ *.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" ;;
460+ esac
461+
462+ cat >>Makefile.objects<<EOF
463+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
464+ $ac_comp
465+EOF
466+ done
467+
468+
469+ install_modules="install-modules"
470+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
471+
472+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
473+
474+ cat >>Makefile.objects<<EOF
475+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
476+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
477+
478+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
479+ \$(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)
480+
481+EOF
482+
483+ cat >> confdefs.h <<EOF
484+#define COMPILE_DL_VARFILTER 1
485+EOF
486+
487+ fi
488+ fi
489+
490+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
491+ if test "$PHP_SAPI" = "cgi"; then
492+
493+
494+ case ext/varfilter in
495+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
496+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
497+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
498+ esac
499+
500+
501+
502+ b_c_pre=$php_c_pre
503+ b_cxx_pre=$php_cxx_pre
504+ b_c_meta=$php_c_meta
505+ b_cxx_meta=$php_cxx_meta
506+ b_c_post=$php_c_post
507+ b_cxx_post=$php_cxx_post
508+ b_lo=$php_lo
509+
510+
511+ old_IFS=$IFS
512+ for ac_src in varfilter.c; do
513+
514+ IFS=.
515+ set $ac_src
516+ ac_obj=$1
517+ IFS=$old_IFS
518+
519+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
520+
521+ case $ac_src in
522+ *.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" ;;
523+ *.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" ;;
524+ esac
525+
526+ cat >>Makefile.objects<<EOF
527+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
528+ $ac_comp
529+EOF
530+ done
531+
532+
533+ EXT_STATIC="$EXT_STATIC varfilter"
534+ else
535+
536+
537+ case ext/varfilter in
538+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
539+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
540+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
541+ esac
542+
543+
544+
545+ b_c_pre=$php_c_pre
546+ b_cxx_pre=$php_cxx_pre
547+ b_c_meta=$php_c_meta
548+ b_cxx_meta=$php_cxx_meta
549+ b_c_post=$php_c_post
550+ b_cxx_post=$php_cxx_post
551+ b_lo=$php_lo
552+
553+
554+ old_IFS=$IFS
555+ for ac_src in varfilter.c; do
556+
557+ IFS=.
558+ set $ac_src
559+ ac_obj=$1
560+ IFS=$old_IFS
561+
562+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
563+
564+ case $ac_src in
565+ *.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" ;;
566+ *.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" ;;
567+ esac
568+
569+ cat >>Makefile.objects<<EOF
570+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
571+ $ac_comp
572+EOF
573+ done
574+
575+
576+ fi
577+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
578+ fi
579+
580+ BUILD_DIR="$BUILD_DIR $ext_builddir"
581+
582+
583+fi
584
585
586 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
587@@ -112351,7 +112829,7 @@
588 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
589 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
590 network.c php_open_temporary_file.c php_logos.c \
591- output.c ; do
592+ output.c hardening_patch.c ; do
593
594 IFS=.
595 set $ac_src
596@@ -112596,7 +113074,7 @@
597 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
598 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
599 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
600- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
601+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
602
603 IFS=.
604 set $ac_src
605diff -Nura php-5.1.4/configure.in hardening-patch-5.1.4-0.4.11/configure.in
606--- php-5.1.4/configure.in 2006-05-04 01:30:02.000000000 +0200
607+++ hardening-patch-5.1.4-0.4.11/configure.in 2006-05-13 15:39:35.000000000 +0200
608@@ -209,7 +209,7 @@
609
610 sinclude(Zend/Zend.m4)
611 sinclude(TSRM/tsrm.m4)
612-
613+sinclude(main/hardening_patch.m4)
614
615 divert(2)
616
617@@ -1275,7 +1275,7 @@
618 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
619 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
620 network.c php_open_temporary_file.c php_logos.c \
621- output.c )
622+ output.c hardening_patch.c )
623
624 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
625 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
626@@ -1302,7 +1302,7 @@
627 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
628 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
629 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
630- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
631+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
632
633 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
634 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
635diff -Nura php-5.1.4/ext/fbsql/php_fbsql.c hardening-patch-5.1.4-0.4.11/ext/fbsql/php_fbsql.c
636--- php-5.1.4/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100
637+++ hardening-patch-5.1.4-0.4.11/ext/fbsql/php_fbsql.c 2006-05-13 15:39:35.000000000 +0200
638@@ -1925,8 +1925,24 @@
639 }
640 else if (fbcmdErrorsFound(md))
641 {
642+#if HARDENING_PATCH
643+ char* query_copy;
644+ int i;
645+#endif
646 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
647 char* emg = fbcemdAllErrorMessages(emd);
648+#if HARDENING_PATCH
649+ query_copy=estrdup(query_copy);
650+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
651+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
652+ efree(query_copy);
653+ if (HG(hphp_sql_bailout_on_error)) {
654+ free(emg);
655+ fbcemdRelease(emd);
656+ result = 0;
657+ zend_bailout();
658+ }
659+#endif
660 if (FB_SQL_G(generateWarnings))
661 {
662 if (emg)
663diff -Nura php-5.1.4/ext/mysql/php_mysql.c hardening-patch-5.1.4-0.4.11/ext/mysql/php_mysql.c
664--- php-5.1.4/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100
665+++ hardening-patch-5.1.4-0.4.11/ext/mysql/php_mysql.c 2006-05-13 15:39:35.000000000 +0200
666@@ -1231,6 +1231,8 @@
667 {
668 php_mysql_conn *mysql;
669 MYSQL_RES *mysql_result;
670+ char *copy_query;
671+ int i;
672
673 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
674
675@@ -1281,6 +1283,13 @@
676 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
677 }
678 }
679+ copy_query = estrdup(Z_STRVAL_PP(query));
680+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
681+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
682+ efree(copy_query);
683+ if (HG(hphp_sql_bailout_on_error)) {
684+ zend_bailout();
685+ }
686 RETURN_FALSE;
687 }
688 #else
689@@ -1291,6 +1300,13 @@
690 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
691 }
692 }
693+ copy_query = estrdup(Z_STRVAL_PP(query));
694+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
695+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
696+ efree(copy_query);
697+ if (HG(hphp_sql_bailout_on_error)) {
698+ zend_bailout();
699+ }
700 RETURN_FALSE;
701 }
702 #endif
703diff -Nura php-5.1.4/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.4-0.4.11/ext/mysqli/mysqli_nonapi.c
704--- php-5.1.4/ext/mysqli/mysqli_nonapi.c 2006-03-24 10:32:24.000000000 +0100
705+++ hardening-patch-5.1.4-0.4.11/ext/mysqli/mysqli_nonapi.c 2006-05-13 15:39:35.000000000 +0200
706@@ -184,6 +184,17 @@
707 if (mysql_real_query(mysql->mysql, query, query_len)) {
708 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
709 unsigned int s_errno;
710+#if HARDENING_PATCH
711+ char *query_copy = estrdup(query);
712+ int i;
713+
714+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
715+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
716+ efree(query_copy);
717+ if (HG(hphp_sql_bailout_on_error)) {
718+ zend_bailout();
719+ }
720+#endif
721 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
722
723 /* we have to save error information, cause
724@@ -234,6 +245,17 @@
725 MYSQLI_DISABLE_MQ;
726
727 if (mysql_real_query(mysql->mysql, query, query_len)) {
728+#if HARDENING_PATCH
729+ char *query_copy = estrdup(query);
730+ int i;
731+
732+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
733+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
734+ efree(query_copy);
735+ if (HG(hphp_sql_bailout_on_error)) {
736+ zend_bailout();
737+ }
738+#endif
739 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
740 RETURN_FALSE;
741 }
742diff -Nura php-5.1.4/ext/pgsql/pgsql.c hardening-patch-5.1.4-0.4.11/ext/pgsql/pgsql.c
743--- php-5.1.4/ext/pgsql/pgsql.c 2006-04-10 21:51:55.000000000 +0200
744+++ hardening-patch-5.1.4-0.4.11/ext/pgsql/pgsql.c 2006-05-13 15:39:35.000000000 +0200
745@@ -1152,10 +1152,28 @@
746 case PGRES_EMPTY_QUERY:
747 case PGRES_BAD_RESPONSE:
748 case PGRES_NONFATAL_ERROR:
749- case PGRES_FATAL_ERROR:
750- PHP_PQ_ERROR("Query failed: %s", pgsql);
751- PQclear(pgsql_result);
752- RETURN_FALSE;
753+ case PGRES_FATAL_ERROR:
754+ {
755+#if HARDENING_PATCH
756+ int i;
757+ char *query_copy;
758+#endif
759+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
760+ PQclear(pgsql_result);
761+#if HARDENING_PATCH
762+ query_copy = estrdup(Z_STRVAL_PP(query));
763+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
764+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
765+ efree(query_copy);
766+ if (HG(hphp_sql_bailout_on_error)) {
767+ efree(msgbuf);
768+ zend_bailout();
769+ }
770+#endif
771+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
772+ efree(msgbuf);
773+ RETURN_FALSE;
774+ }
775 break;
776 case PGRES_COMMAND_OK: /* successful command that did not return rows */
777 default:
778diff -Nura php-5.1.4/ext/session/mod_files.c hardening-patch-5.1.4-0.4.11/ext/session/mod_files.c
779--- php-5.1.4/ext/session/mod_files.c 2006-04-18 02:31:45.000000000 +0200
780+++ hardening-patch-5.1.4-0.4.11/ext/session/mod_files.c 2006-05-13 15:39:35.000000000 +0200
781@@ -422,6 +422,35 @@
782 return SUCCESS;
783 }
784
785+PS_VALIDATE_SID_FUNC(files)
786+{
787+ char buf[MAXPATHLEN];
788+ int fd;
789+ PS_FILES_DATA;
790+
791+ if (!ps_files_valid_key(key)) {
792+ return FAILURE;
793+ }
794+
795+ if (!PS(use_strict_mode)) {
796+ return SUCCESS;
797+ }
798+
799+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
800+ return FAILURE;
801+ }
802+
803+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY,
804+ data->filemode);
805+
806+ if (fd != -1) {
807+ close(fd);
808+ return SUCCESS;
809+ }
810+
811+ return FAILURE;
812+}
813+
814 /*
815 * Local variables:
816 * tab-width: 4
817diff -Nura php-5.1.4/ext/session/mod_mm.c hardening-patch-5.1.4-0.4.11/ext/session/mod_mm.c
818--- php-5.1.4/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100
819+++ hardening-patch-5.1.4-0.4.11/ext/session/mod_mm.c 2006-05-13 15:39:35.000000000 +0200
820@@ -425,6 +425,42 @@
821 return SUCCESS;
822 }
823
824+PS_VALIDATE_SID_FUNC(mm)
825+{
826+ PS_MM_DATA;
827+ ps_sd *sd;
828+ const char *p;
829+ char c;
830+ int ret = SUCCESS;
831+
832+ for (p = key; (c = *p); p++) {
833+ /* valid characters are a..z,A..Z,0..9 */
834+ if (!((c >= 'a' && c <= 'z')
835+ || (c >= 'A' && c <= 'Z')
836+ || (c >= '0' && c <= '9')
837+ || c == ','
838+ || c == '-')) {
839+ return FAILURE;
840+ }
841+ }
842+
843+ if (!PS(use_strict_mode)) {
844+ return SUCCESS;
845+ }
846+
847+ mm_lock(data->mm, MM_LOCK_RD);
848+
849+ sd = ps_sd_lookup(data, key, 0);
850+ if (sd) {
851+ mm_unlock(data->mm);
852+ return SUCCESS;
853+ }
854+
855+ mm_unlock(data->mm);
856+
857+ return FAILURE;
858+}
859+
860 #endif
861
862 /*
863diff -Nura php-5.1.4/ext/session/mod_user.c hardening-patch-5.1.4-0.4.11/ext/session/mod_user.c
864--- php-5.1.4/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100
865+++ hardening-patch-5.1.4-0.4.11/ext/session/mod_user.c 2006-05-13 15:39:35.000000000 +0200
866@@ -23,7 +23,7 @@
867 #include "mod_user.h"
868
869 ps_module ps_mod_user = {
870- PS_MOD(user)
871+ PS_MOD_SID(user)
872 };
873
874 #define SESS_ZVAL_LONG(val, a) \
875@@ -174,6 +174,83 @@
876 FINISH;
877 }
878
879+PS_CREATE_SID_FUNC(user)
880+{
881+ int i;
882+ char *val = NULL;
883+ zval *retval;
884+ ps_user *mdata = PS_GET_MOD_DATA();
885+
886+ if (!mdata)
887+ return estrndup("", 0);
888+
889+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
890+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
891+ }
892+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
893+
894+ if (retval) {
895+ if (Z_TYPE_P(retval) == IS_STRING) {
896+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
897+ } else {
898+ val = estrndup("", 0);
899+ }
900+ zval_ptr_dtor(&retval);
901+ } else {
902+ val = estrndup("", 0);
903+ }
904+
905+ return val;
906+}
907+
908+static int ps_user_valid_key(const char *key TSRMLS_DC)
909+{
910+ size_t len;
911+ const char *p;
912+ char c;
913+ int ret = SUCCESS;
914+
915+ for (p = key; (c = *p); p++) {
916+ /* valid characters are a..z,A..Z,0..9 */
917+ if (!((c >= 'a' && c <= 'z')
918+ || (c >= 'A' && c <= 'Z')
919+ || (c >= '0' && c <= '9')
920+ || c == ','
921+ || c == '-')) {
922+ ret = FAILURE;
923+ break;
924+ }
925+ }
926+
927+ len = p - key;
928+
929+ if (len == 0)
930+ ret = FAILURE;
931+
932+ return ret;
933+}
934+
935+PS_VALIDATE_SID_FUNC(user)
936+{
937+ zval *args[1];
938+ STDVARS;
939+
940+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
941+ return ps_user_valid_key(key TSRMLS_CC);
942+ }
943+ SESS_ZVAL_STRING(key, args[0]);
944+
945+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
946+
947+ if (retval) {
948+ convert_to_long(retval);
949+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
950+ zval_ptr_dtor(&retval);
951+ }
952+
953+ return ret;
954+}
955+
956 /*
957 * Local variables:
958 * tab-width: 4
959diff -Nura php-5.1.4/ext/session/mod_user.h hardening-patch-5.1.4-0.4.11/ext/session/mod_user.h
960--- php-5.1.4/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100
961+++ hardening-patch-5.1.4-0.4.11/ext/session/mod_user.h 2006-05-13 15:39:35.000000000 +0200
962@@ -22,7 +22,7 @@
963 #define MOD_USER_H
964
965 typedef union {
966- zval *names[6];
967+ zval *names[8];
968 struct {
969 zval *ps_open;
970 zval *ps_close;
971@@ -30,6 +30,8 @@
972 zval *ps_write;
973 zval *ps_destroy;
974 zval *ps_gc;
975+ zval *ps_create;
976+ zval *ps_validate;
977 } name;
978 } ps_user;
979
980diff -Nura php-5.1.4/ext/session/php_session.h hardening-patch-5.1.4-0.4.11/ext/session/php_session.h
981--- php-5.1.4/ext/session/php_session.h 2006-01-28 07:14:49.000000000 +0100
982+++ hardening-patch-5.1.4-0.4.11/ext/session/php_session.h 2006-05-13 15:39:35.000000000 +0200
983@@ -23,7 +23,7 @@
984
985 #include "ext/standard/php_var.h"
986
987-#define PHP_SESSION_API 20020330
988+#define PHP_SESSION_API 20051121
989
990 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
991 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
992@@ -32,6 +32,7 @@
993 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
994 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
995 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
996+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
997
998 /* default create id function */
999 PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
1000@@ -45,6 +46,7 @@
1001 int (*s_destroy)(PS_DESTROY_ARGS);
1002 int (*s_gc)(PS_GC_ARGS);
1003 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1004+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1005 } ps_module;
1006
1007 #define PS_GET_MOD_DATA() *mod_data
1008@@ -57,6 +59,7 @@
1009 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1010 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1011 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1012+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1013
1014 #define PS_FUNCS(x) \
1015 PS_OPEN_FUNC(x); \
1016@@ -65,11 +68,12 @@
1017 PS_WRITE_FUNC(x); \
1018 PS_DESTROY_FUNC(x); \
1019 PS_GC_FUNC(x); \
1020- PS_CREATE_SID_FUNC(x)
1021+ PS_CREATE_SID_FUNC(x); \
1022+ PS_VALIDATE_SID_FUNC(x)
1023
1024 #define PS_MOD(x) \
1025 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1026- ps_delete_##x, ps_gc_##x, php_session_create_id
1027+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1028
1029 /* SID enabled module handler definitions */
1030 #define PS_FUNCS_SID(x) \
1031@@ -79,11 +83,12 @@
1032 PS_WRITE_FUNC(x); \
1033 PS_DESTROY_FUNC(x); \
1034 PS_GC_FUNC(x); \
1035- PS_CREATE_SID_FUNC(x)
1036+ PS_CREATE_SID_FUNC(x); \
1037+ PS_VALIDATE_SID(x)
1038
1039 #define PS_MOD_SID(x) \
1040 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1041- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1042+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1043
1044 typedef enum {
1045 php_session_disabled,
1046@@ -120,6 +125,7 @@
1047 zend_bool use_only_cookies;
1048 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1049 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1050+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1051
1052 long hash_func;
1053 long hash_bits_per_character;
1054diff -Nura php-5.1.4/ext/session/session.c hardening-patch-5.1.4-0.4.11/ext/session/session.c
1055--- php-5.1.4/ext/session/session.c 2006-02-10 08:39:13.000000000 +0100
1056+++ hardening-patch-5.1.4-0.4.11/ext/session/session.c 2006-05-13 15:39:35.000000000 +0200
1057@@ -166,6 +166,7 @@
1058 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1059 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1060 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1061+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1062 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1063 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1064 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals)
1065@@ -758,6 +759,15 @@
1066 return;
1067 }
1068
1069+ /* If there is an ID, use session module to verify it */
1070+ if (PS(id)) {
1071+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1072+ efree(PS(id));
1073+ PS(id) = NULL;
1074+ PS(send_cookie) = 1;
1075+ }
1076+ }
1077+
1078 /* If there is no ID, use session module to create one */
1079 if (!PS(id))
1080 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1081@@ -1377,22 +1387,29 @@
1082 }
1083 /* }}} */
1084
1085-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1086+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1087 Sets user-level functions */
1088 PHP_FUNCTION(session_set_save_handler)
1089 {
1090- zval **args[6];
1091- int i;
1092+ zval **args[8];
1093+ int i, numargs;
1094 ps_user *mdata;
1095 char *name;
1096
1097- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1098+ numargs = ZEND_NUM_ARGS();
1099+ args[6] = NULL;
1100+ args[7] = NULL;
1101+
1102+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1103 WRONG_PARAM_COUNT;
1104
1105 if (PS(session_status) != php_session_none)
1106 RETURN_FALSE;
1107
1108- for (i = 0; i < 6; i++) {
1109+ for (i = 0; i < 8; i++) {
1110+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1111+ continue;
1112+ }
1113 if (!zend_is_callable(*args[i], 0, &name)) {
1114 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1115 efree(name);
1116@@ -1405,7 +1422,11 @@
1117
1118 mdata = emalloc(sizeof(*mdata));
1119
1120- for (i = 0; i < 6; i++) {
1121+ for (i = 0; i < 8; i++) {
1122+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1123+ mdata->names[i] = NULL;
1124+ continue;
1125+ }
1126 ZVAL_ADDREF(*args[i]);
1127 mdata->names[i] = *args[i];
1128 }
1129diff -Nura php-5.1.4/ext/session/tests/014.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/014.phpt
1130--- php-5.1.4/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200
1131+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/014.phpt 2006-05-13 15:39:35.000000000 +0200
1132@@ -5,6 +5,7 @@
1133 --INI--
1134 session.use_trans_sid=1
1135 session.use_cookies=0
1136+session.use_strict_mode=0
1137 session.cache_limiter=
1138 register_globals=1
1139 session.bug_compat_42=1
1140diff -Nura php-5.1.4/ext/session/tests/015.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/015.phpt
1141--- php-5.1.4/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200
1142+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/015.phpt 2006-05-13 15:39:35.000000000 +0200
1143@@ -5,6 +5,7 @@
1144 --INI--
1145 session.use_trans_sid=1
1146 session.use_cookies=0
1147+session.use_strict_mode=0
1148 session.cache_limiter=
1149 arg_separator.output=&
1150 session.name=PHPSESSID
1151diff -Nura php-5.1.4/ext/session/tests/018.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/018.phpt
1152--- php-5.1.4/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200
1153+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/018.phpt 2006-05-13 15:39:35.000000000 +0200
1154@@ -4,6 +4,7 @@
1155 <?php include('skipif.inc'); ?>
1156 --INI--
1157 session.use_cookies=0
1158+session.use_strict_mode=0
1159 session.cache_limiter=
1160 session.use_trans_sid=1
1161 session.name=PHPSESSID
1162diff -Nura php-5.1.4/ext/session/tests/019.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/019.phpt
1163--- php-5.1.4/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200
1164+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/019.phpt 2006-05-13 15:39:35.000000000 +0200
1165@@ -4,6 +4,7 @@
1166 <?php include('skipif.inc'); ?>
1167 --INI--
1168 session.use_cookies=0
1169+session.use_strict_mode=0
1170 session.cache_limiter=
1171 register_globals=1
1172 session.serialize_handler=php
1173diff -Nura php-5.1.4/ext/session/tests/020.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/020.phpt
1174--- php-5.1.4/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200
1175+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/020.phpt 2006-05-13 15:39:35.000000000 +0200
1176@@ -4,6 +4,7 @@
1177 <?php include('skipif.inc'); ?>
1178 --INI--
1179 session.use_cookies=0
1180+session.use_strict_mode=0
1181 session.cache_limiter=
1182 session.use_trans_sid=1
1183 arg_separator.output=&amp;
1184diff -Nura php-5.1.4/ext/session/tests/021.phpt hardening-patch-5.1.4-0.4.11/ext/session/tests/021.phpt
1185--- php-5.1.4/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200
1186+++ hardening-patch-5.1.4-0.4.11/ext/session/tests/021.phpt 2006-05-13 15:39:35.000000000 +0200
1187@@ -4,6 +4,7 @@
1188 <?php include('skipif.inc'); ?>
1189 --INI--
1190 session.use_cookies=0
1191+session.use_strict_mode=0
1192 session.cache_limiter=
1193 session.use_trans_sid=1
1194 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1195diff -Nura php-5.1.4/ext/sqlite/sess_sqlite.c hardening-patch-5.1.4-0.4.11/ext/sqlite/sess_sqlite.c
1196--- php-5.1.4/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100
1197+++ hardening-patch-5.1.4-0.4.11/ext/sqlite/sess_sqlite.c 2006-05-13 15:39:35.000000000 +0200
1198@@ -185,6 +185,76 @@
1199 return SQLITE_RETVAL(rv);
1200 }
1201
1202+PS_VALIDATE_SID_FUNC(sqlite)
1203+{
1204+ PS_SQLITE_DATA;
1205+ char *query;
1206+ const char *tail;
1207+ sqlite_vm *vm;
1208+ int colcount, result;
1209+ const char **rowdata, **colnames;
1210+ char *error;
1211+ size_t len;
1212+ const char *p;
1213+ char c;
1214+ int ret = FAILURE;
1215+
1216+ for (p = key; (c = *p); p++) {
1217+ /* valid characters are a..z,A..Z,0..9 */
1218+ if (!((c >= 'a' && c <= 'z')
1219+ || (c >= 'A' && c <= 'Z')
1220+ || (c >= '0' && c <= '9')
1221+ || c == ','
1222+ || c == '-')) {
1223+ return FAILURE;
1224+ break;
1225+ }
1226+ }
1227+
1228+ len = p - key;
1229+
1230+ if (len == 0)
1231+ return FAILURE;
1232+
1233+ if (!PS(use_strict_mode)) {
1234+ return SUCCESS;
1235+ }
1236+
1237+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
1238+ if (query == NULL) {
1239+ /* no memory */
1240+ return FAILURE;
1241+ }
1242+
1243+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
1244+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error);
1245+ sqlite_freemem(error);
1246+ sqlite_freemem(query);
1247+ return FAILURE;
1248+ }
1249+
1250+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
1251+ case SQLITE_ROW:
1252+ if (rowdata[0] != NULL) {
1253+ ret = SUCCESS;
1254+ }
1255+ break;
1256+ default:
1257+ sqlite_freemem(error);
1258+ error = NULL;
1259+ }
1260+
1261+ if (SQLITE_OK != sqlite_finalize(vm, &error)) {
1262+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error);
1263+ sqlite_freemem(error);
1264+ error = NULL;
1265+ }
1266+
1267+ sqlite_freemem(query);
1268+
1269+ return ret;
1270+}
1271+
1272 #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
1273
1274 /*
1275diff -Nura php-5.1.4/ext/sqlite/sqlite.c hardening-patch-5.1.4-0.4.11/ext/sqlite/sqlite.c
1276--- php-5.1.4/ext/sqlite/sqlite.c 2006-04-18 16:30:15.000000000 +0200
1277+++ hardening-patch-5.1.4-0.4.11/ext/sqlite/sqlite.c 2006-05-13 15:39:35.000000000 +0200
1278@@ -1530,6 +1530,19 @@
1279 db->last_err_code = ret;
1280
1281 if (ret != SQLITE_OK) {
1282+#if HARDENING_PATCH
1283+ char *query_copy;
1284+ int i;
1285+
1286+ query_copy = estrdup(sql);
1287+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1288+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
1289+ efree(query_copy);
1290+ if (HG(hphp_sql_bailout_on_error)) {
1291+ sqlite_freemem(errtext);
1292+ zend_bailout();
1293+ }
1294+#endif
1295 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
1296 if (errmsg) {
1297 ZVAL_STRING(errmsg, errtext, 1);
1298diff -Nura php-5.1.4/ext/standard/array.c hardening-patch-5.1.4-0.4.11/ext/standard/array.c
1299--- php-5.1.4/ext/standard/array.c 2006-04-12 21:30:52.000000000 +0200
1300+++ hardening-patch-5.1.4-0.4.11/ext/standard/array.c 2006-05-13 15:39:35.000000000 +0200
1301@@ -1295,6 +1295,32 @@
1302 }
1303 }
1304 }
1305+
1306+ if (var_name[0] == 'H') {
1307+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1308+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1309+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1310+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1311+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1312+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1313+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1314+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1315+ return 0;
1316+ }
1317+ } else if (var_name[0] == '_') {
1318+ if ((strcmp(var_name, "_COOKIE")==0)||
1319+ (strcmp(var_name, "_ENV")==0)||
1320+ (strcmp(var_name, "_FILES")==0)||
1321+ (strcmp(var_name, "_GET")==0)||
1322+ (strcmp(var_name, "_POST")==0)||
1323+ (strcmp(var_name, "_REQUEST")==0)||
1324+ (strcmp(var_name, "_SESSION")==0)||
1325+ (strcmp(var_name, "_SERVER")==0)) {
1326+ return 0;
1327+ }
1328+ } else if (strcmp(var_name, "GLOBALS")==0) {
1329+ return 0;
1330+ }
1331
1332 return 1;
1333 }
1334diff -Nura php-5.1.4/ext/standard/basic_functions.c hardening-patch-5.1.4-0.4.11/ext/standard/basic_functions.c
1335--- php-5.1.4/ext/standard/basic_functions.c 2006-04-03 15:46:11.000000000 +0200
1336+++ hardening-patch-5.1.4-0.4.11/ext/standard/basic_functions.c 2006-05-13 15:39:35.000000000 +0200
1337@@ -151,12 +151,14 @@
1338 typedef struct _php_shutdown_function_entry {
1339 zval **arguments;
1340 int arg_count;
1341+ zend_bool created_by_eval;
1342 } php_shutdown_function_entry;
1343
1344 typedef struct _user_tick_function_entry {
1345 zval **arguments;
1346 int arg_count;
1347 int calling;
1348+ zend_bool created_by_eval;
1349 } user_tick_function_entry;
1350
1351 /* some prototypes for local functions */
1352@@ -188,6 +190,8 @@
1353 PHP_FE(get_html_translation_table, NULL)
1354 PHP_FE(sha1, NULL)
1355 PHP_FE(sha1_file, NULL)
1356+ PHP_FE(sha256, NULL)
1357+ PHP_FE(sha256_file, NULL)
1358 PHP_NAMED_FE(md5,php_if_md5, NULL)
1359 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1360 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1361@@ -632,7 +636,7 @@
1362 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1363
1364 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1365- PHP_FE(realpath, NULL)
1366+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1367 #endif
1368
1369 #ifdef HAVE_FNMATCH
1370@@ -2279,6 +2283,13 @@
1371 {
1372 zval retval;
1373 char *function_name = NULL;
1374+#if HARDENING_PATCH
1375+ zend_uint orig_code_type = EG(in_code_type);
1376+
1377+ if (shutdown_function_entry->created_by_eval) {
1378+ EG(in_code_type) = ZEND_EVAL_CODE;
1379+ }
1380+#endif
1381
1382 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1383 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1384@@ -2294,6 +2305,9 @@
1385 if (function_name) {
1386 efree(function_name);
1387 }
1388+#if HARDENING_PATCH
1389+ EG(in_code_type) = orig_code_type;
1390+#endif
1391 return 0;
1392 }
1393
1394@@ -2301,6 +2315,13 @@
1395 {
1396 zval retval;
1397 zval *function = tick_fe->arguments[0];
1398+#if HARDENING_PATCH
1399+ zend_uint orig_code_type = EG(in_code_type);
1400+
1401+ if (tick_fe->created_by_eval) {
1402+ EG(in_code_type) = ZEND_EVAL_CODE;
1403+ }
1404+#endif
1405
1406 /* Prevent reentrant calls to the same user ticks function */
1407 if (! tick_fe->calling) {
1408@@ -2332,6 +2353,9 @@
1409
1410 tick_fe->calling = 0;
1411 }
1412+#if HARDENING_PATCH
1413+ EG(in_code_type) = orig_code_type;
1414+#endif
1415 }
1416
1417 static void run_user_tick_functions(int tick_count)
1418@@ -2395,6 +2419,13 @@
1419 }
1420
1421 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
1422+#if HARDENING_PATCH
1423+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1424+ shutdown_function_entry.created_by_eval = 1;
1425+ } else {
1426+ shutdown_function_entry.created_by_eval = 0;
1427+ }
1428+#endif
1429
1430 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1431 efree(shutdown_function_entry.arguments);
1432@@ -2979,6 +3010,13 @@
1433 }
1434
1435 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1436+#if HARDENING_PATCH
1437+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1438+ tick_fe.created_by_eval = 1;
1439+ } else {
1440+ tick_fe.created_by_eval = 0;
1441+ }
1442+#endif
1443
1444 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1445 efree(tick_fe.arguments);
1446@@ -3282,6 +3320,35 @@
1447 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1448 }
1449
1450+ if (new_key[0] == 'H') {
1451+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1452+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1453+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1454+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1455+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1456+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1457+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1458+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1459+ efree(new_key);
1460+ return 0;
1461+ }
1462+ } else if (new_key[0] == '_') {
1463+ if ((strcmp(new_key, "_COOKIE")==0)||
1464+ (strcmp(new_key, "_ENV")==0)||
1465+ (strcmp(new_key, "_FILES")==0)||
1466+ (strcmp(new_key, "_GET")==0)||
1467+ (strcmp(new_key, "_POST")==0)||
1468+ (strcmp(new_key, "_REQUEST")==0)||
1469+ (strcmp(new_key, "_SESSION")==0)||
1470+ (strcmp(new_key, "_SERVER")==0)) {
1471+ efree(new_key);
1472+ return 0;
1473+ }
1474+ } else if (strcmp(new_key, "GLOBALS")==0) {
1475+ efree(new_key);
1476+ return 0;
1477+ }
1478+
1479 zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC);
1480 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1481
1482diff -Nura php-5.1.4/ext/standard/config.m4 hardening-patch-5.1.4-0.4.11/ext/standard/config.m4
1483--- php-5.1.4/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100
1484+++ hardening-patch-5.1.4-0.4.11/ext/standard/config.m4 2006-05-13 15:39:35.000000000 +0200
1485@@ -203,7 +203,7 @@
1486 if test "$ac_cv_crypt_blowfish" = "yes"; then
1487 ac_result=1
1488 else
1489- ac_result=0
1490+ ac_result=1
1491 fi
1492 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1493 ])
1494@@ -489,7 +489,7 @@
1495 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1496 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1497 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
1498- filters.c proc_open.c streamsfuncs.c http.c)
1499+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
1500
1501 PHP_ADD_MAKEFILE_FRAGMENT
1502
1503diff -Nura php-5.1.4/ext/standard/config.w32 hardening-patch-5.1.4-0.4.11/ext/standard/config.w32
1504--- php-5.1.4/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100
1505+++ hardening-patch-5.1.4-0.4.11/ext/standard/config.w32 2006-05-13 15:39:35.000000000 +0200
1506@@ -16,5 +16,5 @@
1507 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
1508 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
1509 user_filters.c uuencode.c filters.c proc_open.c \
1510- streamsfuncs.c http.c", false /* never shared */);
1511+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
1512
1513diff -Nura php-5.1.4/ext/standard/crypt_blowfish.c hardening-patch-5.1.4-0.4.11/ext/standard/crypt_blowfish.c
1514--- php-5.1.4/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1515+++ hardening-patch-5.1.4-0.4.11/ext/standard/crypt_blowfish.c 2006-05-13 15:39:35.000000000 +0200
1516@@ -0,0 +1,748 @@
1517+/*
1518+ * This code comes from John the Ripper password cracker, with reentrant
1519+ * and crypt(3) interfaces added, but optimizations specific to password
1520+ * cracking removed.
1521+ *
1522+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1523+ * placed in the public domain.
1524+ *
1525+ * There's absolutely no warranty.
1526+ *
1527+ * It is my intent that you should be able to use this on your system,
1528+ * as a part of a software package, or anywhere else to improve security,
1529+ * ensure compatibility, or for any other purpose. I would appreciate
1530+ * it if you give credit where it is due and keep your modifications in
1531+ * the public domain as well, but I don't require that in order to let
1532+ * you place this code and any modifications you make under a license
1533+ * of your choice.
1534+ *
1535+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1536+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1537+ * ideas. The password hashing algorithm was designed by David Mazieres
1538+ * <dm at lcs.mit.edu>.
1539+ *
1540+ * There's a paper on the algorithm that explains its design decisions:
1541+ *
1542+ * http://www.usenix.org/events/usenix99/provos.html
1543+ *
1544+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1545+ * Blowfish library (I can't be sure if I would think of something if I
1546+ * hadn't seen his code).
1547+ */
1548+
1549+#include <string.h>
1550+
1551+#include <errno.h>
1552+#ifndef __set_errno
1553+#define __set_errno(val) errno = (val)
1554+#endif
1555+
1556+#undef __CONST
1557+#ifdef __GNUC__
1558+#define __CONST __const
1559+#else
1560+#define __CONST
1561+#endif
1562+
1563+#ifdef __i386__
1564+#define BF_ASM 0
1565+#define BF_SCALE 1
1566+#elif defined(__alpha__) || defined(__hppa__)
1567+#define BF_ASM 0
1568+#define BF_SCALE 1
1569+#else
1570+#define BF_ASM 0
1571+#define BF_SCALE 0
1572+#endif
1573+
1574+typedef unsigned int BF_word;
1575+
1576+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1577+#define BF_N 16
1578+
1579+typedef BF_word BF_key[BF_N + 2];
1580+
1581+typedef struct {
1582+ BF_word S[4][0x100];
1583+ BF_key P;
1584+} BF_ctx;
1585+
1586+/*
1587+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1588+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1589+ */
1590+static BF_word BF_magic_w[6] = {
1591+ 0x4F727068, 0x65616E42, 0x65686F6C,
1592+ 0x64657253, 0x63727944, 0x6F756274
1593+};
1594+
1595+/*
1596+ * P-box and S-box tables initialized with digits of Pi.
1597+ */
1598+static BF_ctx BF_init_state = {
1599+ {
1600+ {
1601+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1602+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1603+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1604+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1605+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1606+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1607+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1608+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1609+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1610+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1611+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1612+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1613+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1614+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1615+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1616+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1617+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1618+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1619+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1620+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1621+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1622+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1623+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1624+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1625+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1626+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1627+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1628+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1629+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1630+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1631+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1632+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1633+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1634+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1635+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1636+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1637+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1638+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1639+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1640+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1641+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1642+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1643+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1644+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1645+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1646+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1647+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1648+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1649+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1650+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1651+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1652+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1653+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1654+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1655+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1656+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1657+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1658+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1659+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1660+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1661+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1662+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1663+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1664+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1665+ }, {
1666+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1667+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1668+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1669+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1670+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1671+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1672+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1673+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1674+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1675+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1676+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1677+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1678+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1679+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1680+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1681+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1682+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1683+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1684+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1685+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1686+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1687+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1688+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1689+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1690+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1691+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1692+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1693+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1694+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1695+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1696+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1697+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1698+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1699+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1700+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1701+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1702+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1703+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1704+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1705+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1706+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1707+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1708+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1709+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1710+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1711+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1712+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1713+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1714+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1715+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1716+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1717+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1718+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1719+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1720+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1721+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1722+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1723+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1724+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1725+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1726+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1727+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1728+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1729+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1730+ }, {
1731+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1732+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1733+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1734+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1735+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1736+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1737+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1738+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1739+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1740+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1741+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1742+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1743+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1744+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1745+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1746+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1747+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1748+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1749+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1750+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1751+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1752+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1753+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1754+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1755+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1756+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1757+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1758+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1759+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1760+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1761+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1762+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1763+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1764+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1765+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1766+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1767+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1768+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1769+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1770+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1771+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1772+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1773+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1774+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1775+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1776+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1777+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1778+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1779+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1780+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1781+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1782+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1783+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1784+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1785+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1786+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1787+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1788+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1789+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1790+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1791+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1792+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1793+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1794+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1795+ }, {
1796+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1797+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1798+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1799+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1800+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1801+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1802+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1803+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1804+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1805+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1806+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1807+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1808+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1809+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1810+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1811+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1812+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1813+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1814+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1815+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1816+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1817+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1818+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1819+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1820+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1821+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1822+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1823+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1824+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1825+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1826+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1827+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1828+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1829+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1830+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1831+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1832+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1833+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1834+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1835+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1836+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1837+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1838+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1839+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1840+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1841+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1842+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1843+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1844+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1845+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1846+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1847+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1848+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1849+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1850+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1851+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1852+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1853+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1854+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1855+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1856+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1857+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1858+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1859+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1860+ }
1861+ }, {
1862+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1863+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1864+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1865+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1866+ 0x9216d5d9, 0x8979fb1b
1867+ }
1868+};
1869+
1870+static unsigned char BF_itoa64[64 + 1] =
1871+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1872+
1873+static unsigned char BF_atoi64[0x60] = {
1874+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1875+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1876+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1877+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1878+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1879+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1880+};
1881+
1882+/*
1883+ * This may be optimized out if built with function inlining and no BF_ASM.
1884+ */
1885+static void clean(void *data, int size)
1886+{
1887+#if BF_ASM
1888+ extern void _BF_clean(void *data);
1889+#endif
1890+ memset(data, 0, size);
1891+#if BF_ASM
1892+ _BF_clean(data);
1893+#endif
1894+}
1895+
1896+#define BF_safe_atoi64(dst, src) \
1897+{ \
1898+ tmp = (unsigned char)(src); \
1899+ if (tmp == '$') break; \
1900+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1901+ tmp = BF_atoi64[tmp]; \
1902+ if (tmp > 63) return -1; \
1903+ (dst) = tmp; \
1904+}
1905+
1906+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1907+{
1908+ unsigned char *dptr = (unsigned char *)dst;
1909+ unsigned char *end = dptr + size;
1910+ unsigned char *sptr = (unsigned char *)src;
1911+ unsigned int tmp, c1, c2, c3, c4;
1912+
1913+ do {
1914+ BF_safe_atoi64(c1, *sptr++);
1915+ BF_safe_atoi64(c2, *sptr++);
1916+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1917+ if (dptr >= end) break;
1918+
1919+ BF_safe_atoi64(c3, *sptr++);
1920+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1921+ if (dptr >= end) break;
1922+
1923+ BF_safe_atoi64(c4, *sptr++);
1924+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1925+ } while (dptr < end);
1926+
1927+ while (dptr < end)
1928+ *dptr++ = 0;
1929+
1930+ return 0;
1931+}
1932+
1933+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1934+{
1935+ unsigned char *sptr = (unsigned char *)src;
1936+ unsigned char *end = sptr + size;
1937+ unsigned char *dptr = (unsigned char *)dst;
1938+ unsigned int c1, c2;
1939+
1940+ do {
1941+ c1 = *sptr++;
1942+ *dptr++ = BF_itoa64[c1 >> 2];
1943+ c1 = (c1 & 0x03) << 4;
1944+ if (sptr >= end) {
1945+ *dptr++ = BF_itoa64[c1];
1946+ break;
1947+ }
1948+
1949+ c2 = *sptr++;
1950+ c1 |= c2 >> 4;
1951+ *dptr++ = BF_itoa64[c1];
1952+ c1 = (c2 & 0x0f) << 2;
1953+ if (sptr >= end) {
1954+ *dptr++ = BF_itoa64[c1];
1955+ break;
1956+ }
1957+
1958+ c2 = *sptr++;
1959+ c1 |= c2 >> 6;
1960+ *dptr++ = BF_itoa64[c1];
1961+ *dptr++ = BF_itoa64[c2 & 0x3f];
1962+ } while (sptr < end);
1963+}
1964+
1965+static void BF_swap(BF_word *x, int count)
1966+{
1967+ static int endianness_check = 1;
1968+ char *is_little_endian = (char *)&endianness_check;
1969+ BF_word tmp;
1970+
1971+ if (*is_little_endian)
1972+ do {
1973+ tmp = *x;
1974+ tmp = (tmp << 16) | (tmp >> 16);
1975+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1976+ } while (--count);
1977+}
1978+
1979+#if BF_SCALE
1980+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1981+#define BF_ROUND(L, R, N) \
1982+ tmp1 = L & 0xFF; \
1983+ tmp2 = L >> 8; \
1984+ tmp2 &= 0xFF; \
1985+ tmp3 = L >> 16; \
1986+ tmp3 &= 0xFF; \
1987+ tmp4 = L >> 24; \
1988+ tmp1 = data.ctx.S[3][tmp1]; \
1989+ tmp2 = data.ctx.S[2][tmp2]; \
1990+ tmp3 = data.ctx.S[1][tmp3]; \
1991+ tmp3 += data.ctx.S[0][tmp4]; \
1992+ tmp3 ^= tmp2; \
1993+ R ^= data.ctx.P[N + 1]; \
1994+ tmp3 += tmp1; \
1995+ R ^= tmp3;
1996+#else
1997+/* Architectures with no complicated addressing modes supported */
1998+#define BF_INDEX(S, i) \
1999+ (*((BF_word *)(((unsigned char *)S) + (i))))
2000+#define BF_ROUND(L, R, N) \
2001+ tmp1 = L & 0xFF; \
2002+ tmp1 <<= 2; \
2003+ tmp2 = L >> 6; \
2004+ tmp2 &= 0x3FC; \
2005+ tmp3 = L >> 14; \
2006+ tmp3 &= 0x3FC; \
2007+ tmp4 = L >> 22; \
2008+ tmp4 &= 0x3FC; \
2009+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
2010+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
2011+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
2012+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
2013+ tmp3 ^= tmp2; \
2014+ R ^= data.ctx.P[N + 1]; \
2015+ tmp3 += tmp1; \
2016+ R ^= tmp3;
2017+#endif
2018+
2019+/*
2020+ * Encrypt one block, BF_N is hardcoded here.
2021+ */
2022+#define BF_ENCRYPT \
2023+ L ^= data.ctx.P[0]; \
2024+ BF_ROUND(L, R, 0); \
2025+ BF_ROUND(R, L, 1); \
2026+ BF_ROUND(L, R, 2); \
2027+ BF_ROUND(R, L, 3); \
2028+ BF_ROUND(L, R, 4); \
2029+ BF_ROUND(R, L, 5); \
2030+ BF_ROUND(L, R, 6); \
2031+ BF_ROUND(R, L, 7); \
2032+ BF_ROUND(L, R, 8); \
2033+ BF_ROUND(R, L, 9); \
2034+ BF_ROUND(L, R, 10); \
2035+ BF_ROUND(R, L, 11); \
2036+ BF_ROUND(L, R, 12); \
2037+ BF_ROUND(R, L, 13); \
2038+ BF_ROUND(L, R, 14); \
2039+ BF_ROUND(R, L, 15); \
2040+ tmp4 = R; \
2041+ R = L; \
2042+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2043+
2044+#if BF_ASM
2045+#define BF_body() \
2046+ _BF_body_r(&data.ctx);
2047+#else
2048+#define BF_body() \
2049+ L = R = 0; \
2050+ ptr = data.ctx.P; \
2051+ do { \
2052+ ptr += 2; \
2053+ BF_ENCRYPT; \
2054+ *(ptr - 2) = L; \
2055+ *(ptr - 1) = R; \
2056+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2057+\
2058+ ptr = data.ctx.S[0]; \
2059+ do { \
2060+ ptr += 2; \
2061+ BF_ENCRYPT; \
2062+ *(ptr - 2) = L; \
2063+ *(ptr - 1) = R; \
2064+ } while (ptr < &data.ctx.S[3][0xFF]);
2065+#endif
2066+
2067+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2068+{
2069+ __CONST char *ptr = key;
2070+ int i, j;
2071+ BF_word tmp;
2072+
2073+ for (i = 0; i < BF_N + 2; i++) {
2074+ tmp = 0;
2075+ for (j = 0; j < 4; j++) {
2076+ tmp <<= 8;
2077+ tmp |= *ptr;
2078+
2079+ if (!*ptr) ptr = key; else ptr++;
2080+ }
2081+
2082+ expanded[i] = tmp;
2083+ initial[i] = BF_init_state.P[i] ^ tmp;
2084+ }
2085+}
2086+
2087+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2088+ char *output, int size)
2089+{
2090+#if BF_ASM
2091+ extern void _BF_body_r(BF_ctx *ctx);
2092+#endif
2093+ struct {
2094+ BF_ctx ctx;
2095+ BF_key expanded_key;
2096+ union {
2097+ BF_word salt[4];
2098+ BF_word output[6];
2099+ } binary;
2100+ } data;
2101+ BF_word L, R;
2102+ BF_word tmp1, tmp2, tmp3, tmp4;
2103+ BF_word *ptr;
2104+ BF_word count;
2105+ int i;
2106+
2107+ if (size < 7 + 22 + 31 + 1) {
2108+ __set_errno(ERANGE);
2109+ return NULL;
2110+ }
2111+
2112+ if (setting[0] != '$' ||
2113+ setting[1] != '2' ||
2114+ setting[2] != 'a' ||
2115+ setting[3] != '$' ||
2116+ setting[4] < '0' || setting[4] > '3' ||
2117+ setting[5] < '0' || setting[5] > '9' ||
2118+ setting[6] != '$') {
2119+ __set_errno(EINVAL);
2120+ return NULL;
2121+ }
2122+
2123+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2124+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2125+ clean(data.binary.salt, sizeof(data.binary.salt));
2126+ __set_errno(EINVAL);
2127+ return NULL;
2128+ }
2129+
2130+ BF_swap(data.binary.salt, 4);
2131+
2132+ BF_set_key(key, data.expanded_key, data.ctx.P);
2133+
2134+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2135+
2136+ L = R = 0;
2137+ for (i = 0; i < BF_N + 2; i += 2) {
2138+ L ^= data.binary.salt[i & 2];
2139+ R ^= data.binary.salt[(i & 2) + 1];
2140+ BF_ENCRYPT;
2141+ data.ctx.P[i] = L;
2142+ data.ctx.P[i + 1] = R;
2143+ }
2144+
2145+ ptr = data.ctx.S[0];
2146+ do {
2147+ ptr += 4;
2148+ L ^= data.binary.salt[(BF_N + 2) & 3];
2149+ R ^= data.binary.salt[(BF_N + 3) & 3];
2150+ BF_ENCRYPT;
2151+ *(ptr - 4) = L;
2152+ *(ptr - 3) = R;
2153+
2154+ L ^= data.binary.salt[(BF_N + 4) & 3];
2155+ R ^= data.binary.salt[(BF_N + 5) & 3];
2156+ BF_ENCRYPT;
2157+ *(ptr - 2) = L;
2158+ *(ptr - 1) = R;
2159+ } while (ptr < &data.ctx.S[3][0xFF]);
2160+
2161+ do {
2162+ data.ctx.P[0] ^= data.expanded_key[0];
2163+ data.ctx.P[1] ^= data.expanded_key[1];
2164+ data.ctx.P[2] ^= data.expanded_key[2];
2165+ data.ctx.P[3] ^= data.expanded_key[3];
2166+ data.ctx.P[4] ^= data.expanded_key[4];
2167+ data.ctx.P[5] ^= data.expanded_key[5];
2168+ data.ctx.P[6] ^= data.expanded_key[6];
2169+ data.ctx.P[7] ^= data.expanded_key[7];
2170+ data.ctx.P[8] ^= data.expanded_key[8];
2171+ data.ctx.P[9] ^= data.expanded_key[9];
2172+ data.ctx.P[10] ^= data.expanded_key[10];
2173+ data.ctx.P[11] ^= data.expanded_key[11];
2174+ data.ctx.P[12] ^= data.expanded_key[12];
2175+ data.ctx.P[13] ^= data.expanded_key[13];
2176+ data.ctx.P[14] ^= data.expanded_key[14];
2177+ data.ctx.P[15] ^= data.expanded_key[15];
2178+ data.ctx.P[16] ^= data.expanded_key[16];
2179+ data.ctx.P[17] ^= data.expanded_key[17];
2180+
2181+ BF_body();
2182+
2183+ tmp1 = data.binary.salt[0];
2184+ tmp2 = data.binary.salt[1];
2185+ tmp3 = data.binary.salt[2];
2186+ tmp4 = data.binary.salt[3];
2187+ data.ctx.P[0] ^= tmp1;
2188+ data.ctx.P[1] ^= tmp2;
2189+ data.ctx.P[2] ^= tmp3;
2190+ data.ctx.P[3] ^= tmp4;
2191+ data.ctx.P[4] ^= tmp1;
2192+ data.ctx.P[5] ^= tmp2;
2193+ data.ctx.P[6] ^= tmp3;
2194+ data.ctx.P[7] ^= tmp4;
2195+ data.ctx.P[8] ^= tmp1;
2196+ data.ctx.P[9] ^= tmp2;
2197+ data.ctx.P[10] ^= tmp3;
2198+ data.ctx.P[11] ^= tmp4;
2199+ data.ctx.P[12] ^= tmp1;
2200+ data.ctx.P[13] ^= tmp2;
2201+ data.ctx.P[14] ^= tmp3;
2202+ data.ctx.P[15] ^= tmp4;
2203+ data.ctx.P[16] ^= tmp1;
2204+ data.ctx.P[17] ^= tmp2;
2205+
2206+ BF_body();
2207+ } while (--count);
2208+
2209+ for (i = 0; i < 6; i += 2) {
2210+ L = BF_magic_w[i];
2211+ R = BF_magic_w[i + 1];
2212+
2213+ count = 64;
2214+ do {
2215+ BF_ENCRYPT;
2216+ } while (--count);
2217+
2218+ data.binary.output[i] = L;
2219+ data.binary.output[i + 1] = R;
2220+ }
2221+
2222+ memcpy(output, setting, 7 + 22 - 1);
2223+ output[7 + 22 - 1] = BF_itoa64[(int)
2224+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2225+
2226+/* This has to be bug-compatible with the original implementation, so
2227+ * only encode 23 of the 24 bytes. :-) */
2228+ BF_swap(data.binary.output, 6);
2229+ BF_encode(&output[7 + 22], data.binary.output, 23);
2230+ output[7 + 22 + 31] = '\0';
2231+
2232+/* Overwrite the most obvious sensitive data we have on the stack. Note
2233+ * that this does not guarantee there's no sensitive data left on the
2234+ * stack and/or in registers; I'm not aware of portable code that does. */
2235+ clean(&data, sizeof(data));
2236+
2237+ return output;
2238+}
2239+
2240+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2241+ __CONST char *input, int size, char *output, int output_size)
2242+{
2243+ if (size < 16 || output_size < 7 + 22 + 1 ||
2244+ (count && (count < 4 || count > 31))) {
2245+ if (output_size > 0) output[0] = '\0';
2246+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2247+ return NULL;
2248+ }
2249+
2250+ if (!count) count = 5;
2251+
2252+ output[0] = '$';
2253+ output[1] = '2';
2254+ output[2] = 'a';
2255+ output[3] = '$';
2256+ output[4] = '0' + count / 10;
2257+ output[5] = '0' + count % 10;
2258+ output[6] = '$';
2259+
2260+ BF_encode(&output[7], (BF_word *)input, 16);
2261+ output[7 + 22] = '\0';
2262+
2263+ return output;
2264+}
2265diff -Nura php-5.1.4/ext/standard/crypt.c hardening-patch-5.1.4-0.4.11/ext/standard/crypt.c
2266--- php-5.1.4/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100
2267+++ hardening-patch-5.1.4-0.4.11/ext/standard/crypt.c 2006-05-13 15:39:35.000000000 +0200
2268@@ -100,6 +100,8 @@
2269 return SUCCESS;
2270 }
2271
2272+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2273+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2274
2275 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2276
2277@@ -135,7 +137,14 @@
2278
2279 /* The automatic salt generation only covers standard DES and md5-crypt */
2280 if(!*salt) {
2281-#if PHP_MD5_CRYPT
2282+#if PHP_BLOWFISH_CRYPT
2283+ char randat[16];
2284+ int i;
2285+
2286+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2287+
2288+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2289+#elif PHP_MD5_CRYPT
2290 strcpy(salt, "$1$");
2291 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2292 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2293@@ -145,8 +154,24 @@
2294 salt[2] = '\0';
2295 #endif
2296 }
2297-
2298- RETVAL_STRING(crypt(str, salt), 1);
2299+
2300+ if (salt[0] == '$' &&
2301+ salt[1] == '2' &&
2302+ salt[2] == 'a' &&
2303+ salt[3] == '$' &&
2304+ salt[4] >= '0' && salt[4] <= '3' &&
2305+ salt[5] >= '0' && salt[5] <= '9' &&
2306+ salt[6] == '$') {
2307+
2308+ char output[PHP_MAX_SALT_LEN+1];
2309+
2310+ output[0] = 0;
2311+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2312+ RETVAL_STRING(output, 1);
2313+
2314+ } else {
2315+ RETVAL_STRING(crypt(str, salt), 1);
2316+ }
2317 }
2318 /* }}} */
2319 #endif
2320diff -Nura php-5.1.4/ext/standard/dl.c hardening-patch-5.1.4-0.4.11/ext/standard/dl.c
2321--- php-5.1.4/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100
2322+++ hardening-patch-5.1.4-0.4.11/ext/standard/dl.c 2006-05-13 15:39:35.000000000 +0200
2323@@ -164,8 +164,35 @@
2324 RETURN_FALSE;
2325 }
2326 module_entry = get_module();
2327+
2328+ /* check if Hardening-Patch is installed */
2329+ if (module_entry->zend_api < 1000000000) {
2330+ php_error_docref(NULL TSRMLS_CC, error_type,
2331+ "%s: Unable to initialize module\n"
2332+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2333+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2334+ "These options need to match\n",
2335+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2336+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2337+ DL_UNLOAD(handle);
2338+ RETURN_FALSE;
2339+ }
2340+
2341+ /* check if correct Hardening-Patch is installed */
2342+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2343+ php_error_docref(NULL TSRMLS_CC, error_type,
2344+ "%s: Unable to initialize module\n"
2345+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2346+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2347+ "These options need to match\n",
2348+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2349+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2350+ DL_UNLOAD(handle);
2351+ RETURN_FALSE;
2352+ }
2353+
2354 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2355- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2356+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2357 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2358 struct pre_4_1_0_module_entry {
2359 char *name;
2360@@ -199,7 +226,7 @@
2361 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2362 } else {
2363 name = module_entry->name;
2364- zend_api = module_entry->zend_api;
2365+ zend_api = module_entry->real_zend_api;
2366 zend_debug = module_entry->zend_debug;
2367 zts = module_entry->zts;
2368 }
2369diff -Nura php-5.1.4/ext/standard/file.c hardening-patch-5.1.4-0.4.11/ext/standard/file.c
2370--- php-5.1.4/ext/standard/file.c 2006-04-06 04:39:55.000000000 +0200
2371+++ hardening-patch-5.1.4-0.4.11/ext/standard/file.c 2006-05-13 15:39:35.000000000 +0200
2372@@ -2302,7 +2302,7 @@
2373 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2374 /* {{{ proto string realpath(string path)
2375 Return the resolved path */
2376-PHP_FUNCTION(realpath)
2377+PHP_FUNCTION(real_path)
2378 {
2379 zval **path;
2380 char resolved_path_buff[MAXPATHLEN];
2381diff -Nura php-5.1.4/ext/standard/file.h hardening-patch-5.1.4-0.4.11/ext/standard/file.h
2382--- php-5.1.4/ext/standard/file.h 2006-01-13 05:05:59.000000000 +0100
2383+++ hardening-patch-5.1.4-0.4.11/ext/standard/file.h 2006-05-13 15:39:35.000000000 +0200
2384@@ -61,7 +61,7 @@
2385 PHP_FUNCTION(fd_set);
2386 PHP_FUNCTION(fd_isset);
2387 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
2388-PHP_FUNCTION(realpath);
2389+PHP_FUNCTION(real_path);
2390 PHP_FUNCTION(fnmatch);
2391 #endif
2392 PHP_NAMED_FUNCTION(php_if_ftruncate);
2393diff -Nura php-5.1.4/ext/standard/head.c hardening-patch-5.1.4-0.4.11/ext/standard/head.c
2394--- php-5.1.4/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100
2395+++ hardening-patch-5.1.4-0.4.11/ext/standard/head.c 2006-05-13 15:39:35.000000000 +0200
2396@@ -45,7 +45,7 @@
2397 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2398 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2399 return;
2400-
2401+
2402 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2403 }
2404 /* }}} */
2405diff -Nura php-5.1.4/ext/standard/info.c hardening-patch-5.1.4-0.4.11/ext/standard/info.c
2406--- php-5.1.4/ext/standard/info.c 2006-03-31 13:11:12.000000000 +0200
2407+++ hardening-patch-5.1.4-0.4.11/ext/standard/info.c 2006-05-13 15:39:35.000000000 +0200
2408@@ -411,7 +411,7 @@
2409
2410 if (flag & PHP_INFO_GENERAL) {
2411 char *zend_version = get_zend_version();
2412- char temp_api[10];
2413+ char temp_api[11];
2414 char *logo_guid;
2415
2416 php_uname = php_get_uname('a');
2417@@ -434,11 +434,22 @@
2418 PUTS("\" alt=\"PHP Logo\" /></a>");
2419 }
2420
2421+#if HARDENING_PATCH
2422+ if (!sapi_module.phpinfo_as_text) {
2423+ 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);
2424+ } else {
2425+ char temp_ver[40];
2426+
2427+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2428+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2429+ }
2430+#else
2431 if (!sapi_module.phpinfo_as_text) {
2432 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2433 } else {
2434 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2435- }
2436+ }
2437+#endif
2438 php_info_print_box_end();
2439 php_info_print_table_start();
2440 php_info_print_table_row(2, "System", php_uname );
2441diff -Nura php-5.1.4/ext/standard/php_standard.h hardening-patch-5.1.4-0.4.11/ext/standard/php_standard.h
2442--- php-5.1.4/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100
2443+++ hardening-patch-5.1.4-0.4.11/ext/standard/php_standard.h 2006-05-13 15:39:35.000000000 +0200
2444@@ -28,6 +28,7 @@
2445 #include "php_mail.h"
2446 #include "md5.h"
2447 #include "sha1.h"
2448+#include "sha256.h"
2449 #include "html.h"
2450 #include "exec.h"
2451 #include "file.h"
2452diff -Nura php-5.1.4/ext/standard/sha256.c hardening-patch-5.1.4-0.4.11/ext/standard/sha256.c
2453--- php-5.1.4/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2454+++ hardening-patch-5.1.4-0.4.11/ext/standard/sha256.c 2006-05-13 15:39:35.000000000 +0200
2455@@ -0,0 +1,388 @@
2456+/*
2457+ +----------------------------------------------------------------------+
2458+ | PHP Version 5 |
2459+ +----------------------------------------------------------------------+
2460+ | Copyright (c) 1997-2004 The PHP Group |
2461+ +----------------------------------------------------------------------+
2462+ | This source file is subject to version 3.0 of the PHP license, |
2463+ | that is bundled with this package in the file LICENSE, and is |
2464+ | available through the world-wide-web at the following url: |
2465+ | http://www.php.net/license/3_0.txt. |
2466+ | If you did not receive a copy of the PHP license and are unable to |
2467+ | obtain it through the world-wide-web, please send a note to |
2468+ | license@php.net so we can mail you a copy immediately. |
2469+ +----------------------------------------------------------------------+
2470+ | Author: Stefan Esser <sesser@php.net> |
2471+ +----------------------------------------------------------------------+
2472+*/
2473+
2474+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2475+
2476+#include "php.h"
2477+
2478+/* This code is heavily based on the PHP md5/sha1 implementations */
2479+
2480+#include "sha256.h"
2481+
2482+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2483+{
2484+ int i;
2485+
2486+ for (i = 0; i < 32; i++) {
2487+ sprintf(sha256str, "%02x", digest[i]);
2488+ sha256str += 2;
2489+ }
2490+
2491+ *sha256str = '\0';
2492+}
2493+
2494+/* {{{ proto string sha256(string str [, bool raw_output])
2495+ Calculate the sha256 hash of a string */
2496+PHP_FUNCTION(sha256)
2497+{
2498+ char *arg;
2499+ int arg_len;
2500+ zend_bool raw_output = 0;
2501+ char sha256str[65];
2502+ PHP_SHA256_CTX context;
2503+ unsigned char digest[32];
2504+
2505+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2506+ return;
2507+ }
2508+
2509+ sha256str[0] = '\0';
2510+ PHP_SHA256Init(&context);
2511+ PHP_SHA256Update(&context, arg, arg_len);
2512+ PHP_SHA256Final(digest, &context);
2513+ if (raw_output) {
2514+ RETURN_STRINGL(digest, 32, 1);
2515+ } else {
2516+ make_sha256_digest(sha256str, digest);
2517+ RETVAL_STRING(sha256str, 1);
2518+ }
2519+
2520+}
2521+
2522+/* }}} */
2523+
2524+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2525+ Calculate the sha256 hash of given filename */
2526+PHP_FUNCTION(sha256_file)
2527+{
2528+ char *arg;
2529+ int arg_len;
2530+ zend_bool raw_output = 0;
2531+ char sha256str[65];
2532+ unsigned char buf[1024];
2533+ unsigned char digest[32];
2534+ PHP_SHA256_CTX context;
2535+ int n;
2536+ php_stream *stream;
2537+
2538+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2539+ return;
2540+ }
2541+
2542+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
2543+ if (!stream) {
2544+ RETURN_FALSE;
2545+ }
2546+
2547+ PHP_SHA256Init(&context);
2548+
2549+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
2550+ PHP_SHA256Update(&context, buf, n);
2551+ }
2552+
2553+ PHP_SHA256Final(digest, &context);
2554+
2555+ php_stream_close(stream);
2556+
2557+ if (n<0) {
2558+ RETURN_FALSE;
2559+ }
2560+
2561+ if (raw_output) {
2562+ RETURN_STRINGL(digest, 32, 1);
2563+ } else {
2564+ make_sha256_digest(sha256str, digest);
2565+ RETVAL_STRING(sha256str, 1);
2566+ }
2567+}
2568+/* }}} */
2569+
2570+
2571+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2572+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2573+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2574+
2575+static unsigned char PADDING[64] =
2576+{
2577+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2578+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2579+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2580+};
2581+
2582+/* F, G, H and I are basic SHA256 functions.
2583+ */
2584+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2585+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2586+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2587+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2588+
2589+/* ROTATE_RIGHT rotates x right n bits.
2590+ */
2591+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2592+
2593+/* W[i]
2594+ */
2595+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2596+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2597+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2598+
2599+/* ROUND function of sha256
2600+ */
2601+
2602+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2603+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2604+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2605+ (d) += t1; \
2606+ }
2607+
2608+
2609+/* {{{ PHP_SHA256Init
2610+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2611+ */
2612+static void PHP_SHA256Init(PHP_SHA256_CTX * context)
2613+{
2614+ context->count[0] = context->count[1] = 0;
2615+ /* Load magic initialization constants.
2616+ */
2617+ context->state[0] = 0x6a09e667;
2618+ context->state[1] = 0xbb67ae85;
2619+ context->state[2] = 0x3c6ef372;
2620+ context->state[3] = 0xa54ff53a;
2621+ context->state[4] = 0x510e527f;
2622+ context->state[5] = 0x9b05688c;
2623+ context->state[6] = 0x1f83d9ab;
2624+ context->state[7] = 0x5be0cd19;
2625+}
2626+/* }}} */
2627+
2628+/* {{{ PHP_SHA256Update
2629+ SHA256 block update operation. Continues an SHA256 message-digest
2630+ operation, processing another message block, and updating the
2631+ context.
2632+ */
2633+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2634+ unsigned int inputLen)
2635+{
2636+ unsigned int i, index, partLen;
2637+
2638+ /* Compute number of bytes mod 64 */
2639+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2640+
2641+ /* Update number of bits */
2642+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2643+ < ((php_uint32) inputLen << 3))
2644+ context->count[1]++;
2645+ context->count[1] += ((php_uint32) inputLen >> 29);
2646+
2647+ partLen = 64 - index;
2648+
2649+ /* Transform as many times as possible.
2650+ */
2651+ if (inputLen >= partLen) {
2652+ memcpy
2653+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2654+ SHA256Transform(context->state, context->buffer);
2655+
2656+ for (i = partLen; i + 63 < inputLen; i += 64)
2657+ SHA256Transform(context->state, &input[i]);
2658+
2659+ index = 0;
2660+ } else
2661+ i = 0;
2662+
2663+ /* Buffer remaining input */
2664+ memcpy
2665+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2666+ inputLen - i);
2667+}
2668+/* }}} */
2669+
2670+/* {{{ PHP_SHA256Final
2671+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2672+ the message digest and zeroizing the context.
2673+ */
2674+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2675+{
2676+ unsigned char bits[8];
2677+ unsigned int index, padLen;
2678+
2679+ /* Save number of bits */
2680+ bits[7] = context->count[0] & 0xFF;
2681+ bits[6] = (context->count[0] >> 8) & 0xFF;
2682+ bits[5] = (context->count[0] >> 16) & 0xFF;
2683+ bits[4] = (context->count[0] >> 24) & 0xFF;
2684+ bits[3] = context->count[1] & 0xFF;
2685+ bits[2] = (context->count[1] >> 8) & 0xFF;
2686+ bits[1] = (context->count[1] >> 16) & 0xFF;
2687+ bits[0] = (context->count[1] >> 24) & 0xFF;
2688+
2689+ /* Pad out to 56 mod 64.
2690+ */
2691+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2692+ padLen = (index < 56) ? (56 - index) : (120 - index);
2693+ PHP_SHA256Update(context, PADDING, padLen);
2694+
2695+ /* Append length (before padding) */
2696+ PHP_SHA256Update(context, bits, 8);
2697+
2698+ /* Store state in digest */
2699+ SHA256Encode(digest, context->state, 32);
2700+
2701+ /* Zeroize sensitive information.
2702+ */
2703+ memset((unsigned char*) context, 0, sizeof(*context));
2704+}
2705+/* }}} */
2706+
2707+/* {{{ SHA256Transform
2708+ * SHA256 basic transformation. Transforms state based on block.
2709+ */
2710+static void SHA256Transform(state, block)
2711+php_uint32 state[8];
2712+const unsigned char block[64];
2713+{
2714+ php_uint32 a = state[0], b = state[1], c = state[2];
2715+ php_uint32 d = state[3], e = state[4], f = state[5];
2716+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2717+
2718+ SHA256Decode(x, block, 64);
2719+
2720+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2721+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2722+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2723+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2724+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2725+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2726+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2727+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2728+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2729+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2730+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2731+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2732+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2733+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2734+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2735+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2736+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2737+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2738+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2739+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2740+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2741+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2742+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2743+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2744+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2745+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2746+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2747+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2748+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2749+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2750+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2751+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2752+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2753+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2754+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2755+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2756+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2757+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2758+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2759+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2760+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2761+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2762+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2763+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2764+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2765+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2766+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2767+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2768+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2769+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2770+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2771+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2772+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2773+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2774+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2775+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2776+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2777+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2778+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2779+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2780+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2781+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2782+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2783+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2784+
2785+ state[0] += a;
2786+ state[1] += b;
2787+ state[2] += c;
2788+ state[3] += d;
2789+ state[4] += e;
2790+ state[5] += f;
2791+ state[6] += g;
2792+ state[7] += h;
2793+
2794+ /* Zeroize sensitive information. */
2795+ memset((unsigned char*) x, 0, sizeof(x));
2796+}
2797+/* }}} */
2798+
2799+/* {{{ SHA256Encode
2800+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2801+ a multiple of 4.
2802+ */
2803+static void SHA256Encode(output, input, len)
2804+unsigned char *output;
2805+php_uint32 *input;
2806+unsigned int len;
2807+{
2808+ unsigned int i, j;
2809+
2810+ for (i = 0, j = 0; j < len; i++, j += 4) {
2811+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2812+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2813+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2814+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2815+ }
2816+}
2817+/* }}} */
2818+
2819+/* {{{ SHA256Decode
2820+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2821+ a multiple of 4.
2822+ */
2823+static void SHA256Decode(output, input, len)
2824+php_uint32 *output;
2825+const unsigned char *input;
2826+unsigned int len;
2827+{
2828+ unsigned int i, j;
2829+
2830+ for (i = 0, j = 0; j < len; i++, j += 4)
2831+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2832+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2833+}
2834+/* }}} */
2835+
2836+/*
2837+ * Local variables:
2838+ * tab-width: 4
2839+ * c-basic-offset: 4
2840+ * End:
2841+ * vim600: sw=4 ts=4 fdm=marker
2842+ * vim<600: sw=4 ts=4
2843+ */
2844diff -Nura php-5.1.4/ext/standard/sha256.h hardening-patch-5.1.4-0.4.11/ext/standard/sha256.h
2845--- php-5.1.4/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2846+++ hardening-patch-5.1.4-0.4.11/ext/standard/sha256.h 2006-05-13 15:39:35.000000000 +0200
2847@@ -0,0 +1,40 @@
2848+/*
2849+ +----------------------------------------------------------------------+
2850+ | PHP Version 5 |
2851+ +----------------------------------------------------------------------+
2852+ | Copyright (c) 1997-2004 The PHP Group |
2853+ +----------------------------------------------------------------------+
2854+ | This source file is subject to version 3.0 of the PHP license, |
2855+ | that is bundled with this package in the file LICENSE, and is |
2856+ | available through the world-wide-web at the following url: |
2857+ | http://www.php.net/license/3_0.txt. |
2858+ | If you did not receive a copy of the PHP license and are unable to |
2859+ | obtain it through the world-wide-web, please send a note to |
2860+ | license@php.net so we can mail you a copy immediately. |
2861+ +----------------------------------------------------------------------+
2862+ | Author: Stefan Esser <sesser@php.net> |
2863+ +----------------------------------------------------------------------+
2864+*/
2865+
2866+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2867+
2868+#ifndef SHA256_H
2869+#define SHA256_H
2870+
2871+#include "ext/standard/basic_functions.h"
2872+
2873+/* SHA1 context. */
2874+typedef struct {
2875+ php_uint32 state[8]; /* state (ABCD) */
2876+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2877+ unsigned char buffer[64]; /* input buffer */
2878+} PHP_SHA256_CTX;
2879+
2880+static void PHP_SHA256Init(PHP_SHA256_CTX *);
2881+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2882+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2883+
2884+PHP_FUNCTION(sha256);
2885+PHP_FUNCTION(sha256_file);
2886+
2887+#endif
2888diff -Nura php-5.1.4/ext/standard/syslog.c hardening-patch-5.1.4-0.4.11/ext/standard/syslog.c
2889--- php-5.1.4/ext/standard/syslog.c 2006-03-21 01:59:08.000000000 +0100
2890+++ hardening-patch-5.1.4-0.4.11/ext/standard/syslog.c 2006-05-13 15:39:35.000000000 +0200
2891@@ -42,6 +42,7 @@
2892 */
2893 PHP_MINIT_FUNCTION(syslog)
2894 {
2895+#if !HARDENING_PATCH
2896 /* error levels */
2897 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2898 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2899@@ -97,6 +98,7 @@
2900 /* AIX doesn't have LOG_PERROR */
2901 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2902 #endif
2903+#endif
2904 BG(syslog_device)=NULL;
2905
2906 return SUCCESS;
2907diff -Nura php-5.1.4/ext/varfilter/config.m4 hardening-patch-5.1.4-0.4.11/ext/varfilter/config.m4
2908--- php-5.1.4/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2909+++ hardening-patch-5.1.4-0.4.11/ext/varfilter/config.m4 2006-05-13 15:39:35.000000000 +0200
2910@@ -0,0 +1,11 @@
2911+dnl
2912+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2913+dnl
2914+
2915+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2916+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2917+
2918+if test "$PHP_VARFILTER" != "no"; then
2919+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2920+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2921+fi
2922diff -Nura php-5.1.4/ext/varfilter/CREDITS hardening-patch-5.1.4-0.4.11/ext/varfilter/CREDITS
2923--- php-5.1.4/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2924+++ hardening-patch-5.1.4-0.4.11/ext/varfilter/CREDITS 2006-05-13 15:39:35.000000000 +0200
2925@@ -0,0 +1,2 @@
2926+varfilter
2927+Stefan Esser
2928\ Kein Zeilenumbruch am Dateiende.
2929diff -Nura php-5.1.4/ext/varfilter/php_varfilter.h hardening-patch-5.1.4-0.4.11/ext/varfilter/php_varfilter.h
2930--- php-5.1.4/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2931+++ hardening-patch-5.1.4-0.4.11/ext/varfilter/php_varfilter.h 2006-05-13 15:39:35.000000000 +0200
2932@@ -0,0 +1,144 @@
2933+/*
2934+ +----------------------------------------------------------------------+
2935+ | Hardened-PHP Project's varfilter extension |
2936+ +----------------------------------------------------------------------+
2937+ | Copyright (c) 2004-2005 Stefan Esser |
2938+ +----------------------------------------------------------------------+
2939+ | This source file is subject to version 2.02 of the PHP license, |
2940+ | that is bundled with this package in the file LICENSE, and is |
2941+ | available at through the world-wide-web at |
2942+ | http://www.php.net/license/2_02.txt. |
2943+ | If you did not receive a copy of the PHP license and are unable to |
2944+ | obtain it through the world-wide-web, please send a note to |
2945+ | license@php.net so we can mail you a copy immediately. |
2946+ +----------------------------------------------------------------------+
2947+ | Author: Stefan Esser <sesser@hardened-php.net> |
2948+ +----------------------------------------------------------------------+
2949+
2950+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2951+*/
2952+
2953+#ifndef PHP_VARFILTER_H
2954+#define PHP_VARFILTER_H
2955+
2956+extern zend_module_entry varfilter_module_entry;
2957+#define phpext_varfilter_ptr &varfilter_module_entry
2958+
2959+#ifdef PHP_WIN32
2960+#define PHP_VARFILTER_API __declspec(dllexport)
2961+#else
2962+#define PHP_VARFILTER_API
2963+#endif
2964+
2965+#ifdef ZTS
2966+#include "TSRM.h"
2967+#endif
2968+
2969+#include "SAPI.h"
2970+
2971+#include "php_variables.h"
2972+
2973+#ifdef ZEND_ENGINE_2
2974+#define HASH_HTTP_GET_VARS 0x2095733f
2975+#define HASH_HTTP_POST_VARS 0xbfee1265
2976+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
2977+#define HASH_HTTP_ENV_VARS 0x1fe186a8
2978+#define HASH_HTTP_SERVER_VARS 0xc987afd6
2979+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
2980+#define HASH_HTTP_POST_FILES 0x98eb1ddc
2981+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
2982+#else
2983+#define HASH_HTTP_GET_VARS 0x8d8645bd
2984+#define HASH_HTTP_POST_VARS 0x7c699bf3
2985+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
2986+#define HASH_HTTP_ENV_VARS 0x84da3016
2987+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
2988+#define HASH_HTTP_SESSION_VARS 0x322906f5
2989+#define HASH_HTTP_POST_FILES 0xe4e4ce70
2990+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
2991+#endif
2992+
2993+PHP_MINIT_FUNCTION(varfilter);
2994+PHP_MSHUTDOWN_FUNCTION(varfilter);
2995+PHP_RINIT_FUNCTION(varfilter);
2996+PHP_RSHUTDOWN_FUNCTION(varfilter);
2997+PHP_MINFO_FUNCTION(varfilter);
2998+
2999+
3000+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
3001+/* request variables */
3002+ long max_request_variables;
3003+ long cur_request_variables;
3004+ long max_varname_length;
3005+ long max_totalname_length;
3006+ long max_value_length;
3007+ long max_array_depth;
3008+ long max_array_index_length;
3009+ zend_bool disallow_nul;
3010+/* cookie variables */
3011+ long max_cookie_vars;
3012+ long cur_cookie_vars;
3013+ long max_cookie_name_length;
3014+ long max_cookie_totalname_length;
3015+ long max_cookie_value_length;
3016+ long max_cookie_array_depth;
3017+ long max_cookie_array_index_length;
3018+ zend_bool disallow_cookie_nul;
3019+/* get variables */
3020+ long max_get_vars;
3021+ long cur_get_vars;
3022+ long max_get_name_length;
3023+ long max_get_totalname_length;
3024+ long max_get_value_length;
3025+ long max_get_array_depth;
3026+ long max_get_array_index_length;
3027+ zend_bool disallow_get_nul;
3028+/* post variables */
3029+ long max_post_vars;
3030+ long cur_post_vars;
3031+ long max_post_name_length;
3032+ long max_post_totalname_length;
3033+ long max_post_value_length;
3034+ long max_post_array_depth;
3035+ long max_post_array_index_length;
3036+ zend_bool disallow_post_nul;
3037+/* fileupload */
3038+ long max_uploads;
3039+ long cur_uploads;
3040+ zend_bool disallow_elf_files;
3041+ char *verification_script;
3042+
3043+ zend_bool no_more_variables;
3044+ zend_bool no_more_get_variables;
3045+ zend_bool no_more_post_variables;
3046+ zend_bool no_more_cookie_variables;
3047+ zend_bool no_more_uploads;
3048+
3049+ZEND_END_MODULE_GLOBALS(varfilter)
3050+
3051+
3052+#ifdef ZTS
3053+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3054+#else
3055+#define VARFILTER_G(v) (varfilter_globals.v)
3056+#endif
3057+
3058+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3059+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3060+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3061+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3062+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3063+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3064+
3065+
3066+
3067+#endif /* PHP_VARFILTER_H */
3068+
3069+
3070+/*
3071+ * Local variables:
3072+ * tab-width: 4
3073+ * c-basic-offset: 4
3074+ * indent-tabs-mode: t
3075+ * End:
3076+ */
3077diff -Nura php-5.1.4/ext/varfilter/varfilter.c hardening-patch-5.1.4-0.4.11/ext/varfilter/varfilter.c
3078--- php-5.1.4/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3079+++ hardening-patch-5.1.4-0.4.11/ext/varfilter/varfilter.c 2006-05-13 15:53:08.000000000 +0200
3080@@ -0,0 +1,915 @@
3081+/*
3082+ +----------------------------------------------------------------------+
3083+ | Hardened-PHP Project's varfilter extension |
3084+ +----------------------------------------------------------------------+
3085+ | Copyright (c) 2004-2005 Stefan Esser |
3086+ +----------------------------------------------------------------------+
3087+ | This source file is subject to version 2.02 of the PHP license, |
3088+ | that is bundled with this package in the file LICENSE, and is |
3089+ | available at through the world-wide-web at |
3090+ | http://www.php.net/license/2_02.txt. |
3091+ | If you did not receive a copy of the PHP license and are unable to |
3092+ | obtain it through the world-wide-web, please send a note to |
3093+ | license@php.net so we can mail you a copy immediately. |
3094+ +----------------------------------------------------------------------+
3095+ | Author: Stefan Esser <sesser@hardened-php.net> |
3096+ +----------------------------------------------------------------------+
3097+
3098+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3099+*/
3100+
3101+#ifdef HAVE_CONFIG_H
3102+#include "config.h"
3103+#endif
3104+
3105+#include "php.h"
3106+#include "php_ini.h"
3107+#include "ext/standard/info.h"
3108+#include "php_varfilter.h"
3109+#include "hardening_patch.h"
3110+
3111+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3112+
3113+/* True global resources - no need for thread safety here */
3114+static int le_varfilter;
3115+
3116+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3117+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3118+static zend_bool hooked = 0;
3119+
3120+/* {{{ varfilter_module_entry
3121+ */
3122+zend_module_entry varfilter_module_entry = {
3123+#if ZEND_MODULE_API_NO >= 20010901
3124+ STANDARD_MODULE_HEADER,
3125+#endif
3126+ "varfilter",
3127+ NULL,
3128+ PHP_MINIT(varfilter),
3129+ PHP_MSHUTDOWN(varfilter),
3130+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3131+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3132+ PHP_MINFO(varfilter),
3133+#if ZEND_MODULE_API_NO >= 20010901
3134+ "0.4.11", /* Replace with version number for your extension */
3135+#endif
3136+ STANDARD_MODULE_PROPERTIES
3137+};
3138+/* }}} */
3139+
3140+#ifdef COMPILE_DL_VARFILTER
3141+ZEND_GET_MODULE(varfilter)
3142+#endif
3143+
3144+/* {{{ PHP_INI
3145+ */
3146+PHP_INI_BEGIN()
3147+ /* for backward compatibility */
3148+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3149+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3150+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3151+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3152+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3153+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3154+
3155+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3156+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3157+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3158+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3159+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3160+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3161+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3162+
3163+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3164+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3165+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3166+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3167+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3168+ 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)
3169+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3170+
3171+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3172+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3173+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3174+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3175+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3176+ 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)
3177+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3178+
3179+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3180+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3181+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3182+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3183+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3184+ 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)
3185+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3186+
3187+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3188+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3189+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3190+
3191+
3192+PHP_INI_END()
3193+/* }}} */
3194+
3195+/* {{{ php_varfilter_init_globals
3196+ */
3197+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3198+{
3199+ varfilter_globals->max_request_variables = 200;
3200+ varfilter_globals->max_varname_length = 64;
3201+ varfilter_globals->max_value_length = 10000;
3202+ varfilter_globals->max_array_depth = 100;
3203+ varfilter_globals->max_totalname_length = 256;
3204+ varfilter_globals->max_array_index_length = 64;
3205+ varfilter_globals->disallow_nul = 1;
3206+
3207+ varfilter_globals->max_cookie_vars = 100;
3208+ varfilter_globals->max_cookie_name_length = 64;
3209+ varfilter_globals->max_cookie_totalname_length = 256;
3210+ varfilter_globals->max_cookie_value_length = 10000;
3211+ varfilter_globals->max_cookie_array_depth = 100;
3212+ varfilter_globals->max_cookie_array_index_length = 64;
3213+ varfilter_globals->disallow_cookie_nul = 1;
3214+
3215+ varfilter_globals->max_get_vars = 100;
3216+ varfilter_globals->max_get_name_length = 64;
3217+ varfilter_globals->max_get_totalname_length = 256;
3218+ varfilter_globals->max_get_value_length = 512;
3219+ varfilter_globals->max_get_array_depth = 50;
3220+ varfilter_globals->max_get_array_index_length = 64;
3221+ varfilter_globals->disallow_get_nul = 1;
3222+
3223+ varfilter_globals->max_post_vars = 200;
3224+ varfilter_globals->max_post_name_length = 64;
3225+ varfilter_globals->max_post_totalname_length = 256;
3226+ varfilter_globals->max_post_value_length = 65000;
3227+ varfilter_globals->max_post_array_depth = 100;
3228+ varfilter_globals->max_post_array_index_length = 64;
3229+ varfilter_globals->disallow_post_nul = 1;
3230+
3231+ varfilter_globals->max_uploads = 25;
3232+ varfilter_globals->disallow_elf_files = 1;
3233+ varfilter_globals->verification_script = NULL;
3234+
3235+ varfilter_globals->no_more_variables = 0;
3236+ varfilter_globals->no_more_get_variables = 0;
3237+ varfilter_globals->no_more_post_variables = 0;
3238+ varfilter_globals->no_more_cookie_variables = 0;
3239+ varfilter_globals->no_more_uploads = 0;
3240+
3241+ varfilter_globals->cur_request_variables = 0;
3242+ varfilter_globals->cur_get_vars = 0;
3243+ varfilter_globals->cur_post_vars = 0;
3244+ varfilter_globals->cur_cookie_vars = 0;
3245+
3246+ varfilter_globals->cur_uploads = 0;
3247+
3248+}
3249+/* }}} */
3250+
3251+
3252+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3253+{
3254+ HashTable *svars;
3255+ int retval, failure=0;
3256+
3257+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3258+
3259+ svars = Z_ARRVAL_P(track_vars_array);
3260+
3261+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3262+ if (retval == SUCCESS) failure = 1;
3263+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3264+ if (retval == SUCCESS) failure = 1;
3265+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3266+ if (retval == SUCCESS) failure = 1;
3267+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3268+ if (retval == SUCCESS) failure = 1;
3269+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3270+ if (retval == SUCCESS) failure = 1;
3271+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3272+ if (retval == SUCCESS) failure = 1;
3273+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3274+ if (retval == SUCCESS) failure = 1;
3275+ 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);
3276+ if (retval == SUCCESS) failure = 1;
3277+
3278+ if (failure) {
3279+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3280+ }
3281+}
3282+
3283+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3284+{
3285+ int retval = SAPI_HEADER_ADD, i;
3286+ char *tmp;
3287+
3288+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3289+
3290+ tmp = sapi_header->header;
3291+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3292+ if (tmp[0] == 0) {
3293+ char *fname = get_active_function_name(TSRMLS_C);
3294+
3295+ if (!fname) {
3296+ fname = "unknown";
3297+ }
3298+
3299+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3300+ sapi_header->header_len = i;
3301+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3302+ char *fname = get_active_function_name(TSRMLS_C);
3303+
3304+ if (!fname) {
3305+ fname = "unknown";
3306+ }
3307+
3308+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3309+ sapi_header->header_len = i;
3310+ tmp[0] = 0;
3311+ }
3312+ }
3313+ }
3314+
3315+ if (orig_header_handler) {
3316+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3317+ }
3318+
3319+ return retval;
3320+}
3321+
3322+/* {{{ PHP_MINIT_FUNCTION
3323+ */
3324+PHP_MINIT_FUNCTION(varfilter)
3325+{
3326+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3327+ REGISTER_INI_ENTRIES();
3328+
3329+ if (!hooked) {
3330+ void *temp;
3331+ hooked = 1;
3332+
3333+ temp = (void *)sapi_module.register_server_variables;
3334+ if (temp != varfilter_register_server_variables) {
3335+ orig_register_server_variables = temp;
3336+ }
3337+ temp = (void *)sapi_module.header_handler;
3338+ if (temp != varfilter_header_handler) {
3339+ orig_header_handler = temp;
3340+ }
3341+ }
3342+
3343+ sapi_register_input_filter(varfilter_input_filter);
3344+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3345+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3346+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3347+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3348+
3349+ sapi_module.header_handler = varfilter_header_handler;
3350+ sapi_module.register_server_variables = varfilter_register_server_variables;
3351+
3352+
3353+ return SUCCESS;
3354+}
3355+/* }}} */
3356+
3357+/* {{{ PHP_MSHUTDOWN_FUNCTION
3358+ */
3359+PHP_MSHUTDOWN_FUNCTION(varfilter)
3360+{
3361+ UNREGISTER_INI_ENTRIES();
3362+
3363+ return SUCCESS;
3364+}
3365+/* }}} */
3366+
3367+/* Remove if there's nothing to do at request start */
3368+/* {{{ PHP_RINIT_FUNCTION
3369+ */
3370+PHP_RINIT_FUNCTION(varfilter)
3371+{
3372+ VARFILTER_G(cur_request_variables) = 0;
3373+ VARFILTER_G(cur_get_vars) = 0;
3374+ VARFILTER_G(cur_post_vars) = 0;
3375+ VARFILTER_G(cur_cookie_vars) = 0;
3376+
3377+ VARFILTER_G(cur_uploads) = 0;
3378+
3379+ VARFILTER_G(no_more_variables) = 0;
3380+ VARFILTER_G(no_more_get_variables) = 0;
3381+ VARFILTER_G(no_more_post_variables) = 0;
3382+ VARFILTER_G(no_more_cookie_variables) = 0;
3383+ VARFILTER_G(no_more_uploads) = 0;
3384+
3385+ return SUCCESS;
3386+}
3387+/* }}} */
3388+
3389+/* Remove if there's nothing to do at request end */
3390+/* {{{ PHP_RSHUTDOWN_FUNCTION
3391+ */
3392+PHP_RSHUTDOWN_FUNCTION(varfilter)
3393+{
3394+ return SUCCESS;
3395+}
3396+/* }}} */
3397+
3398+/* {{{ PHP_MINFO_FUNCTION
3399+ */
3400+PHP_MINFO_FUNCTION(varfilter)
3401+{
3402+ php_info_print_table_start();
3403+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3404+ php_info_print_table_end();
3405+
3406+ DISPLAY_INI_ENTRIES();
3407+}
3408+/* }}} */
3409+
3410+/* {{{ normalize_varname
3411+ */
3412+static void normalize_varname(char *varname)
3413+{
3414+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3415+
3416+ /* overjump leading space */
3417+ while (*s == ' ') {
3418+ s++;
3419+ }
3420+
3421+ /* and remove it */
3422+ if (s != varname) {
3423+ memmove(varname, s, strlen(s)+1);
3424+ }
3425+
3426+ for (p=varname; *p && *p != '['; p++) {
3427+ switch(*p) {
3428+ case ' ':
3429+ case '.':
3430+ *p='_';
3431+ break;
3432+ }
3433+ }
3434+
3435+ /* find index */
3436+ index = strchr(varname, '[');
3437+ if (index) {
3438+ index++;
3439+ s=index;
3440+ } else {
3441+ return;
3442+ }
3443+
3444+ /* done? */
3445+ while (index) {
3446+
3447+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3448+ index++;
3449+ }
3450+ indexend = strchr(index, ']');
3451+ indexend = indexend ? indexend + 1 : index + strlen(index);
3452+
3453+ if (s != index) {
3454+ memmove(s, index, strlen(index)+1);
3455+ s += indexend-index;
3456+ } else {
3457+ s = indexend;
3458+ }
3459+
3460+ if (*s == '[') {
3461+ s++;
3462+ index = s;
3463+ } else {
3464+ index = NULL;
3465+ }
3466+ }
3467+ *s++='\0';
3468+}
3469+/* }}} */
3470+
3471+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3472+ */
3473+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3474+{
3475+ char *index, *prev_index = NULL, *var;
3476+ unsigned int var_len, total_len, depth = 0;
3477+
3478+ var = estrdup(varname);
3479+
3480+ /* Normalize the variable name */
3481+ normalize_varname(var);
3482+
3483+ /* Find length of variable name */
3484+ index = strchr(var, '[');
3485+ total_len = strlen(var);
3486+ var_len = index ? index-var : total_len;
3487+
3488+ /* Drop this variable if it exceeds the varname/total length limit */
3489+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3490+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3491+ goto return_failure;
3492+ }
3493+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3494+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3495+ goto return_failure;
3496+ }
3497+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3498+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3499+
3500+ goto return_failure;
3501+ }
3502+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3503+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3504+ goto return_failure;
3505+ }
3506+
3507+ /* Find out array depth */
3508+ while (index) {
3509+ unsigned int index_length;
3510+
3511+ depth++;
3512+ index = strchr(index+1, '[');
3513+
3514+ if (prev_index) {
3515+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3516+
3517+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3518+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3519+ goto return_failure;
3520+ }
3521+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3522+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3523+ goto return_failure;
3524+ }
3525+ prev_index = index;
3526+ }
3527+
3528+ }
3529+
3530+ /* Drop this variable if it exceeds the array depth limit */
3531+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3532+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3533+ goto return_failure;
3534+ }
3535+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3536+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3537+ goto return_failure;
3538+ }
3539+
3540+
3541+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3542+ /* This is to protect several silly scripts that do globalizing themself */
3543+
3544+ switch (var_len) {
3545+ case 18:
3546+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3547+ break;
3548+ case 17:
3549+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3550+ break;
3551+ case 16:
3552+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3553+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3554+ break;
3555+ case 15:
3556+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3557+ break;
3558+ case 14:
3559+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3560+ break;
3561+ case 13:
3562+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3563+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3564+ break;
3565+ case 8:
3566+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3567+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3568+ break;
3569+ case 7:
3570+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3571+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3572+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3573+ break;
3574+ case 6:
3575+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3576+ break;
3577+ case 5:
3578+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3579+ break;
3580+ case 4:
3581+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3582+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3583+ break;
3584+ }
3585+
3586+ efree(var);
3587+ return SUCCESS;
3588+protected_varname2:
3589+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3590+return_failure:
3591+ efree(var);
3592+ return FAILURE;
3593+}
3594+/* }}} */
3595+
3596+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3597+ */
3598+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3599+{
3600+ /* Drop if no more variables flag is set */
3601+ if (VARFILTER_G(no_more_uploads)) {
3602+ return FAILURE;
3603+ }
3604+ /* Drop this fileupload if the limit is reached */
3605+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3606+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3607+ VARFILTER_G(no_more_uploads) = 1;
3608+ return FAILURE;
3609+ }
3610+
3611+ return SUCCESS;
3612+}
3613+/* }}} */
3614+
3615+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3616+ */
3617+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3618+{
3619+
3620+ if (VARFILTER_G(disallow_elf_files)) {
3621+
3622+ if (offset == 0 && buffer_len > 10) {
3623+
3624+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3625+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3626+ return FAILURE;
3627+ }
3628+ }
3629+
3630+ }
3631+
3632+ return SUCCESS;
3633+}
3634+/* }}} */
3635+
3636+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3637+ */
3638+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3639+{
3640+ int retval = SUCCESS;
3641+
3642+ if (VARFILTER_G(verification_script)) {
3643+ char cmd[8192];
3644+ FILE *in;
3645+ int first=1;
3646+
3647+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3648+
3649+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3650+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3651+ return FAILURE;
3652+ }
3653+
3654+ retval = FAILURE;
3655+
3656+ /* read and forget the result */
3657+ while (1) {
3658+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3659+ if (readbytes<=0) {
3660+ break;
3661+ }
3662+ if (first) {
3663+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3664+ first = 0;
3665+ }
3666+ }
3667+ pclose(in);
3668+ }
3669+
3670+ if (retval != SUCCESS) {
3671+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3672+ return FAILURE;
3673+ }
3674+
3675+ VARFILTER_G(cur_uploads)++;
3676+ return SUCCESS;
3677+}
3678+/* }}} */
3679+
3680+/* {{{ SAPI_INPUT_FILTER_FUNC
3681+ */
3682+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3683+{
3684+ char *index, *prev_index = NULL;
3685+ unsigned int var_len, total_len, depth = 0;
3686+
3687+ /* Drop this variable if the limit was reached */
3688+ switch (arg) {
3689+ case PARSE_GET:
3690+ if (VARFILTER_G(no_more_get_variables)) {
3691+ return 0;
3692+ }
3693+ break;
3694+ case PARSE_POST:
3695+ if (VARFILTER_G(no_more_post_variables)) {
3696+ return 0;
3697+ }
3698+ break;
3699+ case PARSE_COOKIE:
3700+ if (VARFILTER_G(no_more_cookie_variables)) {
3701+ return 0;
3702+ }
3703+ break;
3704+ default: /* we do not want to protect parse_str() and friends */
3705+ if (new_val_len) {
3706+ *new_val_len = val_len;
3707+ }
3708+ return 1;
3709+ }
3710+ if (VARFILTER_G(no_more_variables)) {
3711+ return 0;
3712+ }
3713+
3714+ /* Drop this variable if the limit is now reached */
3715+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3716+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3717+ VARFILTER_G(no_more_variables) = 1;
3718+ return 0;
3719+ }
3720+ switch (arg) {
3721+ case PARSE_GET:
3722+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3723+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3724+ VARFILTER_G(no_more_get_variables) = 1;
3725+ return 0;
3726+ }
3727+ break;
3728+ case PARSE_COOKIE:
3729+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3730+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3731+ VARFILTER_G(no_more_cookie_variables) = 1;
3732+ return 0;
3733+ }
3734+ break;
3735+ case PARSE_POST:
3736+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3737+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3738+ VARFILTER_G(no_more_post_variables) = 1;
3739+ return 0;
3740+ }
3741+ break;
3742+ }
3743+
3744+
3745+ /* Drop this variable if it exceeds the value length limit */
3746+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3747+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3748+ return 0;
3749+ }
3750+ switch (arg) {
3751+ case PARSE_GET:
3752+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3753+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3754+ return 0;
3755+ }
3756+ break;
3757+ case PARSE_COOKIE:
3758+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3759+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3760+ return 0;
3761+ }
3762+ break;
3763+ case PARSE_POST:
3764+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3765+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3766+ return 0;
3767+ }
3768+ break;
3769+ }
3770+
3771+ /* Normalize the variable name */
3772+ normalize_varname(var);
3773+
3774+ /* Find length of variable name */
3775+ index = strchr(var, '[');
3776+ total_len = strlen(var);
3777+ var_len = index ? index-var : total_len;
3778+
3779+ /* Drop this variable if it exceeds the varname/total length limit */
3780+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3781+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3782+ return 0;
3783+ }
3784+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3785+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3786+ return 0;
3787+ }
3788+ switch (arg) {
3789+ case PARSE_GET:
3790+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3791+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3792+ return 0;
3793+ }
3794+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3795+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3796+ return 0;
3797+ }
3798+ break;
3799+ case PARSE_COOKIE:
3800+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3801+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3802+ return 0;
3803+ }
3804+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3805+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3806+ return 0;
3807+ }
3808+ break;
3809+ case PARSE_POST:
3810+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3811+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3812+ return 0;
3813+ }
3814+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3815+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3816+ return 0;
3817+ }
3818+ break;
3819+ }
3820+
3821+ /* Find out array depth */
3822+ while (index) {
3823+ unsigned int index_length;
3824+
3825+ depth++;
3826+ index = strchr(index+1, '[');
3827+
3828+ if (prev_index) {
3829+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3830+
3831+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3832+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3833+ return 0;
3834+ }
3835+ switch (arg) {
3836+ case PARSE_GET:
3837+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3838+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3839+ return 0;
3840+ }
3841+ break;
3842+ case PARSE_COOKIE:
3843+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3844+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3845+ return 0;
3846+ }
3847+ break;
3848+ case PARSE_POST:
3849+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3850+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3851+ return 0;
3852+ }
3853+ break;
3854+ }
3855+ prev_index = index;
3856+ }
3857+
3858+ }
3859+
3860+ /* Drop this variable if it exceeds the array depth limit */
3861+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3862+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3863+ return 0;
3864+ }
3865+ switch (arg) {
3866+ case PARSE_GET:
3867+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3868+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3869+ return 0;
3870+ }
3871+ break;
3872+ case PARSE_COOKIE:
3873+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3874+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3875+ return 0;
3876+ }
3877+ break;
3878+ case PARSE_POST:
3879+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3880+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3881+ return 0;
3882+ }
3883+ break;
3884+ }
3885+
3886+ /* Check if variable value is truncated by a \0 */
3887+
3888+ if (val && *val && val_len != strlen(*val)) {
3889+
3890+ if (VARFILTER_G(disallow_nul)) {
3891+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3892+ return 0;
3893+ }
3894+ switch (arg) {
3895+ case PARSE_GET:
3896+ if (VARFILTER_G(disallow_get_nul)) {
3897+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3898+ return 0;
3899+ }
3900+ break;
3901+ case PARSE_COOKIE:
3902+ if (VARFILTER_G(disallow_cookie_nul)) {
3903+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3904+ return 0;
3905+ }
3906+ break;
3907+ case PARSE_POST:
3908+ if (VARFILTER_G(disallow_post_nul)) {
3909+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3910+ return 0;
3911+ }
3912+ break;
3913+ }
3914+ }
3915+
3916+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3917+ /* This is to protect several silly scripts that do globalizing themself */
3918+
3919+ switch (var_len) {
3920+ case 18:
3921+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3922+ break;
3923+ case 17:
3924+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3925+ break;
3926+ case 16:
3927+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3928+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3929+ break;
3930+ case 15:
3931+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3932+ break;
3933+ case 14:
3934+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3935+ break;
3936+ case 13:
3937+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3938+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3939+ break;
3940+ case 8:
3941+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3942+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3943+ break;
3944+ case 7:
3945+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3946+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3947+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3948+ break;
3949+ case 6:
3950+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3951+ break;
3952+ case 5:
3953+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3954+ break;
3955+ case 4:
3956+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3957+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3958+ break;
3959+ }
3960+
3961+ /* Okay let PHP register this variable */
3962+ VARFILTER_G(cur_request_variables)++;
3963+ switch (arg) {
3964+ case PARSE_GET:
3965+ VARFILTER_G(cur_get_vars)++;
3966+ break;
3967+ case PARSE_COOKIE:
3968+ VARFILTER_G(cur_cookie_vars)++;
3969+ break;
3970+ case PARSE_POST:
3971+ VARFILTER_G(cur_post_vars)++;
3972+ break;
3973+ }
3974+
3975+ if (new_val_len) {
3976+ *new_val_len = val_len;
3977+ }
3978+
3979+ return 1;
3980+protected_varname:
3981+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3982+ return 0;
3983+}
3984+/* }}} */
3985+
3986+/*
3987+ * Local variables:
3988+ * tab-width: 4
3989+ * c-basic-offset: 4
3990+ * End:
3991+ * vim600: noet sw=4 ts=4 fdm=marker
3992+ * vim<600: noet sw=4 ts=4
3993+ */
3994+
3995+
3996diff -Nura php-5.1.4/main/fopen_wrappers.c hardening-patch-5.1.4-0.4.11/main/fopen_wrappers.c
3997--- php-5.1.4/main/fopen_wrappers.c 2006-03-17 11:42:31.000000000 +0100
3998+++ hardening-patch-5.1.4-0.4.11/main/fopen_wrappers.c 2006-05-13 15:39:35.000000000 +0200
3999@@ -114,14 +114,20 @@
4000 }
4001 }
4002
4003+ resolved_name_len = strlen(resolved_name);
4004 if (path[strlen(path)-1] == PHP_DIR_SEPARATOR) {
4005- resolved_name_len = strlen(resolved_name);
4006 if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) {
4007 resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR;
4008 resolved_name[++resolved_name_len] = '\0';
4009 }
4010 }
4011
4012+ if (resolved_name_len == resolved_basedir_len - 1) {
4013+ if (resolved_basedir[resolved_basedir_len - 1] == PHP_DIR_SEPARATOR) {
4014+ resolved_basedir_len--;
4015+ }
4016+ }
4017+
4018 /* Check the path */
4019 #if defined(PHP_WIN32) || defined(NETWARE)
4020 if (strncasecmp(resolved_basedir, resolved_name, resolved_basedir_len) == 0) {
4021@@ -154,6 +160,21 @@
4022 char *pathbuf;
4023 char *ptr;
4024 char *end;
4025+ char path_copy[MAXPATHLEN];
4026+ int path_len;
4027+
4028+ /* Special case path ends with a trailing slash */
4029+ path_len = strlen(path);
4030+ if (path_len >= MAXPATHLEN) {
4031+ errno = EPERM; /* we deny permission to open it */
4032+ return -1;
4033+ }
4034+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
4035+ memcpy(path_copy, path, path_len+1);
4036+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
4037+ path_copy[path_len] = '\0';
4038+ path = (const char *)&path_copy;
4039+ }
4040
4041 pathbuf = estrdup(PG(open_basedir));
4042
4043diff -Nura php-5.1.4/main/hardened_globals.h hardening-patch-5.1.4-0.4.11/main/hardened_globals.h
4044--- php-5.1.4/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
4045+++ hardening-patch-5.1.4-0.4.11/main/hardened_globals.h 2006-05-13 15:39:35.000000000 +0200
4046@@ -0,0 +1,62 @@
4047+/*
4048+ +----------------------------------------------------------------------+
4049+ | Hardening-Patch for PHP |
4050+ +----------------------------------------------------------------------+
4051+ | Copyright (c) 2004-2005 Stefan Esser |
4052+ +----------------------------------------------------------------------+
4053+ | This source file is subject to version 2.02 of the PHP license, |
4054+ | that is bundled with this package in the file LICENSE, and is |
4055+ | available at through the world-wide-web at |
4056+ | http://www.php.net/license/2_02.txt. |
4057+ | If you did not receive a copy of the PHP license and are unable to |
4058+ | obtain it through the world-wide-web, please send a note to |
4059+ | license@php.net so we can mail you a copy immediately. |
4060+ +----------------------------------------------------------------------+
4061+ | Author: Stefan Esser <sesser@hardened-php.net> |
4062+ +----------------------------------------------------------------------+
4063+ */
4064+
4065+#ifndef HARDENED_GLOBALS_H
4066+#define HARDENED_GLOBALS_H
4067+
4068+typedef struct _hardened_globals hardened_globals_struct;
4069+
4070+#ifdef ZTS
4071+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4072+extern int hardened_globals_id;
4073+#else
4074+# define HG(v) (hardened_globals.v)
4075+extern struct _hardened_globals hardened_globals;
4076+#endif
4077+
4078+
4079+struct _hardened_globals {
4080+#if HARDENING_PATCH_MM_PROTECT
4081+ unsigned int canary_1;
4082+ unsigned int canary_2;
4083+#endif
4084+#if HARDENING_PATCH_LL_PROTECT
4085+ unsigned int canary_3;
4086+ unsigned int canary_4;
4087+ unsigned int ll_canary_inited;
4088+#endif
4089+ zend_bool hphp_sql_bailout_on_error;
4090+ zend_bool hphp_multiheader;
4091+ HashTable *eval_whitelist;
4092+ HashTable *eval_blacklist;
4093+ HashTable *func_whitelist;
4094+ HashTable *func_blacklist;
4095+ HashTable *include_whitelist;
4096+ HashTable *include_blacklist;
4097+ unsigned int dummy;
4098+};
4099+
4100+
4101+#endif /* HARDENED_GLOBALS_H */
4102+
4103+/*
4104+ * Local variables:
4105+ * tab-width: 4
4106+ * c-basic-offset: 4
4107+ * End:
4108+ */
4109diff -Nura php-5.1.4/main/hardening_patch.c hardening-patch-5.1.4-0.4.11/main/hardening_patch.c
4110--- php-5.1.4/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4111+++ hardening-patch-5.1.4-0.4.11/main/hardening_patch.c 2006-05-13 15:39:35.000000000 +0200
4112@@ -0,0 +1,430 @@
4113+/*
4114+ +----------------------------------------------------------------------+
4115+ | Hardening Patch for PHP |
4116+ +----------------------------------------------------------------------+
4117+ | Copyright (c) 2004-2005 Stefan Esser |
4118+ +----------------------------------------------------------------------+
4119+ | This source file is subject to version 2.02 of the PHP license, |
4120+ | that is bundled with this package in the file LICENSE, and is |
4121+ | available at through the world-wide-web at |
4122+ | http://www.php.net/license/2_02.txt. |
4123+ | If you did not receive a copy of the PHP license and are unable to |
4124+ | obtain it through the world-wide-web, please send a note to |
4125+ | license@php.net so we can mail you a copy immediately. |
4126+ +----------------------------------------------------------------------+
4127+ | Author: Stefan Esser <sesser@hardened-php.net> |
4128+ +----------------------------------------------------------------------+
4129+ */
4130+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4131+
4132+#include "php.h"
4133+
4134+#include <stdio.h>
4135+#include <stdlib.h>
4136+
4137+#if HAVE_UNISTD_H
4138+#include <unistd.h>
4139+#endif
4140+#include "SAPI.h"
4141+#include "php_globals.h"
4142+
4143+#if HARDENING_PATCH
4144+
4145+#ifdef HAVE_SYS_SOCKET_H
4146+#include <sys/socket.h>
4147+#endif
4148+
4149+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4150+#undef AF_UNIX
4151+#endif
4152+
4153+#if defined(AF_UNIX)
4154+#include <sys/un.h>
4155+#endif
4156+
4157+#define SYSLOG_PATH "/dev/log"
4158+
4159+#include "snprintf.h"
4160+
4161+#include "hardening_patch.h"
4162+
4163+#ifdef ZTS
4164+#include "hardened_globals.h"
4165+int hardened_globals_id;
4166+#else
4167+struct _hardened_globals hardened_globals;
4168+#endif
4169+
4170+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4171+{
4172+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4173+}
4174+
4175+
4176+PHPAPI void hardened_startup()
4177+{
4178+#ifdef ZTS
4179+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4180+#else
4181+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4182+#endif
4183+}
4184+
4185+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4186+{
4187+ HG(canary_1) = php_canary();
4188+ HG(canary_2) = php_canary();
4189+}
4190+
4191+char *loglevel2string(int loglevel)
4192+{
4193+ switch (loglevel) {
4194+ case S_FILES:
4195+ return "FILES";
4196+ case S_INCLUDE:
4197+ return "INCLUDE";
4198+ case S_MEMORY:
4199+ return "MEMORY";
4200+ case S_MISC:
4201+ return "MISC";
4202+ case S_SQL:
4203+ return "SQL";
4204+ case S_EXECUTOR:
4205+ return "EXECUTOR";
4206+ case S_VARS:
4207+ return "VARS";
4208+ default:
4209+ return "UNKNOWN";
4210+ }
4211+}
4212+
4213+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4214+{
4215+#if defined(AF_UNIX)
4216+ int s, r, i=0;
4217+ struct sockaddr_un saun;
4218+ char buf[4096+64];
4219+ char error[4096+100];
4220+ char *ip_address;
4221+ char *fname;
4222+ int lineno;
4223+ va_list ap;
4224+ TSRMLS_FETCH();
4225+
4226+ if (EG(hphp_log_use_x_forwarded_for)) {
4227+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4228+ if (ip_address == NULL) {
4229+ ip_address = "X-FORWARDED-FOR not set";
4230+ }
4231+ } else {
4232+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4233+ if (ip_address == NULL) {
4234+ ip_address = "REMOTE_ADDR not set";
4235+ }
4236+ }
4237+
4238+
4239+ va_start(ap, fmt);
4240+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4241+ va_end(ap);
4242+ while (error[i]) {
4243+ if (error[i] < 32) error[i] = '.';
4244+ i++;
4245+ }
4246+
4247+ if (zend_is_executing(TSRMLS_C)) {
4248+ lineno = zend_get_executed_lineno(TSRMLS_C);
4249+ fname = zend_get_executed_filename(TSRMLS_C);
4250+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4251+ } else {
4252+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4253+ if (fname==NULL) {
4254+ fname = "unknown";
4255+ }
4256+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4257+ }
4258+
4259+ /* Syslog-Logging disabled? */
4260+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4261+ goto log_sapi;
4262+ }
4263+
4264+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4265+
4266+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4267+ if (s == -1) {
4268+ goto log_sapi;
4269+ }
4270+
4271+ memset(&saun, 0, sizeof(saun));
4272+ saun.sun_family = AF_UNIX;
4273+ strcpy(saun.sun_path, SYSLOG_PATH);
4274+ /*saun.sun_len = sizeof(saun);*/
4275+
4276+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4277+ if (r) {
4278+ close(s);
4279+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4280+ if (s == -1) {
4281+ goto log_sapi;
4282+ }
4283+
4284+ memset(&saun, 0, sizeof(saun));
4285+ saun.sun_family = AF_UNIX;
4286+ strcpy(saun.sun_path, SYSLOG_PATH);
4287+ /*saun.sun_len = sizeof(saun);*/
4288+
4289+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4290+ if (r) {
4291+ close(s);
4292+ goto log_sapi;
4293+ }
4294+ }
4295+ send(s, error, strlen(error), 0);
4296+
4297+ close(s);
4298+
4299+log_sapi:
4300+ /* SAPI Logging activated? */
4301+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4302+ sapi_module.log_message(buf);
4303+ }
4304+
4305+log_script:
4306+ /* script logging activaed? */
4307+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4308+ char cmd[8192], *cmdpos, *bufpos;
4309+ FILE *in;
4310+ int space;
4311+
4312+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4313+ space = sizeof(cmd) - strlen(cmd);
4314+ cmdpos = cmd + strlen(cmd);
4315+ bufpos = buf;
4316+ if (space <= 1) return;
4317+ while (space > 2 && *bufpos) {
4318+ if (*bufpos == '\'') {
4319+ if (space<=5) break;
4320+ *cmdpos++ = '\'';
4321+ *cmdpos++ = '\\';
4322+ *cmdpos++ = '\'';
4323+ *cmdpos++ = '\'';
4324+ bufpos++;
4325+ space-=4;
4326+ } else {
4327+ *cmdpos++ = *bufpos++;
4328+ space--;
4329+ }
4330+ }
4331+ *cmdpos++ = '\'';
4332+ *cmdpos = 0;
4333+
4334+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4335+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4336+ return;
4337+ }
4338+ /* read and forget the result */
4339+ while (1) {
4340+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4341+ if (readbytes<=0) {
4342+ break;
4343+ }
4344+ }
4345+ pclose(in);
4346+ }
4347+
4348+#endif
4349+}
4350+#endif
4351+
4352+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4353+
4354+/* will be replaced later with more compatible method */
4355+PHPAPI unsigned int php_canary()
4356+{
4357+ time_t t;
4358+ unsigned int canary;
4359+ int fd;
4360+
4361+ fd = open("/dev/urandom", 0);
4362+ if (fd != -1) {
4363+ int r = read(fd, &canary, sizeof(canary));
4364+ close(fd);
4365+ if (r == sizeof(canary)) {
4366+ return (canary);
4367+ }
4368+ }
4369+ /* not good but we never want to do this */
4370+ time(&t);
4371+ canary = *(unsigned int *)&t + getpid() << 16;
4372+ return (canary);
4373+}
4374+#endif
4375+
4376+#if HARDENING_PATCH_INC_PROTECT
4377+
4378+PHPAPI int php_is_valid_include(zval *z)
4379+{
4380+ char *filename;
4381+ int len, i;
4382+ TSRMLS_FETCH();
4383+
4384+ /* must be of type string */
4385+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4386+ return (0);
4387+ }
4388+
4389+ /* short cut */
4390+ filename = z->value.str.val;
4391+ len = z->value.str.len;
4392+
4393+ /* 1. must be shorter than MAXPATHLEN */
4394+ if (len > MAXPATHLEN) {
4395+ char *fname = estrndup(filename, len);
4396+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4397+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4398+ efree(fname);
4399+ return (0);
4400+ }
4401+
4402+ /* 2. must not be cutted */
4403+ if (len != strlen(filename)) {
4404+ char *fname = estrndup(filename, len);
4405+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4406+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4407+ efree(fname);
4408+ return (0);
4409+ }
4410+
4411+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4412+ if (strstr(filename, "://")) {
4413+ char *fname = estrndup(filename, len);
4414+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4415+
4416+ /* no black or whitelist then disallow all */
4417+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4418+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4419+ efree(fname);
4420+ return (0);
4421+ }
4422+
4423+ /* whitelist is stronger than blacklist */
4424+ if (HG(include_whitelist)) {
4425+ char *s, *t, *h, *index;
4426+ uint indexlen;
4427+ ulong numindex;
4428+
4429+ s = filename;
4430+
4431+ do {
4432+ zend_bool isOk = 0;
4433+ int tlen;
4434+
4435+ t = h = strstr(s, "://");
4436+ if (h == NULL) break;
4437+
4438+
4439+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4440+ t--;
4441+ }
4442+
4443+ tlen = strlen(t);
4444+
4445+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4446+ do {
4447+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4448+
4449+ if (r==HASH_KEY_NON_EXISTANT) {
4450+ break;
4451+ }
4452+ if (r==HASH_KEY_IS_STRING) {
4453+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4454+ if (strncmp(t, index, indexlen-1)==0) {
4455+ isOk = 1;
4456+ break;
4457+ }
4458+ }
4459+ }
4460+
4461+ zend_hash_move_forward(HG(include_whitelist));
4462+ } while (1);
4463+
4464+ /* not found in whitelist */
4465+ if (!isOk) {
4466+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4467+ efree(fname);
4468+ return 0;
4469+ }
4470+
4471+ s = h + 3;
4472+ } while (1);
4473+ } else {
4474+ /* okay then handle the blacklist */
4475+ char *s, *t, *h, *index;
4476+ uint indexlen;
4477+ ulong numindex;
4478+
4479+ s = filename;
4480+
4481+ do {
4482+ int tlen;
4483+
4484+ t = h = strstr(s, "://");
4485+ if (h == NULL) break;
4486+
4487+
4488+ while (t > s) {
4489+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4490+ }
4491+
4492+ tlen = strlen(t);
4493+
4494+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4495+ do {
4496+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4497+
4498+ if (r==HASH_KEY_NON_EXISTANT) {
4499+ break;
4500+ }
4501+ if (r==HASH_KEY_IS_STRING) {
4502+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4503+ if (strncmp(t, index, indexlen-1)==0) {
4504+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4505+ efree(fname);
4506+ return 0;
4507+ }
4508+ }
4509+ }
4510+
4511+ zend_hash_move_forward(HG(include_blacklist));
4512+ } while (1);
4513+
4514+ s = h + 3;
4515+ } while (1);
4516+ }
4517+
4518+ efree(fname);
4519+ }
4520+
4521+ /* 4. must not be an uploaded file */
4522+ if (SG(rfc1867_uploaded_files)) {
4523+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4524+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4525+ return (0);
4526+ }
4527+ }
4528+
4529+ /* passed all tests */
4530+ return (1);
4531+}
4532+
4533+#endif
4534+
4535+/*
4536+ * Local variables:
4537+ * tab-width: 4
4538+ * c-basic-offset: 4
4539+ * End:
4540+ * vim600: sw=4 ts=4 fdm=marker
4541+ * vim<600: sw=4 ts=4
4542+ */
4543diff -Nura php-5.1.4/main/hardening_patch.h hardening-patch-5.1.4-0.4.11/main/hardening_patch.h
4544--- php-5.1.4/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4545+++ hardening-patch-5.1.4-0.4.11/main/hardening_patch.h 2006-05-13 15:39:47.000000000 +0200
4546@@ -0,0 +1,46 @@
4547+/*
4548+ +----------------------------------------------------------------------+
4549+ | Hardening Patch for PHP |
4550+ +----------------------------------------------------------------------+
4551+ | Copyright (c) 2004-2005 Stefan Esser |
4552+ +----------------------------------------------------------------------+
4553+ | This source file is subject to version 2.02 of the PHP license, |
4554+ | that is bundled with this package in the file LICENSE, and is |
4555+ | available at through the world-wide-web at |
4556+ | http://www.php.net/license/2_02.txt. |
4557+ | If you did not receive a copy of the PHP license and are unable to |
4558+ | obtain it through the world-wide-web, please send a note to |
4559+ | license@php.net so we can mail you a copy immediately. |
4560+ +----------------------------------------------------------------------+
4561+ | Author: Stefan Esser <sesser@hardened-php.net> |
4562+ +----------------------------------------------------------------------+
4563+ */
4564+
4565+#ifndef HARDENING_PATCH_H
4566+#define HARDENING_PATCH_H
4567+
4568+#include "zend.h"
4569+
4570+#if HARDENING_PATCH
4571+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4572+PHPAPI void hardened_startup();
4573+#define HARDENING_PATCH_VERSION "0.4.11"
4574+
4575+#endif
4576+
4577+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4578+PHPAPI unsigned int php_canary();
4579+#endif
4580+
4581+#if HARDENING_PATCH_INC_PROTECT
4582+PHPAPI int php_is_valid_include(zval *z);
4583+#endif
4584+
4585+#endif /* HARDENING_PATCH_H */
4586+
4587+/*
4588+ * Local variables:
4589+ * tab-width: 4
4590+ * c-basic-offset: 4
4591+ * End:
4592+ */
4593diff -Nura php-5.1.4/main/hardening_patch.m4 hardening-patch-5.1.4-0.4.11/main/hardening_patch.m4
4594--- php-5.1.4/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4595+++ hardening-patch-5.1.4-0.4.11/main/hardening_patch.m4 2006-05-13 15:39:35.000000000 +0200
4596@@ -0,0 +1,95 @@
4597+dnl
4598+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4599+dnl
4600+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4601+dnl
4602+
4603+AC_ARG_ENABLE(hardening-patch-mm-protect,
4604+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4605+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4606+],[
4607+ DO_HARDENING_PATCH_MM_PROTECT=yes
4608+])
4609+
4610+AC_ARG_ENABLE(hardening-patch-ll-protect,
4611+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4612+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4613+],[
4614+ DO_HARDENING_PATCH_LL_PROTECT=yes
4615+])
4616+
4617+AC_ARG_ENABLE(hardening-patch-inc-protect,
4618+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4619+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4620+],[
4621+ DO_HARDENING_PATCH_INC_PROTECT=yes
4622+])
4623+
4624+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4625+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4626+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4627+],[
4628+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4629+])
4630+
4631+AC_ARG_ENABLE(hardening-patch-hash-protect,
4632+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4633+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4634+],[
4635+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4636+])
4637+
4638+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4639+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4640+
4641+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4642+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4643+
4644+AC_MSG_CHECKING(whether to protect include/require statements)
4645+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4646+
4647+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4648+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4649+
4650+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4651+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4652+
4653+
4654+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4655+
4656+
4657+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4658+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4659+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4660+else
4661+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4662+fi
4663+
4664+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4665+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4666+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4667+else
4668+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4669+fi
4670+
4671+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4672+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4673+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4674+else
4675+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4676+fi
4677+
4678+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4679+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4680+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4681+else
4682+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4683+fi
4684+
4685+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4686+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4687+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4688+else
4689+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4690+fi
4691+
4692diff -Nura php-5.1.4/main/main.c hardening-patch-5.1.4-0.4.11/main/main.c
4693--- php-5.1.4/main/main.c 2006-04-12 14:49:39.000000000 +0200
4694+++ hardening-patch-5.1.4-0.4.11/main/main.c 2006-05-13 16:14:43.000000000 +0200
4695@@ -85,6 +85,10 @@
4696
4697 #include "SAPI.h"
4698 #include "rfc1867.h"
4699+#if HARDENING_PATCH
4700+#include "hardened_globals.h"
4701+#endif
4702+
4703 /* }}} */
4704
4705 #ifndef ZTS
4706@@ -109,10 +113,33 @@
4707 */
4708 static PHP_INI_MH(OnChangeMemoryLimit)
4709 {
4710+#if HARDENING_PATCH
4711+ long orig_memory_limit;
4712+
4713+ if (entry->modified) {
4714+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4715+ } else {
4716+ orig_memory_limit = 1<<30;
4717+ }
4718+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4719+ orig_memory_limit = 1<<30;
4720+ }
4721+#endif
4722 if (new_value) {
4723 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4724+#if HARDENING_PATCH
4725+ if (PG(memory_limit) > orig_memory_limit) {
4726+ PG(memory_limit) = orig_memory_limit;
4727+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4728+ return FAILURE;
4729+ }
4730+#endif
4731 } else {
4732+#if HARDENING_PATCH
4733+ PG(memory_limit) = orig_memory_limit;
4734+#else
4735 PG(memory_limit) = 1<<30; /* effectively, no limit */
4736+#endif
4737 }
4738 return zend_set_memory_limit(PG(memory_limit));
4739 }
4740@@ -1095,6 +1122,13 @@
4741 sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
4742 }
4743
4744+ /* Disable realpath cache if safe_mode or open_basedir are set */
4745+ if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
4746+ CWDG(realpath_cache_disable) = 1;
4747+ } else {
4748+ CWDG(realpath_cache_disable) = 0;
4749+ }
4750+
4751 if (PG(output_handler) && PG(output_handler)[0]) {
4752 php_start_ob_buffer_named(PG(output_handler), 0, 1 TSRMLS_CC);
4753 } else if (PG(output_buffering)) {
4754@@ -1222,6 +1256,9 @@
4755
4756 zend_try {
4757 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4758+#if HARDENING_PATCH
4759+ hardened_clear_mm_canaries(TSRMLS_C);
4760+#endif
4761 } zend_end_try();
4762
4763 zend_try {
4764@@ -1393,6 +1430,10 @@
4765 tsrm_ls = ts_resource(0);
4766 #endif
4767
4768+#if HARDENING_PATCH
4769+ hardened_startup();
4770+#endif
4771+
4772 module_shutdown = 0;
4773 module_startup = 1;
4774 sapi_initialize_empty_request(TSRMLS_C);
4775@@ -1406,6 +1447,12 @@
4776
4777 php_output_startup();
4778
4779+#if HARDENING_PATCH_INC_PROTECT
4780+ zuf.is_valid_include = php_is_valid_include;
4781+#endif
4782+#if HARDENING_PATCH
4783+ zuf.security_log_function = php_security_log;
4784+#endif
4785 zuf.error_function = php_error_cb;
4786 zuf.printf_function = php_printf;
4787 zuf.write_function = php_body_write_wrapper;
4788@@ -1476,7 +1523,9 @@
4789
4790 /* Disable realpath cache if safe_mode or open_basedir are set */
4791 if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
4792- CWDG(realpath_cache_size_limit) = 0;
4793+ CWDG(realpath_cache_disable) = 1;
4794+ } else {
4795+ CWDG(realpath_cache_disable) = 0;
4796 }
4797
4798 /* initialize stream wrappers registry
4799@@ -1517,6 +1566,10 @@
4800 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
4801 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);
4802 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4803+#if HARDENING_PATCH
4804+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4805+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4806+#endif
4807 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4808 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4809 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4810diff -Nura php-5.1.4/main/php_config.h.in hardening-patch-5.1.4-0.4.11/main/php_config.h.in
4811--- php-5.1.4/main/php_config.h.in 2006-05-04 01:31:35.000000000 +0200
4812+++ hardening-patch-5.1.4-0.4.11/main/php_config.h.in 2006-05-13 15:39:35.000000000 +0200
4813@@ -788,6 +788,39 @@
4814 /* Enabling BIND8 compatibility for Panther */
4815 #undef BIND_8_COMPAT
4816
4817+/* Hardening-Patch for PHP */
4818+#undef HARDENING_PATCH
4819+
4820+/* Memory Manager Protection */
4821+#undef HARDENING_PATCH_MM_PROTECT
4822+
4823+/* Memory Manager Protection */
4824+#undef HARDENING_PATCH_MM_PROTECT
4825+
4826+/* Linked List Protection */
4827+#undef HARDENING_PATCH_LL_PROTECT
4828+
4829+/* Linked List Protection */
4830+#undef HARDENING_PATCH_LL_PROTECT
4831+
4832+/* Include/Require Protection */
4833+#undef HARDENING_PATCH_INC_PROTECT
4834+
4835+/* Include/Require Protection */
4836+#undef HARDENING_PATCH_INC_PROTECT
4837+
4838+/* Fmt String Protection */
4839+#undef HARDENING_PATCH_FMT_PROTECT
4840+
4841+/* Fmt String Protection */
4842+#undef HARDENING_PATCH_FMT_PROTECT
4843+
4844+/* HashTable DTOR Protection */
4845+#undef HARDENING_PATCH_HASH_PROTECT
4846+
4847+/* HashTable DTOR Protection */
4848+#undef HARDENING_PATCH_HASH_PROTECT
4849+
4850 /* Whether you have AOLserver */
4851 #undef HAVE_AOLSERVER
4852
4853@@ -1131,6 +1164,12 @@
4854 /* Define if you have the getaddrinfo function */
4855 #undef HAVE_GETADDRINFO
4856
4857+/* Whether realpath is broken */
4858+#undef PHP_BROKEN_REALPATH
4859+
4860+/* Whether realpath is broken */
4861+#undef PHP_BROKEN_REALPATH
4862+
4863 /* Whether system headers declare timezone */
4864 #undef HAVE_DECLARED_TIMEZONE
4865
4866diff -Nura php-5.1.4/main/php.h hardening-patch-5.1.4-0.4.11/main/php.h
4867--- php-5.1.4/main/php.h 2006-03-07 23:37:53.000000000 +0100
4868+++ hardening-patch-5.1.4-0.4.11/main/php.h 2006-05-13 15:39:35.000000000 +0200
4869@@ -35,11 +35,19 @@
4870 #include "zend_qsort.h"
4871 #include "php_compat.h"
4872
4873+
4874 #include "zend_API.h"
4875
4876 #undef sprintf
4877 #define sprintf php_sprintf
4878
4879+#if HARDENING_PATCH
4880+#if HAVE_REALPATH
4881+#undef realpath
4882+#define realpath php_realpath
4883+#endif
4884+#endif
4885+
4886 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4887 #undef PHP_DEBUG
4888 #define PHP_DEBUG ZEND_DEBUG
4889@@ -338,6 +346,7 @@
4890 #define PHP_FUNCTION ZEND_FUNCTION
4891 #define PHP_METHOD ZEND_METHOD
4892
4893+#define PHP_STATIC_FE ZEND_STATIC_FE
4894 #define PHP_NAMED_FE ZEND_NAMED_FE
4895 #define PHP_FE ZEND_FE
4896 #define PHP_DEP_FE ZEND_DEP_FE
4897@@ -447,6 +456,10 @@
4898 #endif
4899 #endif /* !XtOffsetOf */
4900
4901+#if HARDENING_PATCH
4902+#include "hardening_patch.h"
4903+#endif
4904+
4905 #endif
4906
4907 /*
4908diff -Nura php-5.1.4/main/php_variables.c hardening-patch-5.1.4-0.4.11/main/php_variables.c
4909--- php-5.1.4/main/php_variables.c 2006-05-03 13:24:29.000000000 +0200
4910+++ hardening-patch-5.1.4-0.4.11/main/php_variables.c 2006-05-13 15:39:35.000000000 +0200
4911@@ -73,6 +73,10 @@
4912 symtable1 = Z_ARRVAL_P(track_vars_array);
4913 } else if (PG(register_globals)) {
4914 symtable1 = EG(active_symbol_table);
4915+ /* GLOBALS hijack attempt, reject parameter */
4916+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) {
4917+ symtable1 = NULL;
4918+ }
4919 }
4920 if (!symtable1) {
4921 /* Nothing to do */
4922@@ -513,7 +517,7 @@
4923 */
4924 static inline void php_register_server_variables(TSRMLS_D)
4925 {
4926- zval *array_ptr = NULL;
4927+ zval *array_ptr = NULL, *vptr;
4928 /* turn off magic_quotes while importing server variables */
4929 int magic_quotes_gpc = PG(magic_quotes_gpc);
4930
4931diff -Nura php-5.1.4/main/rfc1867.c hardening-patch-5.1.4-0.4.11/main/rfc1867.c
4932--- php-5.1.4/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100
4933+++ hardening-patch-5.1.4-0.4.11/main/rfc1867.c 2006-05-13 15:39:35.000000000 +0200
4934@@ -132,6 +132,7 @@
4935 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4936 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4937 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4938+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
4939
4940 void php_rfc1867_register_constants(TSRMLS_D)
4941 {
4942@@ -142,6 +143,7 @@
4943 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4944 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4945 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4946+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4947 }
4948
4949 static void normalize_protected_variable(char *varname TSRMLS_DC)
4950@@ -854,6 +856,7 @@
4951 char buff[FILLUNIT];
4952 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4953 int blen=0, wlen=0;
4954+ unsigned long offset;
4955
4956 zend_llist_clean(&header);
4957
4958@@ -970,7 +973,11 @@
4959 tmp++;
4960 }
4961 }
4962-
4963+
4964+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4965+ skip_upload = 1;
4966+ }
4967+
4968 total_bytes = cancel_upload = 0;
4969
4970 if (!skip_upload) {
4971@@ -994,6 +1001,11 @@
4972 cancel_upload = UPLOAD_ERROR_D;
4973 }
4974
4975+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4976+ cancel_upload = UPLOAD_ERROR_X;
4977+ }
4978+
4979+ offset = 0;
4980 end = 0;
4981 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4982 {
4983@@ -1008,6 +1020,10 @@
4984 #endif
4985 cancel_upload = UPLOAD_ERROR_B;
4986 } else if (blen > 0) {
4987+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4988+ cancel_upload = UPLOAD_ERROR_X;
4989+ }
4990+
4991 wlen = write(fd, buff, blen);
4992
4993 if (wlen < blen) {
4994@@ -1036,6 +1052,10 @@
4995 }
4996 #endif
4997
4998+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4999+ cancel_upload = UPLOAD_ERROR_X;
5000+ }
5001+
5002 if (cancel_upload) {
5003 if (temp_filename) {
5004 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
5005diff -Nura php-5.1.4/main/SAPI.c hardening-patch-5.1.4-0.4.11/main/SAPI.c
5006--- php-5.1.4/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100
5007+++ hardening-patch-5.1.4-0.4.11/main/SAPI.c 2006-05-13 15:39:35.000000000 +0200
5008@@ -870,6 +870,36 @@
5009 post_entry->content_type_len+1);
5010 }
5011
5012+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))
5013+{
5014+ sapi_module.input_filter = input_filter;
5015+ return SUCCESS;
5016+}
5017+
5018+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5019+{
5020+ sapi_module.upload_varname_filter = upload_varname_filter;
5021+ return SUCCESS;
5022+}
5023+
5024+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5025+{
5026+ sapi_module.pre_upload_filter = pre_upload_filter;
5027+ return SUCCESS;
5028+}
5029+
5030+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))
5031+{
5032+ sapi_module.upload_content_filter = upload_content_filter;
5033+ return SUCCESS;
5034+}
5035+
5036+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5037+{
5038+ sapi_module.post_upload_filter = post_upload_filter;
5039+ return SUCCESS;
5040+}
5041+
5042
5043 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
5044 {
5045@@ -884,11 +914,6 @@
5046 return SUCCESS;
5047 }
5048
5049-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))
5050-{
5051- sapi_module.input_filter = input_filter;
5052- return SUCCESS;
5053-}
5054
5055 SAPI_API int sapi_flush(TSRMLS_D)
5056 {
5057diff -Nura php-5.1.4/main/SAPI.h hardening-patch-5.1.4-0.4.11/main/SAPI.h
5058--- php-5.1.4/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100
5059+++ hardening-patch-5.1.4-0.4.11/main/SAPI.h 2006-05-13 15:39:35.000000000 +0200
5060@@ -190,6 +190,10 @@
5061 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5062 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));
5063
5064+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5065+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));
5066+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5067+
5068 SAPI_API int sapi_flush(TSRMLS_D);
5069 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5070 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
5071@@ -254,6 +258,11 @@
5072 int (*get_target_gid)(gid_t * TSRMLS_DC);
5073
5074 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5075+
5076+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5077+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5078+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5079+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5080
5081 void (*ini_defaults)(HashTable *configuration_hash);
5082 int phpinfo_as_text;
5083@@ -279,7 +288,11 @@
5084
5085 #define SAPI_DEFAULT_MIMETYPE "text/html"
5086 #define SAPI_DEFAULT_CHARSET ""
5087+#if HARDENING_PATCH
5088+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5089+#else
5090 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5091+#endif
5092
5093 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5094 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5095@@ -287,6 +300,11 @@
5096 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5097 #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)
5098
5099+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5100+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5101+#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)
5102+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5103+
5104 BEGIN_EXTERN_C()
5105 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5106 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5107diff -Nura php-5.1.4/main/snprintf.c hardening-patch-5.1.4-0.4.11/main/snprintf.c
5108--- php-5.1.4/main/snprintf.c 2006-01-24 21:59:46.000000000 +0100
5109+++ hardening-patch-5.1.4-0.4.11/main/snprintf.c 2006-05-13 15:39:35.000000000 +0200
5110@@ -1014,7 +1014,11 @@
5111
5112
5113 case 'n':
5114+#if HARDENING_PATCH_FMT_PROTECT
5115+ php_security_log(S_MISC, "'n' specifier within format string");
5116+#else
5117 *(va_arg(ap, int *)) = cc;
5118+#endif
5119 goto skip_output;
5120
5121 /*
5122diff -Nura php-5.1.4/main/spprintf.c hardening-patch-5.1.4-0.4.11/main/spprintf.c
5123--- php-5.1.4/main/spprintf.c 2006-01-24 21:59:46.000000000 +0100
5124+++ hardening-patch-5.1.4-0.4.11/main/spprintf.c 2006-05-13 15:39:35.000000000 +0200
5125@@ -630,7 +630,11 @@
5126
5127
5128 case 'n':
5129+#if HARDENING_PATCH_FMT_PROTECT
5130+ php_security_log(S_MISC, "'n' specifier within format string");
5131+#else
5132 *(va_arg(ap, int *)) = xbuf->len;
5133+#endif
5134 goto skip_output;
5135
5136 /*
5137diff -Nura php-5.1.4/pear/Makefile.frag hardening-patch-5.1.4-0.4.11/pear/Makefile.frag
5138--- php-5.1.4/pear/Makefile.frag 2006-02-08 02:12:12.000000000 +0100
5139+++ hardening-patch-5.1.4-0.4.11/pear/Makefile.frag 2006-05-13 15:39:35.000000000 +0200
5140@@ -3,7 +3,7 @@
5141 peardir=$(PEAR_INSTALLDIR)
5142
5143 # Skip all php.ini files altogether
5144-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -dmemory_limit=-1 -ddetect_unicode=0
5145+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
5146
5147 install-pear-installer: $(SAPI_CLI_PATH)
5148 @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)"
5149diff -Nura php-5.1.4/php.ini-dist hardening-patch-5.1.4-0.4.11/php.ini-dist
5150--- php-5.1.4/php.ini-dist 2006-02-09 00:43:48.000000000 +0100
5151+++ hardening-patch-5.1.4-0.4.11/php.ini-dist 2006-05-13 15:39:35.000000000 +0200
5152@@ -1197,6 +1197,209 @@
5153 ; instead of original one.
5154 soap.wsdl_cache_ttl=86400
5155
5156+[hardening-patch]
5157+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5158+; Hardening-Patch's logging ;
5159+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5160+
5161+;
5162+; hphp.log.syslog - Configures level for alerts reported through syslog
5163+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5164+; hphp.log.script - Configures level for alerts reported through external script
5165+;
5166+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5167+; Or each number up to get desired Hardening-Patch's reporting level
5168+;
5169+; S_ALL - All alerts
5170+; S_MEMORY - All canary violations and the safe unlink protection use this class
5171+; S_VARS - All variable filters trigger this class
5172+; S_FILES - All violation of uploaded files filter use this class
5173+; S_INCLUDE - The protection against malicious include filenames use this class
5174+; S_SQL - Failed SQL queries in MySQL are logged with this class
5175+; S_EXECUTOR - The execution depth protection uses this logging class
5176+; S_MISC - All other log messages (f.e. format string protection) use this class
5177+;
5178+; Example:
5179+;
5180+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5181+; memory alerts through syslog and SQL+Include alerts fo the script
5182+;
5183+;hphp.log.syslog = S_MEMORY
5184+;hphp.log.sapi = S_ALL & ~S_MEMORY
5185+;hphp.log.script = S_INCLUDE | S_SQL
5186+;
5187+; Syslog logging:
5188+;
5189+; - Facility configuration: one of the following facilities
5190+;
5191+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5192+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5193+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5194+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5195+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5196+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5197+; LOG_PERROR
5198+;
5199+; - Priority configuration: one of the followinf priorities
5200+;
5201+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5202+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5203+;
5204+hphp.log.syslog.priority = LOG_ALERT
5205+hphp.log.syslog.facility = LOG_USER
5206+;
5207+; Script logging:
5208+;
5209+;hphp.log.script.name = /home/hphp/log_script
5210+;
5211+; Alert configuration:
5212+;
5213+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5214+;
5215+;hphp.log.use-x-forwarded-for = On
5216+;
5217+
5218+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5219+; Hardening-Patch's Executor options ;
5220+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5221+
5222+; Execution depth limit
5223+;hphp.executor.max_depth = 8000
5224+
5225+; White-/blacklist for function calls during normal execution
5226+;hphp.executor.func.whitelist = ord,chr
5227+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5228+
5229+; White-/blacklist for function calls during eval() execution
5230+;hphp.executor.eval.whitelist = ord,chr
5231+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5232+
5233+; White-/blacklist for URLs allowes in include filenames
5234+;
5235+; - When both options are not set all URLs are forbidden
5236+;
5237+; - When both options are set whitelist is taken and blacklist ignored
5238+;
5239+; - An entry in the lists is either a URL sheme like: http, https
5240+; or the beginning of an URL like: php://input
5241+;
5242+;hphp.executor.include.whitelist = cookietest
5243+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5244+
5245+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5246+; Hardening-Patch's REQUEST variable filters ;
5247+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5248+
5249+; Limits the number of REQUEST variables
5250+hphp.request.max_vars = 200
5251+
5252+; Limits the length of variable names (without indices)
5253+hphp.request.max_varname_length = 64
5254+
5255+; Limits the length of complete variable names (with indices)
5256+hphp.request.max_totalname_length = 256
5257+
5258+; Limits the length of array indices
5259+hphp.request.max_array_index_length = 64
5260+
5261+; Limits the depth of arrays
5262+hphp.request.max_array_depth = 100
5263+
5264+; Limits the length of variable values
5265+hphp.request.max_value_length = 65000
5266+
5267+; Disallow ASCII-NUL characters in input
5268+hphp.request.disallow_nul = 1
5269+
5270+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5271+; Hardening-Patch's COOKIE variable filters ;
5272+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5273+
5274+; Limits the number of COOKIE variables
5275+hphp.cookie.max_vars = 100
5276+
5277+; Limits the length of variable names (without indices)
5278+hphp.cookie.max_name_length = 64
5279+
5280+; Limits the length of complete variable names (with indices)
5281+hphp.cookie.max_totalname_length = 256
5282+
5283+; Limits the length of array indices
5284+hphp.cookie.max_array_index_length = 64
5285+
5286+; Limits the depth of arrays
5287+hphp.cookie.max_array_depth = 100
5288+
5289+; Limits the length of variable values
5290+hphp.cookie.max_value_length = 10000
5291+
5292+; Disallow ASCII-NUL characters in input
5293+hphp.cookie.disallow_nul = 1
5294+
5295+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5296+; Hardening-Patch's GET variable filters ;
5297+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5298+
5299+; Limits the number of COOKIE variables
5300+hphp.get.max_vars = 100
5301+
5302+; Limits the length of variable names (without indices)
5303+hphp.get.max_name_length = 64
5304+
5305+; Limits the length of complete variable names (with indices)
5306+hphp.get.max_totalname_length = 256
5307+
5308+; Limits the length of array indices
5309+hphp.get.max_array_index_length = 64
5310+
5311+; Limits the depth of arrays
5312+hphp.get.max_array_depth = 50
5313+
5314+; Limits the length of variable values
5315+hphp.get.max_value_length = 512
5316+
5317+; Disallow ASCII-NUL characters in input
5318+hphp.get.disallow_nul = 1
5319+
5320+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5321+; Hardening-Patch's POST variable filters ;
5322+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5323+
5324+; Limits the number of POST variables
5325+hphp.post.max_vars = 200
5326+
5327+; Limits the length of variable names (without indices)
5328+hphp.post.max_name_length = 64
5329+
5330+; Limits the length of complete variable names (with indices)
5331+hphp.post.max_totalname_length = 256
5332+
5333+; Limits the length of array indices
5334+hphp.post.max_array_index_length = 64
5335+
5336+; Limits the depth of arrays
5337+hphp.post.max_array_depth = 100
5338+
5339+; Limits the length of variable values
5340+hphp.post.max_value_length = 65000
5341+
5342+; Disallow ASCII-NUL characters in input
5343+hphp.post.disallow_nul = 1
5344+
5345+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5346+; Hardening-Patch's fileupload variable filters ;
5347+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5348+
5349+; Limits the number of uploadable files
5350+hphp.upload.max_uploads = 25
5351+
5352+; Filter out the upload of ELF executables
5353+hphp.upload.disallow_elf_files = On
5354+
5355+; External filterscript for upload verification
5356+;hphp.upload.verification_script = /home/hphp/verify_script
5357+
5358+
5359 ; Local Variables:
5360 ; tab-width: 4
5361 ; End:
5362diff -Nura php-5.1.4/php.ini-recommended hardening-patch-5.1.4-0.4.11/php.ini-recommended
5363--- php-5.1.4/php.ini-recommended 2006-02-09 00:43:48.000000000 +0100
5364+++ hardening-patch-5.1.4-0.4.11/php.ini-recommended 2006-05-13 15:39:35.000000000 +0200
5365@@ -1255,6 +1255,209 @@
5366 ; instead of original one.
5367 soap.wsdl_cache_ttl=86400
5368
5369+[hardening-patch]
5370+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5371+; Hardening-Patch's logging ;
5372+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5373+
5374+;
5375+; hphp.log.syslog - Configures level for alerts reported through syslog
5376+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5377+; hphp.log.script - Configures level for alerts reported through external script
5378+;
5379+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5380+; Or each number up to get desired Hardening-Patch's reporting level
5381+;
5382+; S_ALL - All alerts
5383+; S_MEMORY - All canary violations and the safe unlink protection use this class
5384+; S_VARS - All variable filters trigger this class
5385+; S_FILES - All violation of uploaded files filter use this class
5386+; S_INCLUDE - The protection against malicious include filenames use this class
5387+; S_SQL - Failed SQL queries in MySQL are logged with this class
5388+; S_EXECUTOR - The execution depth protection uses this logging class
5389+; S_MISC - All other log messages (f.e. format string protection) use this class
5390+;
5391+; Example:
5392+;
5393+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5394+; memory alerts through syslog and SQL+Include alerts fo the script
5395+;
5396+;hphp.log.syslog = S_MEMORY
5397+;hphp.log.sapi = S_ALL & ~S_MEMORY
5398+;hphp.log.script = S_INCLUDE | S_SQL
5399+;
5400+; Syslog logging:
5401+;
5402+; - Facility configuration: one of the following facilities
5403+;
5404+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5405+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5406+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5407+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5408+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5409+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5410+; LOG_PERROR
5411+;
5412+; - Priority configuration: one of the followinf priorities
5413+;
5414+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5415+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5416+;
5417+hphp.log.syslog.priority = LOG_ALERT
5418+hphp.log.syslog.facility = LOG_USER
5419+;
5420+; Script logging:
5421+;
5422+;hphp.log.script.name = /home/hphp/log_script
5423+;
5424+; Alert configuration:
5425+;
5426+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5427+;
5428+;hphp.log.use-x-forwarded-for = On
5429+;
5430+
5431+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5432+; Hardening-Patch's Executor options ;
5433+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5434+
5435+; Execution depth limit
5436+;hphp.executor.max_depth = 8000
5437+
5438+; White-/blacklist for function calls during normal execution
5439+;hphp.executor.func.whitelist = ord,chr
5440+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5441+
5442+; White-/blacklist for function calls during eval() execution
5443+;hphp.executor.eval.whitelist = ord,chr
5444+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5445+
5446+; White-/blacklist for URLs allowes in include filenames
5447+;
5448+; - When both options are not set all URLs are forbidden
5449+;
5450+; - When both options are set whitelist is taken and blacklist ignored
5451+;
5452+; - An entry in the lists is either a URL sheme like: http, https
5453+; or the beginning of an URL like: php://input
5454+;
5455+;hphp.executor.include.whitelist = cookietest
5456+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5457+
5458+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5459+; Hardening-Patch's REQUEST variable filters ;
5460+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5461+
5462+; Limits the number of REQUEST variables
5463+hphp.request.max_vars = 200
5464+
5465+; Limits the length of variable names (without indices)
5466+hphp.request.max_varname_length = 64
5467+
5468+; Limits the length of complete variable names (with indices)
5469+hphp.request.max_totalname_length = 256
5470+
5471+; Limits the length of array indices
5472+hphp.request.max_array_index_length = 64
5473+
5474+; Limits the depth of arrays
5475+hphp.request.max_array_depth = 100
5476+
5477+; Limits the length of variable values
5478+hphp.request.max_value_length = 65000
5479+
5480+; Disallow ASCII-NUL characters in input
5481+hphp.request.disallow_nul = 1
5482+
5483+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5484+; Hardening-Patch's COOKIE variable filters ;
5485+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5486+
5487+; Limits the number of COOKIE variables
5488+hphp.cookie.max_vars = 100
5489+
5490+; Limits the length of variable names (without indices)
5491+hphp.cookie.max_name_length = 64
5492+
5493+; Limits the length of complete variable names (with indices)
5494+hphp.cookie.max_totalname_length = 256
5495+
5496+; Limits the length of array indices
5497+hphp.cookie.max_array_index_length = 64
5498+
5499+; Limits the depth of arrays
5500+hphp.cookie.max_array_depth = 100
5501+
5502+; Limits the length of variable values
5503+hphp.cookie.max_value_length = 10000
5504+
5505+; Disallow ASCII-NUL characters in input
5506+hphp.cookie.disallow_nul = 1
5507+
5508+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5509+; Hardening-Patch's GET variable filters ;
5510+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5511+
5512+; Limits the number of COOKIE variables
5513+hphp.get.max_vars = 100
5514+
5515+; Limits the length of variable names (without indices)
5516+hphp.get.max_name_length = 64
5517+
5518+; Limits the length of complete variable names (with indices)
5519+hphp.get.max_totalname_length = 256
5520+
5521+; Limits the length of array indices
5522+hphp.get.max_array_index_length = 64
5523+
5524+; Limits the depth of arrays
5525+hphp.get.max_array_depth = 50
5526+
5527+; Limits the length of variable values
5528+hphp.get.max_value_length = 512
5529+
5530+; Disallow ASCII-NUL characters in input
5531+hphp.get.disallow_nul = 1
5532+
5533+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5534+; Hardening-Patch's POST variable filters ;
5535+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5536+
5537+; Limits the number of POST variables
5538+hphp.post.max_vars = 200
5539+
5540+; Limits the length of variable names (without indices)
5541+hphp.post.max_name_length = 64
5542+
5543+; Limits the length of complete variable names (with indices)
5544+hphp.post.max_totalname_length = 256
5545+
5546+; Limits the length of array indices
5547+hphp.post.max_array_index_length = 64
5548+
5549+; Limits the depth of arrays
5550+hphp.post.max_array_depth = 100
5551+
5552+; Limits the length of variable values
5553+hphp.post.max_value_length = 65000
5554+
5555+; Disallow ASCII-NUL characters in input
5556+hphp.post.disallow_nul = 1
5557+
5558+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5559+; Hardening-Patch's fileupload variable filters ;
5560+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5561+
5562+; Limits the number of uploadable files
5563+hphp.upload.max_uploads = 25
5564+
5565+; Filter out the upload of ELF executables
5566+hphp.upload.disallow_elf_files = On
5567+
5568+; External filterscript for upload verification
5569+;hphp.upload.verification_script = /home/hphp/verify_script
5570+
5571+
5572 ; Local Variables:
5573 ; tab-width: 4
5574 ; End:
5575diff -Nura php-5.1.4/run-tests.php hardening-patch-5.1.4-0.4.11/run-tests.php
5576--- php-5.1.4/run-tests.php 2006-05-03 23:37:16.000000000 +0200
5577+++ hardening-patch-5.1.4-0.4.11/run-tests.php 2006-05-13 15:39:35.000000000 +0200
5578@@ -161,6 +161,10 @@
5579 'error_reporting=4095',
5580 'display_errors=1',
5581 'log_errors=0',
5582+ 'hphp.executor.include.whitelist=cookietest',
5583+ 'hphp.log.syslog=0',
5584+ 'hphp.log.sapi=0',
5585+ 'hphp.log.script=0',
5586 'html_errors=0',
5587 'track_errors=1',
5588 'report_memleaks=1',
5589diff -Nura php-5.1.4/sapi/apache/mod_php5.c hardening-patch-5.1.4-0.4.11/sapi/apache/mod_php5.c
5590--- php-5.1.4/sapi/apache/mod_php5.c 2006-04-02 19:58:17.000000000 +0200
5591+++ hardening-patch-5.1.4-0.4.11/sapi/apache/mod_php5.c 2006-05-13 15:39:35.000000000 +0200
5592@@ -482,7 +482,7 @@
5593 sapi_apache_get_fd,
5594 sapi_apache_force_http_10,
5595 sapi_apache_get_target_uid,
5596- sapi_apache_get_target_gid
5597+ sapi_apache_get_target_gid,
5598 };
5599 /* }}} */
5600
5601@@ -936,7 +936,11 @@
5602 {
5603 TSRMLS_FETCH();
5604 if (PG(expose_php)) {
5605+#if HARDENING_PATCH
5606+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5607+#else
5608 ap_add_version_component("PHP/" PHP_VERSION);
5609+#endif
5610 }
5611 }
5612 #endif
5613diff -Nura php-5.1.4/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.4-0.4.11/sapi/apache2filter/sapi_apache2.c
5614--- php-5.1.4/sapi/apache2filter/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
5615+++ hardening-patch-5.1.4-0.4.11/sapi/apache2filter/sapi_apache2.c 2006-05-13 15:39:35.000000000 +0200
5616@@ -573,7 +573,11 @@
5617 {
5618 TSRMLS_FETCH();
5619 if (PG(expose_php)) {
5620+#if HARDENING_PATCH
5621+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5622+#else
5623 ap_add_version_component(p, "PHP/" PHP_VERSION);
5624+#endif
5625 }
5626 }
5627
5628diff -Nura php-5.1.4/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.4-0.4.11/sapi/apache2handler/sapi_apache2.c
5629--- php-5.1.4/sapi/apache2handler/sapi_apache2.c 2006-03-19 15:54:53.000000000 +0100
5630+++ hardening-patch-5.1.4-0.4.11/sapi/apache2handler/sapi_apache2.c 2006-05-13 15:39:35.000000000 +0200
5631@@ -341,7 +341,11 @@
5632 {
5633 TSRMLS_FETCH();
5634 if (PG(expose_php)) {
5635+#if HARDENING_PATCH
5636+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5637+#else
5638 ap_add_version_component(p, "PHP/" PHP_VERSION);
5639+#endif
5640 }
5641 }
5642
5643diff -Nura php-5.1.4/sapi/cgi/cgi_main.c hardening-patch-5.1.4-0.4.11/sapi/cgi/cgi_main.c
5644--- php-5.1.4/sapi/cgi/cgi_main.c 2006-05-03 21:40:58.000000000 +0200
5645+++ hardening-patch-5.1.4-0.4.11/sapi/cgi/cgi_main.c 2006-05-13 15:39:35.000000000 +0200
5646@@ -1444,10 +1444,18 @@
5647 SG(headers_sent) = 1;
5648 SG(request_info).no_headers = 1;
5649 }
5650+#if HARDENING_PATCH
5651 #if ZEND_DEBUG
5652- 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());
5653+ 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());
5654 #else
5655- 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());
5656+ 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());
5657+#endif
5658+#else
5659+#if ZEND_DEBUG
5660+ 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());
5661+#else
5662+ 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());
5663+#endif
5664 #endif
5665 php_end_ob_buffers(1 TSRMLS_CC);
5666 exit(0);
5667diff -Nura php-5.1.4/sapi/cli/php_cli.c hardening-patch-5.1.4-0.4.11/sapi/cli/php_cli.c
5668--- php-5.1.4/sapi/cli/php_cli.c 2006-02-21 22:15:13.000000000 +0100
5669+++ hardening-patch-5.1.4-0.4.11/sapi/cli/php_cli.c 2006-05-13 15:39:35.000000000 +0200
5670@@ -753,8 +753,14 @@
5671 goto err;
5672 }
5673
5674+#if HARDENING_PATCH
5675+ php_printf("PHP %s with Hardening-Patch %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
5676+ PHP_VERSION, HARDENING_PATCH_VERSION,
5677+#else
5678 php_printf("PHP %s (%s) (built: %s %s) %s\nCopyright (c) 1997-2006 The PHP Group\n%s",
5679- PHP_VERSION, sapi_module.name, __DATE__, __TIME__,
5680+ PHP_VERSION,
5681+#endif
5682+ sapi_module.name, __DATE__, __TIME__,
5683 #if ZEND_DEBUG && defined(HAVE_GCOV)
5684 "(DEBUG GCOV)",
5685 #elif ZEND_DEBUG
5686diff -Nura php-5.1.4/TSRM/TSRM.h hardening-patch-5.1.4-0.4.11/TSRM/TSRM.h
5687--- php-5.1.4/TSRM/TSRM.h 2006-03-14 16:16:07.000000000 +0100
5688+++ hardening-patch-5.1.4-0.4.11/TSRM/TSRM.h 2006-05-13 15:39:35.000000000 +0200
5689@@ -33,6 +33,13 @@
5690 # define TSRM_API
5691 #endif
5692
5693+#if HARDENING_PATCH
5694+# if HAVE_REALPATH
5695+# undef realpath
5696+# define realpath php_realpath
5697+# endif
5698+#endif
5699+
5700 /* Only compile multi-threading functions if we're in ZTS mode */
5701 #ifdef ZTS
5702
5703@@ -88,6 +95,7 @@
5704
5705 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5706
5707+
5708 #ifdef __cplusplus
5709 extern "C" {
5710 #endif
5711diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.4-0.4.11/TSRM/tsrm_virtual_cwd.c
5712--- php-5.1.4/TSRM/tsrm_virtual_cwd.c 2006-03-05 19:57:54.000000000 +0100
5713+++ hardening-patch-5.1.4-0.4.11/TSRM/tsrm_virtual_cwd.c 2006-05-13 17:58:25.000000000 +0200
5714@@ -163,6 +163,7 @@
5715 static void cwd_globals_ctor(virtual_cwd_globals *cwd_globals TSRMLS_DC)
5716 {
5717 CWD_STATE_COPY(&cwd_globals->cwd, &main_cwd_state);
5718+ cwd_globals->realpath_cache_disable = 0;
5719 cwd_globals->realpath_cache_size = 0;
5720 cwd_globals->realpath_cache_size_limit = REALPATH_CACHE_SIZE;
5721 cwd_globals->realpath_cache_ttl = REALPATH_CACHE_TTL;
5722@@ -201,6 +202,176 @@
5723 return p;
5724 }
5725
5726+#if HARDENING_PATCH
5727+CWD_API char *php_realpath(const char *path, char *resolved)
5728+{
5729+ struct stat sb;
5730+ char *p, *q, *s;
5731+ size_t left_len, resolved_len;
5732+ unsigned symlinks;
5733+ int serrno, slen;
5734+ int is_dir = 1;
5735+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5736+
5737+ serrno = errno;
5738+ symlinks = 0;
5739+ if (path[0] == '/') {
5740+ resolved[0] = '/';
5741+ resolved[1] = '\0';
5742+ if (path[1] == '\0')
5743+ return (resolved);
5744+ resolved_len = 1;
5745+ left_len = strlcpy(left, path + 1, sizeof(left));
5746+ } else {
5747+ if (getcwd(resolved, PATH_MAX) == NULL) {
5748+ strlcpy(resolved, ".", PATH_MAX);
5749+ return (NULL);
5750+ }
5751+ resolved_len = strlen(resolved);
5752+ left_len = strlcpy(left, path, sizeof(left));
5753+ }
5754+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5755+ errno = ENAMETOOLONG;
5756+ return (NULL);
5757+ }
5758+
5759+ /*
5760+ * Iterate over path components in `left'.
5761+ */
5762+ while (left_len != 0) {
5763+ /*
5764+ * Extract the next path component and adjust `left'
5765+ * and its length.
5766+ */
5767+ p = strchr(left, '/');
5768+ s = p ? p : left + left_len;
5769+ if (s - left >= sizeof(next_token)) {
5770+ errno = ENAMETOOLONG;
5771+ return (NULL);
5772+ }
5773+ memcpy(next_token, left, s - left);
5774+ next_token[s - left] = '\0';
5775+ left_len -= s - left;
5776+ if (p != NULL)
5777+ memmove(left, s + 1, left_len + 1);
5778+ if (resolved[resolved_len - 1] != '/') {
5779+ if (resolved_len + 1 >= PATH_MAX) {
5780+ errno = ENAMETOOLONG;
5781+ return (NULL);
5782+ }
5783+ resolved[resolved_len++] = '/';
5784+ resolved[resolved_len] = '\0';
5785+ }
5786+ if (next_token[0] == '\0')
5787+ continue;
5788+ else if (strcmp(next_token, ".") == 0)
5789+ continue;
5790+ else if (strcmp(next_token, "..") == 0) {
5791+ /*
5792+ * Strip the last path component except when we have
5793+ * single "/"
5794+ */
5795+ if (!is_dir) {
5796+ errno = ENOENT;
5797+ return (NULL);
5798+ }
5799+ if (resolved_len > 1) {
5800+ resolved[resolved_len - 1] = '\0';
5801+ q = strrchr(resolved, '/');
5802+ *q = '\0';
5803+ resolved_len = q - resolved;
5804+ }
5805+ continue;
5806+ }
5807+
5808+ /*
5809+ * Append the next path component and lstat() it. If
5810+ * lstat() fails we still can return successfully if
5811+ * there are no more path components left.
5812+ */
5813+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
5814+ if (resolved_len >= PATH_MAX) {
5815+ errno = ENAMETOOLONG;
5816+ return (NULL);
5817+ }
5818+ if (lstat(resolved, &sb) != 0) {
5819+ if (errno == ENOENT) {
5820+ if (p == NULL) {
5821+ errno = serrno;
5822+ return (resolved);
5823+ } else if (strstr(left, "/.") == NULL && strstr(left, "./") == NULL) {
5824+ resolved_len = strlcat(resolved, "/", PATH_MAX);
5825+ resolved_len = strlcat(resolved, left, PATH_MAX);
5826+ if (resolved_len >= PATH_MAX) {
5827+ errno = ENAMETOOLONG;
5828+ return (NULL);
5829+ }
5830+ errno = serrno;
5831+ return (resolved);
5832+ }
5833+ }
5834+ return (NULL);
5835+ }
5836+ if (S_ISLNK(sb.st_mode)) {
5837+ if (symlinks++ > MAXSYMLINKS) {
5838+ errno = ELOOP;
5839+ return (NULL);
5840+ }
5841+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
5842+ if (slen < 0)
5843+ return (NULL);
5844+ symlink[slen] = '\0';
5845+ if (symlink[0] == '/') {
5846+ resolved[1] = 0;
5847+ resolved_len = 1;
5848+ } else if (resolved_len > 1) {
5849+ /* Strip the last path component. */
5850+ resolved[resolved_len - 1] = '\0';
5851+ q = strrchr(resolved, '/');
5852+ *q = '\0';
5853+ resolved_len = q - resolved;
5854+ }
5855+
5856+ /*
5857+ * If there are any path components left, then
5858+ * append them to symlink. The result is placed
5859+ * in `left'.
5860+ */
5861+ if (p != NULL) {
5862+ if (symlink[slen - 1] != '/') {
5863+ if (slen + 1 >= sizeof(symlink)) {
5864+ errno = ENAMETOOLONG;
5865+ return (NULL);
5866+ }
5867+ symlink[slen] = '/';
5868+ symlink[slen + 1] = 0;
5869+ }
5870+ left_len = strlcat(symlink, left, sizeof(left));
5871+ if (left_len >= sizeof(left)) {
5872+ errno = ENAMETOOLONG;
5873+ return (NULL);
5874+ }
5875+ }
5876+ left_len = strlcpy(left, symlink, sizeof(left));
5877+ } else {
5878+ if (S_ISDIR(sb.st_mode)) {
5879+ is_dir = 1;
5880+ } else {
5881+ is_dir = 0;
5882+ }
5883+ }
5884+ }
5885+
5886+ /*
5887+ * Remove trailing slash except when the resolved pathname
5888+ * is a single "/".
5889+ */
5890+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
5891+ resolved[resolved_len - 1] = '\0';
5892+ return (resolved);
5893+}
5894+#endif
5895+
5896 CWD_API void virtual_cwd_startup(void)
5897 {
5898 char cwd[MAXPATHLEN];
5899@@ -381,22 +552,33 @@
5900 #endif
5901 char orig_path[MAXPATHLEN];
5902 int orig_path_len = 0;
5903+ int use_realpath_cache = 1;
5904 realpath_cache_bucket *bucket;
5905 time_t t = 0;
5906 TSRMLS_FETCH();
5907
5908 if (path_length == 0)
5909 return (0);
5910- if (path_length >= MAXPATHLEN)
5911+ if (path_length >= MAXPATHLEN) {
5912+ state->cwd[0] = 0;
5913+ state->cwd_length = 0;
5914 return (1);
5915+ }
5916+
5917+ /* Disable realpath cache if safe_mode or open_basedir are set */
5918+ if (CWDG(realpath_cache_disable)) {
5919+ use_realpath_cache = 0;
5920+ }
5921
5922- if (use_realpath && CWDG(realpath_cache_size_limit)) {
5923+ if (use_realpath && use_realpath_cache) {
5924 if (IS_ABSOLUTE_PATH(path, path_length) || (state->cwd_length < 1)) {
5925 memcpy(orig_path, path, path_length+1);
5926 orig_path_len = path_length;
5927 } else {
5928 orig_path_len = path_length + state->cwd_length + 1;
5929 if (orig_path_len >= MAXPATHLEN) {
5930+ state->cwd[0] = 0;
5931+ state->cwd_length = 0;
5932 return 1;
5933 }
5934 memcpy(orig_path, state->cwd, state->cwd_length);
5935@@ -414,6 +596,8 @@
5936 if (verify_path && verify_path(state)) {
5937 CWD_STATE_FREE(state);
5938 *state = old_state;
5939+ state->cwd[0] = 0;
5940+ state->cwd_length = 0;
5941 return 1;
5942 } else {
5943 CWD_STATE_FREE(&old_state);
5944@@ -431,8 +615,9 @@
5945 path = resolved_path;
5946 path_length = strlen(path);
5947 } else {
5948- /* disable for now
5949- return 1; */
5950+ state->cwd[0] = 0;
5951+ state->cwd_length = 0;
5952+ return 1;
5953 }
5954 }
5955 } else { /* Concat current directory with relative path and then run realpath() on it */
5956@@ -441,6 +626,8 @@
5957
5958 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
5959 if (!tmp) {
5960+ state->cwd[0] = 0;
5961+ state->cwd_length = 0;
5962 return 1;
5963 }
5964 memcpy(ptr, state->cwd, state->cwd_length);
5965@@ -451,6 +638,8 @@
5966 *ptr = '\0';
5967 if (strlen(tmp) >= MAXPATHLEN) {
5968 free(tmp);
5969+ state->cwd[0] = 0;
5970+ state->cwd_length = 0;
5971 return 1;
5972 }
5973 if (use_realpath) {
5974@@ -458,9 +647,10 @@
5975 path = resolved_path;
5976 path_length = strlen(path);
5977 } else {
5978- /* disable for now
5979 free(tmp);
5980- return 1; */
5981+ state->cwd[0] = 0;
5982+ state->cwd_length = 0;
5983+ return 1;
5984 }
5985 }
5986 free(tmp);
5987@@ -599,7 +789,7 @@
5988 #endif
5989 free(free_path);
5990
5991- if (use_realpath && CWDG(realpath_cache_size_limit)) {
5992+ if (use_realpath && use_realpath_cache) {
5993 realpath_cache_add(orig_path, orig_path_len, state->cwd, state->cwd_length, t TSRMLS_CC);
5994 }
5995
5996diff -Nura php-5.1.4/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.4-0.4.11/TSRM/tsrm_virtual_cwd.h
5997--- php-5.1.4/TSRM/tsrm_virtual_cwd.h 2006-04-10 13:56:18.000000000 +0200
5998+++ hardening-patch-5.1.4-0.4.11/TSRM/tsrm_virtual_cwd.h 2006-05-13 16:11:07.000000000 +0200
5999@@ -127,6 +127,22 @@
6000
6001 typedef int (*verify_path_func)(const cwd_state *);
6002
6003+#ifndef HAVE_STRLCPY
6004+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6005+#undef strlcpy
6006+#define strlcpy php_strlcpy
6007+#endif
6008+
6009+#ifndef HAVE_STRLCAT
6010+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6011+#undef strlcat
6012+#define strlcat php_strlcat
6013+#endif
6014+
6015+
6016+#if HARDENING_PATCH
6017+CWD_API char *php_realpath(const char *path, char *resolved);
6018+#endif
6019 CWD_API void virtual_cwd_startup(void);
6020 CWD_API void virtual_cwd_shutdown(void);
6021 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6022@@ -199,6 +215,7 @@
6023 long realpath_cache_size_limit;
6024 long realpath_cache_ttl;
6025 realpath_cache_bucket *realpath_cache[1024];
6026+ int realpath_cache_disable;
6027 } virtual_cwd_globals;
6028
6029 #ifdef ZTS
6030diff -Nura php-5.1.4/Zend/zend_alloc.c hardening-patch-5.1.4-0.4.11/Zend/zend_alloc.c
6031--- php-5.1.4/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100
6032+++ hardening-patch-5.1.4-0.4.11/Zend/zend_alloc.c 2006-05-13 15:39:35.000000000 +0200
6033@@ -64,6 +64,11 @@
6034 # define END_MAGIC_SIZE 0
6035 #endif
6036
6037+#if HARDENING_PATCH_MM_PROTECT
6038+# define CANARY_SIZE sizeof(unsigned int)
6039+#else
6040+# define CANARY_SIZE 0
6041+#endif
6042
6043 # if MEMORY_LIMIT
6044 # if ZEND_DEBUG
6045@@ -105,9 +110,17 @@
6046 if (p==AG(head)) { \
6047 AG(head) = p->pNext; \
6048 } else { \
6049+ if (p != p->pLast->pNext) { \
6050+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6051+ exit(1); \
6052+ } \
6053 p->pLast->pNext = p->pNext; \
6054 } \
6055 if (p->pNext) { \
6056+ if (p != p->pNext->pLast) { \
6057+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6058+ exit(1); \
6059+ } \
6060 p->pNext->pLast = p->pLast; \
6061 }
6062 #else
6063@@ -146,6 +159,12 @@
6064 DECLARE_CACHE_VARS();
6065 TSRMLS_FETCH();
6066
6067+#if HARDENING_PATCH_MM_PROTECT
6068+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6069+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6070+ exit(1);
6071+ }
6072+#endif
6073 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6074
6075 #if !ZEND_DISABLE_MEMORY_CACHE
6076@@ -164,6 +183,10 @@
6077 AG(cache_stats)[CACHE_INDEX][1]++;
6078 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6079 #endif
6080+#if HARDENING_PATCH_MM_PROTECT
6081+ p->canary = HG(canary_1);
6082+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6083+#endif
6084 p->size = size;
6085 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6086 } else {
6087@@ -179,7 +202,7 @@
6088 AG(allocated_memory_peak) = AG(allocated_memory);
6089 }
6090 #endif
6091- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6092+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6093 #if !ZEND_DISABLE_MEMORY_CACHE
6094 }
6095 #endif
6096@@ -210,7 +233,10 @@
6097 # endif
6098 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6099 #endif
6100-
6101+#if HARDENING_PATCH_MM_PROTECT
6102+ p->canary = HG(canary_1);
6103+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6104+#endif
6105 HANDLE_UNBLOCK_INTERRUPTIONS();
6106 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6107 }
6108@@ -238,6 +264,10 @@
6109 }
6110 }
6111
6112+
6113+#if HARDENING_PATCH
6114+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6115+#endif
6116 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
6117 return 0;
6118 }
6119@@ -270,9 +300,25 @@
6120
6121 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6122 {
6123+#if HARDENING_PATCH_MM_PROTECT
6124+ unsigned int canary_2;
6125+#endif
6126 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6127 DECLARE_CACHE_VARS();
6128 TSRMLS_FETCH();
6129+
6130+#if HARDENING_PATCH_MM_PROTECT
6131+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6132+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6133+ if (canary_2 != HG(canary_2)) {
6134+efree_canary_mismatch:
6135+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6136+ exit(1);
6137+ }
6138+ /* to catch double efree()s */
6139+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6140+ p->canary = 0;
6141+#endif
6142
6143 #if defined(ZTS) && TSRM_DEBUG
6144 if (p->thread_id != tsrm_thread_id()) {
6145@@ -313,23 +359,35 @@
6146
6147 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6148 {
6149- void *p;
6150- int final_size = size*nmemb;
6151+ char *p;
6152+ size_t _size = nmemb * size;
6153+
6154+ if (nmemb && (_size/nmemb!=size)) {
6155+#if HARDENING_PATCH
6156+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6157+#endif
6158+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6159+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6160+ kill(getpid(), SIGSEGV);
6161+#else
6162+ exit(1);
6163+#endif
6164+ }
6165
6166- HANDLE_BLOCK_INTERRUPTIONS();
6167- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6168- if (!p) {
6169- HANDLE_UNBLOCK_INTERRUPTIONS();
6170- return (void *) p;
6171+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6172+ if (p) {
6173+ memset(p, 0, _size);
6174 }
6175- memset(p, 0, final_size);
6176- HANDLE_UNBLOCK_INTERRUPTIONS();
6177- return p;
6178+
6179+ return ((void *)p);
6180 }
6181
6182
6183 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6184 {
6185+#if HARDENING_PATCH_MM_PROTECT
6186+ unsigned int canary_2;
6187+#endif
6188 zend_mem_header *p;
6189 zend_mem_header *orig;
6190 DECLARE_CACHE_VARS();
6191@@ -341,6 +399,16 @@
6192
6193 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6194
6195+#if HARDENING_PATCH_MM_PROTECT
6196+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6197+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6198+ if (canary_2 != HG(canary_2)) {
6199+erealloc_canary_mismatch:
6200+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6201+ exit(1);
6202+ }
6203+#endif
6204+
6205 #if defined(ZTS) && TSRM_DEBUG
6206 if (p->thread_id != tsrm_thread_id()) {
6207 void *new_p;
6208@@ -364,7 +432,7 @@
6209 }
6210 #endif
6211 REMOVE_POINTER_FROM_LIST(p);
6212- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6213+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6214 if (!p) {
6215 if (!allow_failure) {
6216 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6217@@ -386,6 +454,9 @@
6218 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6219 #endif
6220
6221+#if HARDENING_PATCH_MM_PROTECT
6222+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6223+#endif
6224 p->size = size;
6225
6226 HANDLE_UNBLOCK_INTERRUPTIONS();
6227@@ -460,6 +531,10 @@
6228 {
6229 AG(head) = NULL;
6230
6231+#if HARDENING_PATCH_MM_PROTECT
6232+ HG(canary_1) = zend_canary();
6233+ HG(canary_2) = zend_canary();
6234+#endif
6235 #if MEMORY_LIMIT
6236 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6237 AG(allocated_memory) = 0;
6238diff -Nura php-5.1.4/Zend/zend_alloc.h hardening-patch-5.1.4-0.4.11/Zend/zend_alloc.h
6239--- php-5.1.4/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100
6240+++ hardening-patch-5.1.4-0.4.11/Zend/zend_alloc.h 2006-05-13 15:39:35.000000000 +0200
6241@@ -35,6 +35,9 @@
6242 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6243
6244 typedef struct _zend_mem_header {
6245+#if HARDENING_PATCH_MM_PROTECT
6246+ unsigned int canary;
6247+#endif
6248 #if ZEND_DEBUG
6249 long magic;
6250 char *filename;
6251diff -Nura php-5.1.4/Zend/zend_API.h hardening-patch-5.1.4-0.4.11/Zend/zend_API.h
6252--- php-5.1.4/Zend/zend_API.h 2006-03-05 17:12:24.000000000 +0100
6253+++ hardening-patch-5.1.4-0.4.11/Zend/zend_API.h 2006-05-13 15:39:35.000000000 +0200
6254@@ -47,6 +47,7 @@
6255 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
6256
6257 #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 },
6258+#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 },
6259
6260 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
6261 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
6262diff -Nura php-5.1.4/Zend/zend_builtin_functions.c hardening-patch-5.1.4-0.4.11/Zend/zend_builtin_functions.c
6263--- php-5.1.4/Zend/zend_builtin_functions.c 2006-04-05 13:36:13.000000000 +0200
6264+++ hardening-patch-5.1.4-0.4.11/Zend/zend_builtin_functions.c 2006-05-13 15:39:35.000000000 +0200
6265@@ -53,6 +53,9 @@
6266 static ZEND_FUNCTION(crash);
6267 #endif
6268 #endif
6269+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6270+static ZEND_FUNCTION(heap_overflow);
6271+#endif
6272 static ZEND_FUNCTION(get_included_files);
6273 static ZEND_FUNCTION(is_subclass_of);
6274 static ZEND_FUNCTION(is_a);
6275@@ -113,6 +116,9 @@
6276 ZEND_FE(crash, NULL)
6277 #endif
6278 #endif
6279+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6280+ ZEND_FE(heap_overflow, NULL)
6281+#endif
6282 ZEND_FE(get_included_files, NULL)
6283 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6284 ZEND_FE(is_subclass_of, NULL)
6285@@ -1103,6 +1109,19 @@
6286
6287 #endif /* ZEND_DEBUG */
6288
6289+
6290+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6291+ZEND_FUNCTION(heap_overflow)
6292+{
6293+ char *nowhere = emalloc(10);
6294+
6295+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6296+
6297+ efree(nowhere);
6298+}
6299+#endif
6300+
6301+
6302 /* {{{ proto array get_included_files(void)
6303 Returns an array with the file names that were include_once()'d */
6304 ZEND_FUNCTION(get_included_files)
6305diff -Nura php-5.1.4/Zend/zend.c hardening-patch-5.1.4-0.4.11/Zend/zend.c
6306--- php-5.1.4/Zend/zend.c 2006-03-30 23:39:01.000000000 +0200
6307+++ hardening-patch-5.1.4-0.4.11/Zend/zend.c 2006-05-13 15:39:35.000000000 +0200
6308@@ -55,6 +55,12 @@
6309 ZEND_API void (*zend_unblock_interruptions)(void);
6310 ZEND_API void (*zend_ticks_function)(int ticks);
6311 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6312+#if HARDENING_PATCH
6313+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6314+#endif
6315+#if HARDENING_PATCH_INC_PROTECT
6316+ZEND_API int (*zend_is_valid_include)(zval *z);
6317+#endif
6318 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
6319 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
6320
6321@@ -74,9 +80,390 @@
6322 return SUCCESS;
6323 }
6324
6325+#if HARDENING_PATCH
6326+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6327+{
6328+ if (!new_value) {
6329+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6330+ } else {
6331+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6332+ }
6333+ return SUCCESS;
6334+}
6335+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6336+{
6337+ if (!new_value) {
6338+ EG(hphp_log_syslog_facility) = LOG_USER;
6339+ } else {
6340+ EG(hphp_log_syslog_facility) = atoi(new_value);
6341+ }
6342+ return SUCCESS;
6343+}
6344+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6345+{
6346+ if (!new_value) {
6347+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6348+ } else {
6349+ EG(hphp_log_syslog_priority) = atoi(new_value);
6350+ }
6351+ return SUCCESS;
6352+}
6353+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6354+{
6355+ if (!new_value) {
6356+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6357+ } else {
6358+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6359+ }
6360+ return SUCCESS;
6361+}
6362+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6363+{
6364+ if (!new_value) {
6365+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
6366+ } else {
6367+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6368+ }
6369+ return SUCCESS;
6370+}
6371+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6372+{
6373+ if (EG(hphp_log_scriptname)) {
6374+ pefree(EG(hphp_log_scriptname),1);
6375+ }
6376+ EG(hphp_log_scriptname) = NULL;
6377+ if (new_value) {
6378+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6379+ }
6380+ return SUCCESS;
6381+}
6382+
6383+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6384+{
6385+ char *s = NULL, *e, *val;
6386+ unsigned long dummy = 1;
6387+
6388+ if (!new_value) {
6389+include_whitelist_destroy:
6390+ if (HG(include_whitelist)) {
6391+ zend_hash_destroy(HG(include_whitelist));
6392+ pefree(HG(include_whitelist),1);
6393+ }
6394+ HG(include_whitelist) = NULL;
6395+ return SUCCESS;
6396+ }
6397+ if (!(*new_value)) {
6398+ goto include_whitelist_destroy;
6399+ }
6400+
6401+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6402+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6403+
6404+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6405+ e = val;
6406+
6407+ while (*e) {
6408+ switch (*e) {
6409+ case ' ':
6410+ case ',':
6411+ if (s) {
6412+ *e = '\0';
6413+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6414+ s = NULL;
6415+ }
6416+ break;
6417+ default:
6418+ if (!s) {
6419+ s = e;
6420+ }
6421+ break;
6422+ }
6423+ e++;
6424+ }
6425+ if (s) {
6426+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6427+ }
6428+ efree(val);
6429+
6430+ return SUCCESS;
6431+}
6432+
6433+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6434+{
6435+ char *s = NULL, *e, *val;
6436+ unsigned long dummy = 1;
6437+
6438+ if (!new_value) {
6439+include_blacklist_destroy:
6440+ if (HG(include_blacklist)) {
6441+ zend_hash_destroy(HG(include_blacklist));
6442+ pefree(HG(include_blacklist),1);
6443+ }
6444+ HG(include_blacklist) = NULL;
6445+ return SUCCESS;
6446+ }
6447+ if (!(*new_value)) {
6448+ goto include_blacklist_destroy;
6449+ }
6450+
6451+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6452+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6453+
6454+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6455+ e = val;
6456+
6457+ while (*e) {
6458+ switch (*e) {
6459+ case ' ':
6460+ case ',':
6461+ if (s) {
6462+ *e = '\0';
6463+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6464+ s = NULL;
6465+ }
6466+ break;
6467+ default:
6468+ if (!s) {
6469+ s = e;
6470+ }
6471+ break;
6472+ }
6473+ e++;
6474+ }
6475+ if (s) {
6476+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6477+ }
6478+ efree(val);
6479+
6480+ return SUCCESS;
6481+}
6482+
6483+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6484+{
6485+ char *s = NULL, *e, *val;
6486+ unsigned long dummy = 1;
6487+
6488+ if (!new_value) {
6489+eval_whitelist_destroy:
6490+ if (HG(eval_whitelist)) {
6491+ zend_hash_destroy(HG(eval_whitelist));
6492+ pefree(HG(eval_whitelist),1);
6493+ }
6494+ HG(eval_whitelist) = NULL;
6495+ return SUCCESS;
6496+ }
6497+ if (!(*new_value)) {
6498+ goto eval_whitelist_destroy;
6499+ }
6500+
6501+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6502+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6503+
6504+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6505+ e = val;
6506+
6507+ while (*e) {
6508+ switch (*e) {
6509+ case ' ':
6510+ case ',':
6511+ if (s) {
6512+ *e = '\0';
6513+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6514+ s = NULL;
6515+ }
6516+ break;
6517+ default:
6518+ if (!s) {
6519+ s = e;
6520+ }
6521+ break;
6522+ }
6523+ e++;
6524+ }
6525+ if (s) {
6526+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6527+ }
6528+ efree(val);
6529+
6530+ return SUCCESS;
6531+}
6532+
6533+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6534+{
6535+ char *s = NULL, *e, *val;
6536+ unsigned long dummy = 1;
6537+
6538+ if (!new_value) {
6539+eval_blacklist_destroy:
6540+ if (HG(eval_blacklist)) {
6541+ zend_hash_destroy(HG(eval_blacklist));
6542+ pefree(HG(eval_blacklist), 1);
6543+ }
6544+ HG(eval_blacklist) = NULL;
6545+ return SUCCESS;
6546+ }
6547+ if (!(*new_value)) {
6548+ goto eval_blacklist_destroy;
6549+ }
6550+
6551+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6552+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6553+
6554+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6555+ e = val;
6556+
6557+ while (*e) {
6558+ switch (*e) {
6559+ case ' ':
6560+ case ',':
6561+ if (s) {
6562+ *e = '\0';
6563+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6564+ s = NULL;
6565+ }
6566+ break;
6567+ default:
6568+ if (!s) {
6569+ s = e;
6570+ }
6571+ break;
6572+ }
6573+ e++;
6574+ }
6575+ if (s) {
6576+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6577+ }
6578+ efree(val);
6579+
6580+
6581+ return SUCCESS;
6582+}
6583+
6584+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6585+{
6586+ char *s = NULL, *e, *val;
6587+ unsigned long dummy = 1;
6588+
6589+ if (!new_value) {
6590+func_whitelist_destroy:
6591+ if (HG(func_whitelist)) {
6592+ zend_hash_destroy(HG(func_whitelist));
6593+ pefree(HG(func_whitelist),1);
6594+ }
6595+ HG(func_whitelist) = NULL;
6596+ return SUCCESS;
6597+ }
6598+ if (!(*new_value)) {
6599+ goto func_whitelist_destroy;
6600+ }
6601+
6602+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6603+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6604+
6605+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6606+ e = val;
6607+
6608+ while (*e) {
6609+ switch (*e) {
6610+ case ' ':
6611+ case ',':
6612+ if (s) {
6613+ *e = '\0';
6614+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6615+ s = NULL;
6616+ }
6617+ break;
6618+ default:
6619+ if (!s) {
6620+ s = e;
6621+ }
6622+ break;
6623+ }
6624+ e++;
6625+ }
6626+ if (s) {
6627+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6628+ }
6629+ efree(val);
6630+
6631+ return SUCCESS;
6632+}
6633+
6634+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6635+{
6636+ char *s = NULL, *e, *val;
6637+ unsigned long dummy = 1;
6638+
6639+ if (!new_value) {
6640+func_blacklist_destroy:
6641+ if (HG(func_blacklist)) {
6642+ zend_hash_destroy(HG(func_blacklist));
6643+ pefree(HG(func_blacklist),1);
6644+ }
6645+ HG(func_blacklist) = NULL;
6646+ return SUCCESS;
6647+ }
6648+ if (!(*new_value)) {
6649+ goto func_blacklist_destroy;
6650+ }
6651+
6652+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6653+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6654+
6655+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6656+ e = val;
6657+
6658+ while (*e) {
6659+ switch (*e) {
6660+ case ' ':
6661+ case ',':
6662+ if (s) {
6663+ *e = '\0';
6664+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6665+ s = NULL;
6666+ }
6667+ break;
6668+ default:
6669+ if (!s) {
6670+ s = e;
6671+ }
6672+ break;
6673+ }
6674+ e++;
6675+ }
6676+ if (s) {
6677+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6678+ }
6679+ efree(val);
6680+
6681+
6682+ return SUCCESS;
6683+}
6684+
6685+#endif
6686
6687 ZEND_INI_BEGIN()
6688 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6689+#if HARDENING_PATCH
6690+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6691+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6692+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6693+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6694+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6695+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6696+ 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)
6697+
6698+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6699+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6700+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6701+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6702+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6703+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6704+
6705+ 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)
6706+ 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)
6707+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6708+#endif
6709 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
6710 #ifdef ZEND_MULTIBYTE
6711 STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
6712@@ -501,9 +888,13 @@
6713 EG(user_error_handler) = NULL;
6714 EG(user_exception_handler) = NULL;
6715 EG(in_execution) = 0;
6716+ EG(in_code_type) = 0;
6717 EG(in_autoload) = NULL;
6718 EG(current_execute_data) = NULL;
6719 EG(current_module) = NULL;
6720+#if HARDENING_PATCH
6721+ EG(hphp_log_scriptname) = NULL;
6722+#endif
6723 }
6724
6725
6726@@ -574,6 +965,14 @@
6727 extern zend_scanner_globals language_scanner_globals;
6728 #endif
6729
6730+ /* Set up Hardening-Patch utility functions first */
6731+#if HARDENING_PATCH
6732+ zend_security_log = utility_functions->security_log_function;
6733+#endif
6734+#if HARDENING_PATCH_INC_PROTECT
6735+ zend_is_valid_include = utility_functions->is_valid_include;
6736+#endif
6737+
6738 #ifdef ZTS
6739 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6740 #else
6741@@ -777,6 +1176,7 @@
6742 }
6743 CG(unclean_shutdown) = 1;
6744 CG(in_compilation) = EG(in_execution) = 0;
6745+ EG(in_code_type) = 0;
6746 EG(current_execute_data) = NULL;
6747 longjmp(EG(bailout), FAILURE);
6748 }
6749diff -Nura php-5.1.4/Zend/zend_canary.c hardening-patch-5.1.4-0.4.11/Zend/zend_canary.c
6750--- php-5.1.4/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6751+++ hardening-patch-5.1.4-0.4.11/Zend/zend_canary.c 2006-05-13 15:39:35.000000000 +0200
6752@@ -0,0 +1,58 @@
6753+/*
6754+ +----------------------------------------------------------------------+
6755+ | Hardening-Patch for PHP |
6756+ +----------------------------------------------------------------------+
6757+ | Copyright (c) 2004-2005 Stefan Esser |
6758+ +----------------------------------------------------------------------+
6759+ | This source file is subject to version 2.02 of the PHP license, |
6760+ | that is bundled with this package in the file LICENSE, and is |
6761+ | available at through the world-wide-web at |
6762+ | http://www.php.net/license/2_02.txt. |
6763+ | If you did not receive a copy of the PHP license and are unable to |
6764+ | obtain it through the world-wide-web, please send a note to |
6765+ | license@php.net so we can mail you a copy immediately. |
6766+ +----------------------------------------------------------------------+
6767+ | Author: Stefan Esser <sesser@hardened-php.net> |
6768+ +----------------------------------------------------------------------+
6769+ */
6770+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6771+
6772+#include "zend.h"
6773+
6774+#include <stdio.h>
6775+#include <stdlib.h>
6776+
6777+
6778+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6779+
6780+/* will be replaced later with more compatible method */
6781+ZEND_API unsigned int zend_canary()
6782+{
6783+ time_t t;
6784+ unsigned int canary;
6785+ int fd;
6786+
6787+ fd = open("/dev/urandom", 0);
6788+ if (fd != -1) {
6789+ int r = read(fd, &canary, sizeof(canary));
6790+ close(fd);
6791+ if (r == sizeof(canary)) {
6792+ return (canary);
6793+ }
6794+ }
6795+ /* not good but we never want to do this */
6796+ time(&t);
6797+ canary = *(unsigned int *)&t + getpid() << 16;
6798+ return (canary);
6799+}
6800+#endif
6801+
6802+
6803+/*
6804+ * Local variables:
6805+ * tab-width: 4
6806+ * c-basic-offset: 4
6807+ * End:
6808+ * vim600: sw=4 ts=4 fdm=marker
6809+ * vim<600: sw=4 ts=4
6810+ */
6811diff -Nura php-5.1.4/Zend/zend_compile.c hardening-patch-5.1.4-0.4.11/Zend/zend_compile.c
6812--- php-5.1.4/Zend/zend_compile.c 2006-05-02 17:49:26.000000000 +0200
6813+++ hardening-patch-5.1.4-0.4.11/Zend/zend_compile.c 2006-05-13 15:39:35.000000000 +0200
6814@@ -1093,6 +1093,13 @@
6815 op_array.prototype = NULL;
6816
6817 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
6818+#if HARDENING_PATCH
6819+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6820+ op_array.created_by_eval = 1;
6821+ } else {
6822+ op_array.created_by_eval = 0;
6823+ }
6824+#endif
6825
6826 if (is_method) {
6827 char *short_class_name = CG(active_class_entry)->name;
6828diff -Nura php-5.1.4/Zend/zend_compile.h hardening-patch-5.1.4-0.4.11/Zend/zend_compile.h
6829--- php-5.1.4/Zend/zend_compile.h 2006-03-13 12:13:42.000000000 +0100
6830+++ hardening-patch-5.1.4-0.4.11/Zend/zend_compile.h 2006-05-13 15:39:35.000000000 +0200
6831@@ -217,6 +217,9 @@
6832 zend_uint doc_comment_len;
6833
6834 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6835+#if HARDENING_PATCH
6836+ zend_bool created_by_eval;
6837+#endif
6838 };
6839
6840
6841@@ -295,6 +298,8 @@
6842 zval ***CVs;
6843 zend_bool original_in_execution;
6844 HashTable *symbol_table;
6845+ zend_uint original_in_code_type;
6846+ zend_uint execute_depth;
6847 struct _zend_execute_data *prev_execute_data;
6848 zval *old_error_reporting;
6849 };
6850@@ -617,6 +622,7 @@
6851 #define ZEND_OVERLOADED_FUNCTION 3
6852 #define ZEND_EVAL_CODE 4
6853 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
6854+#define ZEND_SANDBOX_CODE 6
6855
6856 #define ZEND_INTERNAL_CLASS 1
6857 #define ZEND_USER_CLASS 2
6858diff -Nura php-5.1.4/Zend/zend_constants.c hardening-patch-5.1.4-0.4.11/Zend/zend_constants.c
6859--- php-5.1.4/Zend/zend_constants.c 2006-03-15 15:12:26.000000000 +0100
6860+++ hardening-patch-5.1.4-0.4.11/Zend/zend_constants.c 2006-05-13 15:39:35.000000000 +0200
6861@@ -109,6 +109,73 @@
6862 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6863
6864 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6865+#if HARDENING_PATCH
6866+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6867+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6868+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6869+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6870+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6871+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6872+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6873+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6874+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6875+
6876+ /* error levels */
6877+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6878+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6879+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6880+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6881+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6882+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6883+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6884+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6885+ /* facility: type of program logging the message */
6886+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6887+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6888+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6889+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6890+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6891+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6892+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6893+#ifdef LOG_NEWS
6894+ /* No LOG_NEWS on HP-UX */
6895+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6896+#endif
6897+#ifdef LOG_UUCP
6898+ /* No LOG_UUCP on HP-UX */
6899+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6900+#endif
6901+#ifdef LOG_CRON
6902+ /* apparently some systems don't have this one */
6903+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6904+#endif
6905+#ifdef LOG_AUTHPRIV
6906+ /* AIX doesn't have LOG_AUTHPRIV */
6907+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
6908+#endif
6909+#if !defined(PHP_WIN32) && !defined(NETWARE)
6910+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
6911+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
6912+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
6913+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
6914+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
6915+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
6916+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
6917+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
6918+#endif
6919+ /* options */
6920+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
6921+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
6922+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
6923+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
6924+#ifdef LOG_NOWAIT
6925+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
6926+#endif
6927+#ifdef LOG_PERROR
6928+ /* AIX doesn't have LOG_PERROR */
6929+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
6930+#endif
6931+#endif
6932
6933 /* true/false constants */
6934 {
6935diff -Nura php-5.1.4/Zend/zend_errors.h hardening-patch-5.1.4-0.4.11/Zend/zend_errors.h
6936--- php-5.1.4/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100
6937+++ hardening-patch-5.1.4-0.4.11/Zend/zend_errors.h 2006-05-13 15:39:35.000000000 +0200
6938@@ -38,6 +38,18 @@
6939 #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)
6940 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
6941
6942+#if HARDENING_PATCH
6943+#define S_MEMORY (1<<0L)
6944+#define S_VARS (1<<1L)
6945+#define S_FILES (1<<2L)
6946+#define S_INCLUDE (1<<3L)
6947+#define S_SQL (1<<4L)
6948+#define S_EXECUTOR (1<<5L)
6949+#define S_MISC (1<<30L)
6950+#define S_INTERNAL (1<<29L)
6951+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
6952+#endif
6953+
6954 #endif /* ZEND_ERRORS_H */
6955
6956 /*
6957diff -Nura php-5.1.4/Zend/zend_execute_API.c hardening-patch-5.1.4-0.4.11/Zend/zend_execute_API.c
6958--- php-5.1.4/Zend/zend_execute_API.c 2006-04-21 00:49:20.000000000 +0200
6959+++ hardening-patch-5.1.4-0.4.11/Zend/zend_execute_API.c 2006-05-13 15:39:35.000000000 +0200
6960@@ -142,6 +142,7 @@
6961 EG(class_table) = CG(class_table);
6962
6963 EG(in_execution) = 0;
6964+ EG(in_code_type) = 0;
6965 EG(in_autoload) = NULL;
6966 EG(autoload_func) = NULL;
6967
6968@@ -784,6 +785,39 @@
6969 if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
6970 EX(function_state).function = NULL;
6971 }
6972+#if HARDENING_PATCH
6973+ else {
6974+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6975+ if (HG(eval_whitelist) != NULL) {
6976+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6977+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
6978+ efree(function_name_lc);
6979+ zend_bailout();
6980+ }
6981+ } else if (HG(eval_blacklist) != NULL) {
6982+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6983+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
6984+ efree(function_name_lc);
6985+ zend_bailout();
6986+ }
6987+ }
6988+ }
6989+
6990+ if (HG(func_whitelist) != NULL) {
6991+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6992+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
6993+ efree(function_name_lc);
6994+ zend_bailout();
6995+ }
6996+ } else if (HG(func_blacklist) != NULL) {
6997+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6998+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
6999+ efree(function_name_lc);
7000+ zend_bailout();
7001+ }
7002+ }
7003+ }
7004+#endif
7005 efree(function_name_lc);
7006 }
7007
7008@@ -1076,7 +1110,7 @@
7009 return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
7010 }
7011
7012-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7013+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7014 {
7015 zval pv;
7016 zend_op_array *new_op_array;
7017@@ -1109,6 +1143,7 @@
7018 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7019 zend_op **original_opline_ptr = EG(opline_ptr);
7020
7021+ new_op_array->type = type;
7022 EG(return_value_ptr_ptr) = &local_retval_ptr;
7023 EG(active_op_array) = new_op_array;
7024 EG(no_extensions)=1;
7025@@ -1143,6 +1178,12 @@
7026 }
7027
7028
7029+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7030+{
7031+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7032+}
7033+
7034+
7035 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
7036 {
7037 int result;
7038diff -Nura php-5.1.4/Zend/zend_execute.c hardening-patch-5.1.4-0.4.11/Zend/zend_execute.c
7039--- php-5.1.4/Zend/zend_execute.c 2006-02-26 11:53:38.000000000 +0100
7040+++ hardening-patch-5.1.4-0.4.11/Zend/zend_execute.c 2006-05-13 15:39:35.000000000 +0200
7041@@ -1351,6 +1351,37 @@
7042 /* OBJ-TBI - doesn't support new object model! */
7043 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
7044 }
7045+#if HARDENING_PATCH
7046+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7047+ if (HG(eval_whitelist) != NULL) {
7048+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7049+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7050+ efree(lcname);
7051+ zend_bailout();
7052+ }
7053+ } else if (HG(eval_blacklist) != NULL) {
7054+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7055+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7056+ efree(lcname);
7057+ zend_bailout();
7058+ }
7059+ }
7060+ }
7061+
7062+ if (HG(func_whitelist) != NULL) {
7063+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7064+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7065+ efree(lcname);
7066+ zend_bailout();
7067+ }
7068+ } else if (HG(func_blacklist) != NULL) {
7069+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7070+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7071+ efree(lcname);
7072+ zend_bailout();
7073+ }
7074+ }
7075+#endif
7076
7077 return 0;
7078 }
7079@@ -1396,6 +1427,7 @@
7080 efree(EX(Ts)); \
7081 } \
7082 EG(in_execution) = EX(original_in_execution); \
7083+ EG(in_code_type) = EX(original_in_code_type); \
7084 EG(current_execute_data) = EX(prev_execute_data); \
7085 ZEND_VM_RETURN()
7086
7087diff -Nura php-5.1.4/Zend/zend_extensions.c hardening-patch-5.1.4-0.4.11/Zend/zend_extensions.c
7088--- php-5.1.4/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100
7089+++ hardening-patch-5.1.4-0.4.11/Zend/zend_extensions.c 2006-05-13 15:39:35.000000000 +0200
7090@@ -55,23 +55,44 @@
7091 return FAILURE;
7092 }
7093
7094+ /* check if module is compiled against Hardening-Patch */
7095+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7096+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7097+ "The Hardening-Patch version %d is installed.\n\n",
7098+ new_extension->name,
7099+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7100+ DL_UNLOAD(handle);
7101+ return FAILURE;
7102+ }
7103+
7104+
7105+ /* check if module is compiled against correct Hardening-Patch version */
7106+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7107+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7108+ "The Hardening-Patch version %d is installed.\n\n",
7109+ new_extension->name,
7110+ extension_version_info->zend_extension_api_no,
7111+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7112+ DL_UNLOAD(handle);
7113+ return FAILURE;
7114+ }
7115
7116 /* allow extension to proclaim compatibility with any Zend version */
7117- 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)) {
7118- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7119+ 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)) {
7120+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7121 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7122 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7123 new_extension->name,
7124- extension_version_info->zend_extension_api_no,
7125+ extension_version_info->real_zend_extension_api_no,
7126 ZEND_EXTENSION_API_NO);
7127 DL_UNLOAD(handle);
7128 return FAILURE;
7129- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7130+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7131 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7132 "The Zend Engine API version %d which is installed, is newer.\n"
7133 "Contact %s at %s for a later version of %s.\n\n",
7134 new_extension->name,
7135- extension_version_info->zend_extension_api_no,
7136+ extension_version_info->real_zend_extension_api_no,
7137 ZEND_EXTENSION_API_NO,
7138 new_extension->author,
7139 new_extension->URL,
7140diff -Nura php-5.1.4/Zend/zend_extensions.h hardening-patch-5.1.4-0.4.11/Zend/zend_extensions.h
7141--- php-5.1.4/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100
7142+++ hardening-patch-5.1.4-0.4.11/Zend/zend_extensions.h 2006-05-13 15:39:35.000000000 +0200
7143@@ -24,9 +24,11 @@
7144
7145 #include "zend_compile.h"
7146
7147-/* The first number is the engine version and the rest is the date.
7148+/* The first API number is a flag saying that Hardening-Patch is used.
7149+ * The second number is the engine version and the date.
7150 * This way engine 2 API no. is always greater than engine 1 API no..
7151 */
7152+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106
7153 #define ZEND_EXTENSION_API_NO 220051025
7154
7155 typedef struct _zend_extension_version_info {
7156@@ -34,6 +36,7 @@
7157 char *required_zend_version;
7158 unsigned char thread_safe;
7159 unsigned char debug;
7160+ int real_zend_extension_api_no;
7161 } zend_extension_version_info;
7162
7163
7164@@ -101,7 +104,7 @@
7165
7166
7167 #define ZEND_EXTENSION() \
7168- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7169+ 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 }
7170
7171 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7172 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7173diff -Nura php-5.1.4/Zend/zend_globals.h hardening-patch-5.1.4-0.4.11/Zend/zend_globals.h
7174--- php-5.1.4/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100
7175+++ hardening-patch-5.1.4-0.4.11/Zend/zend_globals.h 2006-05-13 15:39:35.000000000 +0200
7176@@ -180,6 +180,16 @@
7177
7178 int error_reporting;
7179 int orig_error_reporting;
7180+#if HARDENING_PATCH
7181+ int hphp_log_syslog;
7182+ int hphp_log_syslog_facility;
7183+ int hphp_log_syslog_priority;
7184+ int hphp_log_sapi;
7185+ int hphp_log_script;
7186+ char *hphp_log_scriptname;
7187+ zend_bool hphp_log_use_x_forwarded_for;
7188+ long hphp_executor_max_depth;
7189+#endif
7190 int exit_status;
7191
7192 zend_op_array *active_op_array;
7193@@ -197,6 +207,7 @@
7194 int ticks_count;
7195
7196 zend_bool in_execution;
7197+ zend_uint in_code_type;
7198 HashTable *in_autoload;
7199 zend_function *autoload_func;
7200 zend_bool bailout_set;
7201diff -Nura php-5.1.4/Zend/zend.h hardening-patch-5.1.4-0.4.11/Zend/zend.h
7202--- php-5.1.4/Zend/zend.h 2006-03-30 23:39:01.000000000 +0200
7203+++ hardening-patch-5.1.4-0.4.11/Zend/zend.h 2006-05-13 15:39:35.000000000 +0200
7204@@ -297,6 +297,7 @@
7205 /* Variable information */
7206 zvalue_value value; /* value */
7207 zend_uint refcount;
7208+ zend_ushort flags;
7209 zend_uchar type; /* active type */
7210 zend_uchar is_ref;
7211 };
7212@@ -382,6 +383,12 @@
7213 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7214 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
7215 char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
7216+#if HARDENING_PATCH
7217+ void (*security_log_function)(int loglevel, char *fmt, ...);
7218+#endif
7219+#if HARDENING_PATCH_INC_PROTECT
7220+ int (*is_valid_include)(zval *z);
7221+#endif
7222 } zend_utility_functions;
7223
7224
7225@@ -519,7 +526,16 @@
7226 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7227 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
7228 extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
7229+#if HARDENING_PATCH
7230+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7231+#endif
7232+#if HARDENING_PATCH_INC_PROTECT
7233+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7234+#endif
7235
7236+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7237+ZEND_API unsigned int zend_canary(void);
7238+#endif
7239
7240 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
7241
7242@@ -644,6 +660,11 @@
7243
7244 #include "zend_variables.h"
7245
7246+#if HARDENING_PATCH
7247+#include "hardened_globals.h"
7248+#include "php_syslog.h"
7249+#endif
7250+
7251 #endif /* ZEND_H */
7252
7253 /*
7254diff -Nura php-5.1.4/Zend/zend_hash.c hardening-patch-5.1.4-0.4.11/Zend/zend_hash.c
7255--- php-5.1.4/Zend/zend_hash.c 2006-04-07 12:06:21.000000000 +0200
7256+++ hardening-patch-5.1.4-0.4.11/Zend/zend_hash.c 2006-05-13 15:39:35.000000000 +0200
7257@@ -21,6 +21,18 @@
7258
7259 #include "zend.h"
7260
7261+#if HARDENING_PATCH_HASH_PROTECT
7262+ unsigned int zend_hash_canary = 0x1234567;
7263+ zend_bool zend_hash_canary_inited = 0;
7264+#endif
7265+
7266+#define CHECK_HASH_CANARY(hash) \
7267+ if (zend_hash_canary != (hash)->canary) { \
7268+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7269+ exit(1); \
7270+ }
7271+
7272+
7273 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
7274 (element)->pNext = (list_head); \
7275 (element)->pLast = NULL; \
7276@@ -138,6 +150,9 @@
7277 {
7278 uint i = 3;
7279 Bucket **tmp;
7280+#if HARDENING_PATCH_HASH_PROTECT
7281+ TSRMLS_FETCH();
7282+#endif
7283
7284 SET_INCONSISTENT(HT_OK);
7285
7286@@ -147,6 +162,13 @@
7287
7288 ht->nTableSize = 1 << i;
7289 ht->nTableMask = ht->nTableSize - 1;
7290+#if HARDENING_PATCH_HASH_PROTECT
7291+ if (zend_hash_canary_inited==0) {
7292+ zend_hash_canary = zend_canary();
7293+ zend_hash_canary_inited = 1;
7294+ }
7295+ ht->canary = zend_hash_canary;
7296+#endif
7297 ht->pDestructor = pDestructor;
7298 ht->arBuckets = NULL;
7299 ht->pListHead = NULL;
7300@@ -226,6 +248,9 @@
7301 }
7302 #endif
7303 if (ht->pDestructor) {
7304+#if HARDENING_PATCH_HASH_PROTECT
7305+ CHECK_HASH_CANARY(ht);
7306+#endif
7307 ht->pDestructor(p->pData);
7308 }
7309 UPDATE_DATA(ht, p, pData, nDataSize);
7310@@ -291,6 +316,9 @@
7311 }
7312 #endif
7313 if (ht->pDestructor) {
7314+#if HARDENING_PATCH_HASH_PROTECT
7315+ CHECK_HASH_CANARY(ht);
7316+#endif
7317 ht->pDestructor(p->pData);
7318 }
7319 UPDATE_DATA(ht, p, pData, nDataSize);
7320@@ -366,6 +394,9 @@
7321 }
7322 #endif
7323 if (ht->pDestructor) {
7324+#if HARDENING_PATCH_HASH_PROTECT
7325+ CHECK_HASH_CANARY(ht);
7326+#endif
7327 ht->pDestructor(p->pData);
7328 }
7329 UPDATE_DATA(ht, p, pData, nDataSize);
7330@@ -414,7 +445,7 @@
7331 IS_CONSISTENT(ht);
7332
7333 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7334- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7335+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7336 if (t) {
7337 HANDLE_BLOCK_INTERRUPTIONS();
7338 ht->arBuckets = t;
7339@@ -424,6 +455,7 @@
7340 HANDLE_UNBLOCK_INTERRUPTIONS();
7341 return SUCCESS;
7342 }
7343+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7344 return FAILURE;
7345 }
7346 return SUCCESS;
7347@@ -489,6 +521,9 @@
7348 ht->pInternalPointer = p->pListNext;
7349 }
7350 if (ht->pDestructor) {
7351+#if HARDENING_PATCH_HASH_PROTECT
7352+ CHECK_HASH_CANARY(ht);
7353+#endif
7354 ht->pDestructor(p->pData);
7355 }
7356 if (p->pData != &p->pDataPtr) {
7357@@ -518,6 +553,9 @@
7358 q = p;
7359 p = p->pListNext;
7360 if (ht->pDestructor) {
7361+#if HARDENING_PATCH_HASH_PROTECT
7362+ CHECK_HASH_CANARY(ht);
7363+#endif
7364 ht->pDestructor(q->pData);
7365 }
7366 if (q->pData != &q->pDataPtr) {
7367@@ -544,6 +582,9 @@
7368 q = p;
7369 p = p->pListNext;
7370 if (ht->pDestructor) {
7371+#if HARDENING_PATCH_HASH_PROTECT
7372+ CHECK_HASH_CANARY(ht);
7373+#endif
7374 ht->pDestructor(q->pData);
7375 }
7376 if (q->pData != &q->pDataPtr) {
7377@@ -573,6 +614,9 @@
7378 HANDLE_BLOCK_INTERRUPTIONS();
7379
7380 if (ht->pDestructor) {
7381+#if HARDENING_PATCH_HASH_PROTECT
7382+ CHECK_HASH_CANARY(ht);
7383+#endif
7384 ht->pDestructor(p->pData);
7385 }
7386 if (p->pData != &p->pDataPtr) {
7387diff -Nura php-5.1.4/Zend/zend_hash.h hardening-patch-5.1.4-0.4.11/Zend/zend_hash.h
7388--- php-5.1.4/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100
7389+++ hardening-patch-5.1.4-0.4.11/Zend/zend_hash.h 2006-05-13 15:39:35.000000000 +0200
7390@@ -58,6 +58,9 @@
7391 } Bucket;
7392
7393 typedef struct _hashtable {
7394+#if HARDENING_PATCH_HASH_PROTECT
7395+ unsigned int canary;
7396+#endif
7397 uint nTableSize;
7398 uint nTableMask;
7399 uint nNumOfElements;
7400diff -Nura php-5.1.4/Zend/zend_language_scanner.l hardening-patch-5.1.4-0.4.11/Zend/zend_language_scanner.l
7401--- php-5.1.4/Zend/zend_language_scanner.l 2006-04-13 15:48:28.000000000 +0200
7402+++ hardening-patch-5.1.4-0.4.11/Zend/zend_language_scanner.l 2006-05-13 15:39:35.000000000 +0200
7403@@ -389,6 +389,13 @@
7404 compilation_successful=0;
7405 } else {
7406 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7407+#if HARDENING_PATCH
7408+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7409+ op_array->created_by_eval = 1;
7410+ } else {
7411+ op_array->created_by_eval = 0;
7412+ }
7413+#endif
7414 CG(in_compilation) = 1;
7415 CG(active_op_array) = op_array;
7416 compiler_result = zendparse(TSRMLS_C);
7417diff -Nura php-5.1.4/Zend/zend_language_scanner.c hardening-patch-5.1.4-0.4.11/Zend/zend_language_scanner.c
7418--- php-5.1.4/Zend/zend_language_scanner.c 2006-05-04 01:31:36.000000000 +0200
7419+++ hardening-patch-5.1.4-0.4.11/Zend/zend_language_scanner.c 2006-05-13 15:39:35.000000000 +0200
7420@@ -3075,6 +3075,13 @@
7421 compilation_successful=0;
7422 } else {
7423 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7424+#if HARDENING_PATCH
7425+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7426+ op_array->created_by_eval = 1;
7427+ } else {
7428+ op_array->created_by_eval = 0;
7429+ }
7430+#endif
7431 CG(in_compilation) = 1;
7432 CG(active_op_array) = op_array;
7433 compiler_result = zendparse(TSRMLS_C);
7434diff -Nura php-5.1.4/Zend/zend_llist.c hardening-patch-5.1.4-0.4.11/Zend/zend_llist.c
7435--- php-5.1.4/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100
7436+++ hardening-patch-5.1.4-0.4.11/Zend/zend_llist.c 2006-05-13 15:39:35.000000000 +0200
7437@@ -22,9 +22,49 @@
7438 #include "zend.h"
7439 #include "zend_llist.h"
7440 #include "zend_qsort.h"
7441+#include "zend_globals.h"
7442+
7443+#if HARDENING_PATCH_LL_PROTECT
7444+ unsigned int zend_llist_canary_1 = 0x1234567;
7445+ unsigned int zend_llist_canary_2 = 0x1553425;
7446+ zend_bool zend_llist_canary_inited = 0;
7447+#endif
7448+
7449+#define CHECK_LIST_CANARY(list) \
7450+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7451+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7452+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7453+ exit(1); \
7454+ }
7455+
7456+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7457+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7458+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7459+ exit(1); \
7460+ }
7461+
7462
7463 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7464 {
7465+#if HARDENING_PATCH_LL_PROTECT
7466+ TSRMLS_FETCH();
7467+
7468+ if (persistent) {
7469+ if (!zend_llist_canary_inited) {
7470+ /* do not change order to ensure thread safety */
7471+ zend_llist_canary_1 = zend_canary();
7472+ zend_llist_canary_2 = zend_canary();
7473+ zend_llist_canary_inited = 1;
7474+ }
7475+ } else
7476+ if (!HG(ll_canary_inited)) {
7477+ HG(canary_3) = zend_canary();
7478+ HG(canary_4) = zend_canary();
7479+ HG(ll_canary_inited) = 1;
7480+ }
7481+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7482+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7483+#endif
7484 l->head = NULL;
7485 l->tail = NULL;
7486 l->count = 0;
7487@@ -38,6 +78,11 @@
7488 {
7489 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7490
7491+#if HARDENING_PATCH_LL_PROTECT
7492+ TSRMLS_FETCH();
7493+ CHECK_LIST_CANARY(l)
7494+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7495+#endif
7496 tmp->prev = l->tail;
7497 tmp->next = NULL;
7498 if (l->tail) {
7499@@ -56,6 +101,11 @@
7500 {
7501 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7502
7503+#if HARDENING_PATCH_LL_PROTECT
7504+ TSRMLS_FETCH();
7505+ CHECK_LIST_CANARY(l)
7506+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7507+#endif
7508 tmp->next = l->head;
7509 tmp->prev = NULL;
7510 if (l->head) {
7511@@ -93,10 +143,20 @@
7512 zend_llist_element *current=l->head;
7513 zend_llist_element *next;
7514
7515+#if HARDENING_PATCH_LL_PROTECT
7516+ TSRMLS_FETCH();
7517+ CHECK_LIST_CANARY(l)
7518+#endif
7519 while (current) {
7520+#if HARDENING_PATCH_LL_PROTECT
7521+ CHECK_LISTELEMENT_CANARY(current, l)
7522+#endif
7523 next = current->next;
7524 if (compare(current->data, element)) {
7525 DEL_LLIST_ELEMENT(current, l);
7526+#if HARDENING_PATCH_LL_PROTECT
7527+ current->canary = 0;
7528+#endif
7529 break;
7530 }
7531 current = next;
7532@@ -108,7 +168,14 @@
7533 {
7534 zend_llist_element *current=l->head, *next;
7535
7536+#if HARDENING_PATCH_LL_PROTECT
7537+ TSRMLS_FETCH();
7538+ CHECK_LIST_CANARY(l)
7539+#endif
7540 while (current) {
7541+#if HARDENING_PATCH_LL_PROTECT
7542+ CHECK_LISTELEMENT_CANARY(current, l)
7543+#endif
7544 next = current->next;
7545 if (l->dtor) {
7546 l->dtor(current->data);
7547@@ -133,7 +200,14 @@
7548 zend_llist_element *old_tail;
7549 void *data;
7550
7551+#if HARDENING_PATCH_LL_PROTECT
7552+ TSRMLS_FETCH();
7553+ CHECK_LIST_CANARY(l)
7554+#endif
7555 if ((old_tail = l->tail)) {
7556+#if HARDENING_PATCH_LL_PROTECT
7557+ CHECK_LISTELEMENT_CANARY(old_tail, l)
7558+#endif
7559 if (l->tail->prev) {
7560 l->tail->prev->next = NULL;
7561 }
7562@@ -159,9 +233,16 @@
7563 {
7564 zend_llist_element *ptr;
7565
7566+#if HARDENING_PATCH_LL_PROTECT
7567+ TSRMLS_FETCH();
7568+ CHECK_LIST_CANARY(src)
7569+#endif
7570 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7571 ptr = src->head;
7572 while (ptr) {
7573+#if HARDENING_PATCH_LL_PROTECT
7574+ CHECK_LISTELEMENT_CANARY(ptr, src)
7575+#endif
7576 zend_llist_add_element(dst, ptr->data);
7577 ptr = ptr->next;
7578 }
7579@@ -172,11 +253,21 @@
7580 {
7581 zend_llist_element *element, *next;
7582
7583+#if HARDENING_PATCH_LL_PROTECT
7584+ TSRMLS_FETCH();
7585+ CHECK_LIST_CANARY(l)
7586+#endif
7587 element=l->head;
7588 while (element) {
7589+#if HARDENING_PATCH_LL_PROTECT
7590+ CHECK_LISTELEMENT_CANARY(element, l)
7591+#endif
7592 next = element->next;
7593 if (func(element->data)) {
7594 DEL_LLIST_ELEMENT(element, l);
7595+#if HARDENING_PATCH_LL_PROTECT
7596+ element->canary = 0;
7597+#endif
7598 }
7599 element = next;
7600 }
7601@@ -187,7 +278,13 @@
7602 {
7603 zend_llist_element *element;
7604
7605+#if HARDENING_PATCH_LL_PROTECT
7606+ CHECK_LIST_CANARY(l)
7607+#endif
7608 for (element=l->head; element; element=element->next) {
7609+#if HARDENING_PATCH_LL_PROTECT
7610+ CHECK_LISTELEMENT_CANARY(element, l)
7611+#endif
7612 func(element->data TSRMLS_CC);
7613 }
7614 }
7615@@ -199,6 +296,9 @@
7616 zend_llist_element **elements;
7617 zend_llist_element *element, **ptr;
7618
7619+#if HARDENING_PATCH_LL_PROTECT
7620+ CHECK_LIST_CANARY(l)
7621+#endif
7622 if (l->count <= 0) {
7623 return;
7624 }
7625@@ -208,6 +308,9 @@
7626 ptr = &elements[0];
7627
7628 for (element=l->head; element; element=element->next) {
7629+#if HARDENING_PATCH_LL_PROTECT
7630+ CHECK_LISTELEMENT_CANARY(element, l)
7631+#endif
7632 *ptr++ = element;
7633 }
7634
7635@@ -230,7 +333,13 @@
7636 {
7637 zend_llist_element *element;
7638
7639+#if HARDENING_PATCH_LL_PROTECT
7640+ CHECK_LIST_CANARY(l)
7641+#endif
7642 for (element=l->head; element; element=element->next) {
7643+#if HARDENING_PATCH_LL_PROTECT
7644+ CHECK_LISTELEMENT_CANARY(element, l)
7645+#endif
7646 func(element->data, arg TSRMLS_CC);
7647 }
7648 }
7649@@ -241,8 +350,14 @@
7650 zend_llist_element *element;
7651 va_list args;
7652
7653+#if HARDENING_PATCH_LL_PROTECT
7654+ CHECK_LIST_CANARY(l)
7655+#endif
7656 va_start(args, num_args);
7657 for (element=l->head; element; element=element->next) {
7658+#if HARDENING_PATCH_LL_PROTECT
7659+ CHECK_LISTELEMENT_CANARY(element, l)
7660+#endif
7661 func(element->data, num_args, args TSRMLS_CC);
7662 }
7663 va_end(args);
7664@@ -251,6 +366,10 @@
7665
7666 ZEND_API int zend_llist_count(zend_llist *l)
7667 {
7668+#if HARDENING_PATCH_LL_PROTECT
7669+ TSRMLS_FETCH();
7670+ CHECK_LIST_CANARY(l)
7671+#endif
7672 return l->count;
7673 }
7674
7675@@ -259,8 +378,15 @@
7676 {
7677 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7678
7679+#if HARDENING_PATCH_LL_PROTECT
7680+ TSRMLS_FETCH();
7681+ CHECK_LIST_CANARY(l)
7682+#endif
7683 *current = l->head;
7684 if (*current) {
7685+#if HARDENING_PATCH_LL_PROTECT
7686+ CHECK_LISTELEMENT_CANARY(*current, l)
7687+#endif
7688 return (*current)->data;
7689 } else {
7690 return NULL;
7691@@ -272,8 +398,15 @@
7692 {
7693 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7694
7695+#if HARDENING_PATCH_LL_PROTECT
7696+ TSRMLS_FETCH();
7697+ CHECK_LIST_CANARY(l)
7698+#endif
7699 *current = l->tail;
7700 if (*current) {
7701+#if HARDENING_PATCH_LL_PROTECT
7702+ CHECK_LISTELEMENT_CANARY(*current, l)
7703+#endif
7704 return (*current)->data;
7705 } else {
7706 return NULL;
7707@@ -285,9 +418,19 @@
7708 {
7709 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7710
7711+#if HARDENING_PATCH_LL_PROTECT
7712+ TSRMLS_FETCH();
7713+ CHECK_LIST_CANARY(l)
7714+#endif
7715 if (*current) {
7716+#if HARDENING_PATCH_LL_PROTECT
7717+ CHECK_LISTELEMENT_CANARY(*current, l)
7718+#endif
7719 *current = (*current)->next;
7720 if (*current) {
7721+#if HARDENING_PATCH_LL_PROTECT
7722+ CHECK_LISTELEMENT_CANARY(*current, l)
7723+#endif
7724 return (*current)->data;
7725 }
7726 }
7727@@ -299,9 +442,19 @@
7728 {
7729 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7730
7731+#if HARDENING_PATCH_LL_PROTECT
7732+ TSRMLS_FETCH();
7733+ CHECK_LIST_CANARY(l)
7734+#endif
7735 if (*current) {
7736+#if HARDENING_PATCH_LL_PROTECT
7737+ CHECK_LISTELEMENT_CANARY(*current, l)
7738+#endif
7739 *current = (*current)->prev;
7740 if (*current) {
7741+#if HARDENING_PATCH_LL_PROTECT
7742+ CHECK_LISTELEMENT_CANARY(*current, l)
7743+#endif
7744 return (*current)->data;
7745 }
7746 }
7747diff -Nura php-5.1.4/Zend/zend_llist.h hardening-patch-5.1.4-0.4.11/Zend/zend_llist.h
7748--- php-5.1.4/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100
7749+++ hardening-patch-5.1.4-0.4.11/Zend/zend_llist.h 2006-05-13 15:39:35.000000000 +0200
7750@@ -23,6 +23,9 @@
7751 #define ZEND_LLIST_H
7752
7753 typedef struct _zend_llist_element {
7754+#if HARDENING_PATCH_LL_PROTECT
7755+ unsigned int canary, padding;
7756+#endif
7757 struct _zend_llist_element *next;
7758 struct _zend_llist_element *prev;
7759 char data[1]; /* Needs to always be last in the struct */
7760@@ -35,6 +38,9 @@
7761 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7762
7763 typedef struct _zend_llist {
7764+#if HARDENING_PATCH_LL_PROTECT
7765+ unsigned int canary_h; /* head */
7766+#endif
7767 zend_llist_element *head;
7768 zend_llist_element *tail;
7769 size_t count;
7770@@ -42,6 +48,9 @@
7771 llist_dtor_func_t dtor;
7772 unsigned char persistent;
7773 zend_llist_element *traverse_ptr;
7774+#if HARDENING_PATCH_LL_PROTECT
7775+ unsigned int canary_t; /* tail */
7776+#endif
7777 } zend_llist;
7778
7779 typedef zend_llist_element* zend_llist_position;
7780diff -Nura php-5.1.4/Zend/zend_modules.h hardening-patch-5.1.4-0.4.11/Zend/zend_modules.h
7781--- php-5.1.4/Zend/zend_modules.h 2006-04-06 23:10:45.000000000 +0200
7782+++ hardening-patch-5.1.4-0.4.11/Zend/zend_modules.h 2006-05-13 15:39:35.000000000 +0200
7783@@ -39,6 +39,7 @@
7784 extern struct _zend_arg_info fifth_arg_force_ref[6];
7785 extern struct _zend_arg_info all_args_by_ref[1];
7786
7787+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106
7788 #define ZEND_MODULE_API_NO 20050922
7789 #ifdef ZTS
7790 #define USING_ZTS 1
7791@@ -46,13 +47,13 @@
7792 #define USING_ZTS 0
7793 #endif
7794
7795-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7796+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7797 #define STANDARD_MODULE_HEADER \
7798 STANDARD_MODULE_HEADER_EX, NULL, NULL
7799 #define ZE2_STANDARD_MODULE_HEADER \
7800 STANDARD_MODULE_HEADER_EX, ini_entries, NULL
7801
7802-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
7803+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
7804
7805 #define STANDARD_MODULE_PROPERTIES \
7806 NULL, STANDARD_MODULE_PROPERTIES_EX
7807@@ -87,6 +88,7 @@
7808 unsigned char type;
7809 void *handle;
7810 int module_number;
7811+ unsigned int real_zend_api;
7812 };
7813
7814 #define MODULE_DEP_REQUIRED 1
7815diff -Nura php-5.1.4/Zend/zend_opcode.c hardening-patch-5.1.4-0.4.11/Zend/zend_opcode.c
7816--- php-5.1.4/Zend/zend_opcode.c 2006-04-10 14:26:53.000000000 +0200
7817+++ hardening-patch-5.1.4-0.4.11/Zend/zend_opcode.c 2006-05-13 15:39:35.000000000 +0200
7818@@ -98,6 +98,9 @@
7819 op_array->uses_this = 0;
7820
7821 op_array->start_op = NULL;
7822+#if HARDENING_PATCH
7823+ op_array->created_by_eval = 0;
7824+#endif
7825
7826 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
7827 }
7828diff -Nura php-5.1.4/Zend/zend_vm_def.h hardening-patch-5.1.4-0.4.11/Zend/zend_vm_def.h
7829--- php-5.1.4/Zend/zend_vm_def.h 2006-04-12 13:37:50.000000000 +0200
7830+++ hardening-patch-5.1.4-0.4.11/Zend/zend_vm_def.h 2006-05-13 15:39:35.000000000 +0200
7831@@ -1769,6 +1769,37 @@
7832 efree(lcname);
7833 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7834 }
7835+#if HARDENING_PATCH
7836+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7837+ if (HG(eval_whitelist) != NULL) {
7838+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7839+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7840+ efree(lcname);
7841+ zend_bailout();
7842+ }
7843+ } else if (HG(eval_blacklist) != NULL) {
7844+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7845+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7846+ efree(lcname);
7847+ zend_bailout();
7848+ }
7849+ }
7850+ }
7851+
7852+ if (HG(func_whitelist) != NULL) {
7853+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7854+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7855+ efree(lcname);
7856+ zend_bailout();
7857+ }
7858+ } else if (HG(func_blacklist) != NULL) {
7859+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7860+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7861+ efree(lcname);
7862+ zend_bailout();
7863+ }
7864+ }
7865+#endif
7866
7867 efree(lcname);
7868 if (OP2_TYPE != IS_CONST) {
7869@@ -1994,6 +2025,34 @@
7870 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7871 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7872 }
7873+#if HARDENING_PATCH
7874+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7875+ if (HG(eval_whitelist) != NULL) {
7876+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7877+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7878+ zend_bailout();
7879+ }
7880+ } else if (HG(eval_blacklist) != NULL) {
7881+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7882+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7883+ zend_bailout();
7884+ }
7885+ }
7886+ }
7887+
7888+ if (HG(func_whitelist) != NULL) {
7889+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7890+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7891+ zend_bailout();
7892+ }
7893+ } else if (HG(func_blacklist) != NULL) {
7894+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7895+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7896+ zend_bailout();
7897+ }
7898+ }
7899+#endif
7900+
7901 EX(object) = NULL;
7902
7903 FREE_OP1();
7904@@ -2709,7 +2768,12 @@
7905 int dummy = 1;
7906 zend_file_handle file_handle;
7907
7908- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
7909+#if HARDENING_PATCH_INC_PROTECT
7910+ if (zend_is_valid_include(inc_filename)
7911+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
7912+#else
7913+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
7914+#endif
7915
7916 if (!file_handle.opened_path) {
7917 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
7918@@ -2734,6 +2798,11 @@
7919 break;
7920 case ZEND_INCLUDE:
7921 case ZEND_REQUIRE:
7922+#if HARDENING_PATCH_INC_PROTECT
7923+ if (!zend_is_valid_include(inc_filename)) {
7924+ break;
7925+ }
7926+#endif
7927 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7928 break;
7929 case ZEND_EVAL: {
7930diff -Nura php-5.1.4/Zend/zend_vm_execute.h hardening-patch-5.1.4-0.4.11/Zend/zend_vm_execute.h
7931--- php-5.1.4/Zend/zend_vm_execute.h 2006-04-12 13:37:50.000000000 +0200
7932+++ hardening-patch-5.1.4-0.4.11/Zend/zend_vm_execute.h 2006-05-13 15:39:35.000000000 +0200
7933@@ -56,6 +56,16 @@
7934 EX(symbol_table) = EG(active_symbol_table);
7935 EX(prev_execute_data) = EG(current_execute_data);
7936 EG(current_execute_data) = &execute_data;
7937+#if HARDENING_PATCH
7938+ EX(execute_depth) = 0;
7939+
7940+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
7941+ EG(in_code_type) = ZEND_EVAL_CODE;
7942+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7943+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7944+ op_array->type = ZEND_EVAL_CODE;
7945+ }
7946+#endif
7947
7948 EG(in_execution) = 1;
7949 if (op_array->start_op) {
7950@@ -81,6 +91,18 @@
7951 */
7952 EX(function_state).function_symbol_table = NULL;
7953 #endif
7954+#if HARDENING_PATCH
7955+ if (EX(prev_execute_data) == NULL) {
7956+ EX(execute_depth) = 0;
7957+ } else {
7958+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7959+ }
7960+
7961+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7962+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7963+ zend_bailout();
7964+ }
7965+#endif
7966
7967 while (1) {
7968 #ifdef ZEND_WIN32
7969@@ -724,6 +746,37 @@
7970 efree(lcname);
7971 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7972 }
7973+#if HARDENING_PATCH
7974+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7975+ if (HG(eval_whitelist) != NULL) {
7976+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7977+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7978+ efree(lcname);
7979+ zend_bailout();
7980+ }
7981+ } else if (HG(eval_blacklist) != NULL) {
7982+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7983+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7984+ efree(lcname);
7985+ zend_bailout();
7986+ }
7987+ }
7988+ }
7989+
7990+ if (HG(func_whitelist) != NULL) {
7991+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7992+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7993+ efree(lcname);
7994+ zend_bailout();
7995+ }
7996+ } else if (HG(func_blacklist) != NULL) {
7997+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7998+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7999+ efree(lcname);
8000+ zend_bailout();
8001+ }
8002+ }
8003+#endif
8004
8005 efree(lcname);
8006 if (IS_CONST != IS_CONST) {
8007@@ -925,6 +978,37 @@
8008 efree(lcname);
8009 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8010 }
8011+#if HARDENING_PATCH
8012+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8013+ if (HG(eval_whitelist) != NULL) {
8014+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8015+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8016+ efree(lcname);
8017+ zend_bailout();
8018+ }
8019+ } else if (HG(eval_blacklist) != NULL) {
8020+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8021+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8022+ efree(lcname);
8023+ zend_bailout();
8024+ }
8025+ }
8026+ }
8027+
8028+ if (HG(func_whitelist) != NULL) {
8029+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8030+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8031+ efree(lcname);
8032+ zend_bailout();
8033+ }
8034+ } else if (HG(func_blacklist) != NULL) {
8035+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8036+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8037+ efree(lcname);
8038+ zend_bailout();
8039+ }
8040+ }
8041+#endif
8042
8043 efree(lcname);
8044 if (IS_TMP_VAR != IS_CONST) {
8045@@ -1083,6 +1167,37 @@
8046 efree(lcname);
8047 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8048 }
8049+#if HARDENING_PATCH
8050+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8051+ if (HG(eval_whitelist) != NULL) {
8052+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8053+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8054+ efree(lcname);
8055+ zend_bailout();
8056+ }
8057+ } else if (HG(eval_blacklist) != NULL) {
8058+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8059+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8060+ efree(lcname);
8061+ zend_bailout();
8062+ }
8063+ }
8064+ }
8065+
8066+ if (HG(func_whitelist) != NULL) {
8067+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8068+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8069+ efree(lcname);
8070+ zend_bailout();
8071+ }
8072+ } else if (HG(func_blacklist) != NULL) {
8073+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8074+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8075+ efree(lcname);
8076+ zend_bailout();
8077+ }
8078+ }
8079+#endif
8080
8081 efree(lcname);
8082 if (IS_VAR != IS_CONST) {
8083@@ -1330,6 +1445,37 @@
8084 efree(lcname);
8085 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
8086 }
8087+#if HARDENING_PATCH
8088+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8089+ if (HG(eval_whitelist) != NULL) {
8090+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
8091+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
8092+ efree(lcname);
8093+ zend_bailout();
8094+ }
8095+ } else if (HG(eval_blacklist) != NULL) {
8096+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
8097+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
8098+ efree(lcname);
8099+ zend_bailout();
8100+ }
8101+ }
8102+ }
8103+
8104+ if (HG(func_whitelist) != NULL) {
8105+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
8106+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
8107+ efree(lcname);
8108+ zend_bailout();
8109+ }
8110+ } else if (HG(func_blacklist) != NULL) {
8111+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8112+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8113+ efree(lcname);
8114+ zend_bailout();
8115+ }
8116+ }
8117+#endif
8118
8119 efree(lcname);
8120 if (IS_CV != IS_CONST) {
8121@@ -1635,6 +1781,34 @@
8122 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
8123 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
8124 }
8125+#if HARDENING_PATCH
8126+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8127+ if (HG(eval_whitelist) != NULL) {
8128+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8129+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
8130+ zend_bailout();
8131+ }
8132+ } else if (HG(eval_blacklist) != NULL) {
8133+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8134+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
8135+ zend_bailout();
8136+ }
8137+ }
8138+ }
8139+
8140+ if (HG(func_whitelist) != NULL) {
8141+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8142+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
8143+ zend_bailout();
8144+ }
8145+ } else if (HG(func_blacklist) != NULL) {
8146+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8147+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
8148+ zend_bailout();
8149+ }
8150+ }
8151+#endif
8152+
8153 EX(object) = NULL;
8154
8155 return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
8156@@ -1914,7 +2088,12 @@
8157 int dummy = 1;
8158 zend_file_handle file_handle;
8159
8160- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8161+#if HARDENING_PATCH_INC_PROTECT
8162+ if (zend_is_valid_include(inc_filename)
8163+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
8164+#else
8165+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8166+#endif
8167
8168 if (!file_handle.opened_path) {
8169 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
8170@@ -1939,6 +2118,11 @@
8171 break;
8172 case ZEND_INCLUDE:
8173 case ZEND_REQUIRE:
8174+#if HARDENING_PATCH_INC_PROTECT
8175+ if (!zend_is_valid_include(inc_filename)) {
8176+ break;
8177+ }
8178+#endif
8179 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
8180 break;
8181 case ZEND_EVAL: {
8182diff -Nura php-5.1.4/Zend/zend_vm_execute.skl hardening-patch-5.1.4-0.4.11/Zend/zend_vm_execute.skl
8183--- php-5.1.4/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100
8184+++ hardening-patch-5.1.4-0.4.11/Zend/zend_vm_execute.skl 2006-05-13 15:39:35.000000000 +0200
8185@@ -27,6 +27,16 @@
8186 EX(symbol_table) = EG(active_symbol_table);
8187 EX(prev_execute_data) = EG(current_execute_data);
8188 EG(current_execute_data) = &execute_data;
8189+#if HARDENING_PATCH
8190+ EX(execute_depth) = 0;
8191+
8192+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
8193+ EG(in_code_type) = ZEND_EVAL_CODE;
8194+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
8195+ EG(in_code_type) = ZEND_SANDBOX_CODE;
8196+ op_array->type = ZEND_EVAL_CODE;
8197+ }
8198+#endif
8199
8200 EG(in_execution) = 1;
8201 if (op_array->start_op) {
8202@@ -52,6 +62,18 @@
8203 */
8204 EX(function_state).function_symbol_table = NULL;
8205 #endif
8206+#if HARDENING_PATCH
8207+ if (EX(prev_execute_data) == NULL) {
8208+ EX(execute_depth) = 0;
8209+ } else {
8210+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
8211+ }
8212+
8213+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
8214+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
8215+ zend_bailout();
8216+ }
8217+#endif
8218
8219 while (1) {
8220 {%ZEND_VM_CONTINUE_LABEL%}