summaryrefslogtreecommitdiff
path: root/0.4.8
diff options
context:
space:
mode:
Diffstat (limited to '0.4.8')
-rw-r--r--0.4.8/hardening-patch-4.4.2-0.4.8.patch8085
-rw-r--r--0.4.8/hardening-patch-5.1.2-0.4.8.patch8108
2 files changed, 16193 insertions, 0 deletions
diff --git a/0.4.8/hardening-patch-4.4.2-0.4.8.patch b/0.4.8/hardening-patch-4.4.2-0.4.8.patch
new file mode 100644
index 0000000..5138176
--- /dev/null
+++ b/0.4.8/hardening-patch-4.4.2-0.4.8.patch
@@ -0,0 +1,8085 @@
1diff -Nura php-4.4.2/acinclude.m4 hardening-patch-4.4.2-0.4.8/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.8/acinclude.m4 2006-01-18 12:43:26.816222528 +0100
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/configure hardening-patch-4.4.2-0.4.8/configure
42--- php-4.4.2/configure 2006-01-12 19:24:23.000000000 +0100
43+++ hardening-patch-4.4.2-0.4.8/configure 2006-01-18 12:43:26.873213864 +0100
44@@ -402,6 +402,16 @@
45 ac_default_prefix=/usr/local
46 # Any additions from configure.in:
47 ac_help="$ac_help
48+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
49+ac_help="$ac_help
50+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
51+ac_help="$ac_help
52+ --disable-hardening-patch-inc-protect Disable include/require protection."
53+ac_help="$ac_help
54+ --disable-hardening-patch-fmt-protect Disable format string protection."
55+ac_help="$ac_help
56+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
57+ac_help="$ac_help
58
59 SAPI modules:
60 "
61@@ -854,6 +864,8 @@
62 ac_help="$ac_help
63 --disable-tokenizer Disable tokenizer support"
64 ac_help="$ac_help
65+ --disable-varfilter Disable Hardening-Patch's variable filter"
66+ac_help="$ac_help
67 --enable-wddx Enable WDDX support."
68 ac_help="$ac_help
69 --disable-xml Disable XML support using bundled expat lib"
70@@ -2942,6 +2954,157 @@
71
72
73
74+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
75+if test "${enable_hardening_patch_mm_protect+set}" = set; then
76+ enableval="$enable_hardening_patch_mm_protect"
77+
78+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
79+
80+else
81+
82+ DO_HARDENING_PATCH_MM_PROTECT=yes
83+
84+fi
85+
86+
87+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
88+if test "${enable_hardening_patch_ll_protect+set}" = set; then
89+ enableval="$enable_hardening_patch_ll_protect"
90+
91+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
92+
93+else
94+
95+ DO_HARDENING_PATCH_LL_PROTECT=yes
96+
97+fi
98+
99+
100+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
101+if test "${enable_hardening_patch_inc_protect+set}" = set; then
102+ enableval="$enable_hardening_patch_inc_protect"
103+
104+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
105+
106+else
107+
108+ DO_HARDENING_PATCH_INC_PROTECT=yes
109+
110+fi
111+
112+
113+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
114+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
115+ enableval="$enable_hardening_patch_fmt_protect"
116+
117+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
118+
119+else
120+
121+ DO_HARDENING_PATCH_FMT_PROTECT=yes
122+
123+fi
124+
125+
126+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
127+if test "${enable_hardening_patch_hash_protect+set}" = set; then
128+ enableval="$enable_hardening_patch_hash_protect"
129+
130+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
131+
132+else
133+
134+ DO_HARDENING_PATCH_HASH_PROTECT=yes
135+
136+fi
137+
138+
139+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
140+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
141+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
142+
143+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
144+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
145+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
146+
147+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
148+echo "configure:2733: checking whether to protect include/require statements" >&5
149+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
150+
151+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
152+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
153+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
154+
155+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
156+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
157+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
158+
159+
160+cat >> confdefs.h <<\EOF
161+#define HARDENING_PATCH 1
162+EOF
163+
164+
165+
166+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
167+ cat >> confdefs.h <<\EOF
168+#define HARDENING_PATCH_MM_PROTECT 1
169+EOF
170+
171+else
172+ cat >> confdefs.h <<\EOF
173+#define HARDENING_PATCH_MM_PROTECT 0
174+EOF
175+
176+fi
177+
178+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
179+ cat >> confdefs.h <<\EOF
180+#define HARDENING_PATCH_LL_PROTECT 1
181+EOF
182+
183+else
184+ cat >> confdefs.h <<\EOF
185+#define HARDENING_PATCH_LL_PROTECT 0
186+EOF
187+
188+fi
189+
190+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
191+ cat >> confdefs.h <<\EOF
192+#define HARDENING_PATCH_INC_PROTECT 1
193+EOF
194+
195+else
196+ cat >> confdefs.h <<\EOF
197+#define HARDENING_PATCH_INC_PROTECT 0
198+EOF
199+
200+fi
201+
202+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
203+ cat >> confdefs.h <<\EOF
204+#define HARDENING_PATCH_FMT_PROTECT 1
205+EOF
206+
207+else
208+ cat >> confdefs.h <<\EOF
209+#define HARDENING_PATCH_FMT_PROTECT 0
210+EOF
211+
212+fi
213+
214+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
215+ cat >> confdefs.h <<\EOF
216+#define HARDENING_PATCH_HASH_PROTECT 1
217+EOF
218+
219+else
220+ cat >> confdefs.h <<\EOF
221+#define HARDENING_PATCH_HASH_PROTECT 0
222+EOF
223+
224+fi
225
226
227
228@@ -16017,6 +16180,62 @@
229 fi
230
231
232+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
233+echo "configure:14928: checking whether realpath is broken" >&5
234+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
235+ echo $ac_n "(cached) $ac_c" 1>&6
236+else
237+
238+ if test "$cross_compiling" = yes; then
239+
240+ ac_cv_broken_realpath=no
241+
242+else
243+ cat > conftest.$ac_ext <<EOF
244+#line 14939 "configure"
245+#include "confdefs.h"
246+
247+main() {
248+ char buf[4096+1];
249+ buf[0] = 0;
250+ realpath("/etc/hosts/../passwd", buf);
251+ exit(strcmp(buf, "/etc/passwd")==0);
252+}
253+
254+EOF
255+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
256+then
257+
258+ ac_cv_broken_realpath=no
259+
260+else
261+ echo "configure: failed program was:" >&5
262+ cat conftest.$ac_ext >&5
263+ rm -fr conftest*
264+
265+ ac_cv_broken_realpath=yes
266+
267+fi
268+rm -fr conftest*
269+fi
270+
271+
272+fi
273+
274+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
275+ if test "$ac_cv_broken_realpath" = "yes"; then
276+ cat >> confdefs.h <<\EOF
277+#define PHP_BROKEN_REALPATH 1
278+EOF
279+
280+ else
281+ cat >> confdefs.h <<\EOF
282+#define PHP_BROKEN_REALPATH 0
283+EOF
284+
285+ fi
286+
287+
288 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
289 echo "configure:16022: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -86718,7 +86937,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -87420,7 +87639,7 @@
301 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
302 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
303 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
304- var_unserializer.c ftok.c aggregation.c sha1.c ; do
305+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -87475,7 +87694,7 @@
310 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
311 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
312 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
313- var_unserializer.c ftok.c aggregation.c sha1.c ; do
314+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -87601,7 +87820,7 @@
319 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
320 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
321 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
322- var_unserializer.c ftok.c aggregation.c sha1.c ; do
323+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -87653,7 +87872,7 @@
328 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
329 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
330 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
331- var_unserializer.c ftok.c aggregation.c sha1.c ; do
332+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -91124,6 +91343,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.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" ;;
428+ *.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" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
474+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(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)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.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" ;;
538+ *.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" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.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" ;;
581+ *.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" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -104088,7 +104566,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 streams.c network.c php_open_temporary_file.c php_logos.c \
606- output.c memory_streams.c user_streams.c; do
607+ output.c memory_streams.c user_streams.c hardening_patch.c; do
608
609 IFS=.
610 set $ac_src
611@@ -104273,7 +104751,7 @@
612 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
613 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
614 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
615- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
616+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-4.4.2/configure.in hardening-patch-4.4.2-0.4.8/configure.in
621--- php-4.4.2/configure.in 2006-01-12 18:52:29.000000000 +0100
622+++ hardening-patch-4.4.2-0.4.8/configure.in 2006-01-18 12:43:26.875213560 +0100
623@@ -247,7 +247,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -621,6 +621,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1260,7 +1261,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 streams.c network.c php_open_temporary_file.c php_logos.c \
644- output.c memory_streams.c user_streams.c)
645+ output.c memory_streams.c user_streams.c hardening_patch.c)
646 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
647 case $host_alias in
648 *netware*)
649@@ -1281,7 +1282,7 @@
650 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
654+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
658diff -Nura php-4.4.2/ext/curl/curl.c hardening-patch-4.4.2-0.4.8/ext/curl/curl.c
659--- php-4.4.2/ext/curl/curl.c 2006-01-05 19:03:18.000000000 +0100
660+++ hardening-patch-4.4.2-0.4.8/ext/curl/curl.c 2006-01-18 12:43:26.876213408 +0100
661@@ -111,7 +111,7 @@
662
663 #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
664 if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
665- strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
666+ strncasecmp(str, "file:", sizeof("file:") - 1) == 0) \
667 { \
668 php_url *tmp_url; \
669 \
670diff -Nura php-4.4.2/ext/fbsql/php_fbsql.c hardening-patch-4.4.2-0.4.8/ext/fbsql/php_fbsql.c
671--- php-4.4.2/ext/fbsql/php_fbsql.c 2006-01-01 14:46:52.000000000 +0100
672+++ hardening-patch-4.4.2-0.4.8/ext/fbsql/php_fbsql.c 2006-01-18 12:43:26.878213104 +0100
673@@ -1797,8 +1797,24 @@
674 }
675 else if (fbcmdErrorsFound(md))
676 {
677+#if HARDENING_PATCH
678+ char* query_copy;
679+ int i;
680+#endif
681 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
682 char* emg = fbcemdAllErrorMessages(emd);
683+#if HARDENING_PATCH
684+ query_copy=estrdup(query_copy);
685+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
686+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
687+ efree(query_copy);
688+ if (HG(hphp_sql_bailout_on_error)) {
689+ free(emg);
690+ fbcemdRelease(emd);
691+ result = 0;
692+ zend_bailout();
693+ }
694+#endif
695 if (FB_SQL_G(generateWarnings))
696 {
697 if (emg)
698diff -Nura php-4.4.2/ext/mbstring/mbstring.c hardening-patch-4.4.2-0.4.8/ext/mbstring/mbstring.c
699--- php-4.4.2/ext/mbstring/mbstring.c 2006-01-01 14:46:54.000000000 +0100
700+++ hardening-patch-4.4.2-0.4.8/ext/mbstring/mbstring.c 2006-01-18 12:43:26.884212192 +0100
701@@ -1488,6 +1488,7 @@
702 char *strtok_buf = NULL, **val_list;
703 zval *array_ptr = (zval *) arg;
704 int n, num, val_len, *len_list;
705+ unsigned int new_val_len;
706 enum mbfl_no_encoding from_encoding;
707 mbfl_string string, resvar, resval;
708 mbfl_encoding_detector *identd = NULL;
709@@ -1610,8 +1611,14 @@
710 val_len = len_list[n];
711 }
712 n++;
713- /* add variable to symbol table */
714- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
715+ /* we need val to be emalloc()ed */
716+ val = estrndup(val, val_len);
717+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
718+ /* add variable to symbol table */
719+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
720+ }
721+ efree(val);
722+
723 if (convd != NULL){
724 mbfl_string_clear(&resvar);
725 mbfl_string_clear(&resval);
726diff -Nura php-4.4.2/ext/mysql/php_mysql.c hardening-patch-4.4.2-0.4.8/ext/mysql/php_mysql.c
727--- php-4.4.2/ext/mysql/php_mysql.c 2006-01-01 14:46:55.000000000 +0100
728+++ hardening-patch-4.4.2-0.4.8/ext/mysql/php_mysql.c 2006-01-18 12:43:26.885212040 +0100
729@@ -1218,6 +1218,8 @@
730 {
731 php_mysql_conn *mysql;
732 MYSQL_RES *mysql_result;
733+ char *copy_query;
734+ int i;
735
736 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
737
738@@ -1268,6 +1270,13 @@
739 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
740 }
741 }
742+ copy_query = estrdup(Z_STRVAL_PP(query));
743+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
744+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
745+ efree(copy_query);
746+ if (HG(hphp_sql_bailout_on_error)) {
747+ zend_bailout();
748+ }
749 RETURN_FALSE;
750 }
751 #else
752@@ -1275,12 +1284,20 @@
753 /* check possible error */
754 if (MySG(trace_mode)){
755 if (mysql_errno(&mysql->conn)){
756- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
757+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
758 }
759 }
760+ copy_query = estrdup(Z_STRVAL_PP(query));
761+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
762+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
763+ efree(copy_query);
764+ if (HG(hphp_sql_bailout_on_error)) {
765+ zend_bailout();
766+ }
767 RETURN_FALSE;
768 }
769 #endif
770+
771 if(use_store == MYSQL_USE_RESULT) {
772 mysql_result=mysql_use_result(&mysql->conn);
773 } else {
774diff -Nura php-4.4.2/ext/pgsql/pgsql.c hardening-patch-4.4.2-0.4.8/ext/pgsql/pgsql.c
775--- php-4.4.2/ext/pgsql/pgsql.c 2006-01-01 14:46:56.000000000 +0100
776+++ hardening-patch-4.4.2-0.4.8/ext/pgsql/pgsql.c 2006-01-18 12:43:26.888211584 +0100
777@@ -1001,10 +1001,28 @@
778 case PGRES_EMPTY_QUERY:
779 case PGRES_BAD_RESPONSE:
780 case PGRES_NONFATAL_ERROR:
781- case PGRES_FATAL_ERROR:
782- PHP_PQ_ERROR("Query failed: %s", pgsql);
783- PQclear(pgsql_result);
784- RETURN_FALSE;
785+ case PGRES_FATAL_ERROR:
786+ {
787+#if HARDENING_PATCH
788+ int i;
789+ char *query_copy;
790+#endif
791+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
792+ PQclear(pgsql_result);
793+#if HARDENING_PATCH
794+ query_copy = estrdup(Z_STRVAL_PP(query));
795+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
796+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
797+ efree(query_copy);
798+ if (HG(hphp_sql_bailout_on_error)) {
799+ efree(msgbuf);
800+ zend_bailout();
801+ }
802+#endif
803+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
804+ efree(msgbuf);
805+ RETURN_FALSE;
806+ }
807 break;
808 case PGRES_COMMAND_OK: /* successful command that did not return rows */
809 default:
810diff -Nura php-4.4.2/ext/session/mod_files.c hardening-patch-4.4.2-0.4.8/ext/session/mod_files.c
811--- php-4.4.2/ext/session/mod_files.c 2006-01-01 14:46:56.000000000 +0100
812+++ hardening-patch-4.4.2-0.4.8/ext/session/mod_files.c 2006-01-18 12:43:26.888211584 +0100
813@@ -389,6 +389,34 @@
814 return SUCCESS;
815 }
816
817+PS_VALIDATE_SID_FUNC(files)
818+{
819+ char buf[MAXPATHLEN];
820+ int fd;
821+ PS_FILES_DATA;
822+
823+ if (!ps_files_valid_key(key)) {
824+ return FAILURE;
825+ }
826+
827+ if (!PS(use_strict_mode)) {
828+ return SUCCESS;
829+ }
830+
831+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
832+ return FAILURE;
833+ }
834+
835+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY, 0600);
836+
837+ if (fd != -1) {
838+ close(fd);
839+ return SUCCESS;
840+ }
841+
842+ return FAILURE;
843+}
844+
845 /*
846 * Local variables:
847 * tab-width: 4
848diff -Nura php-4.4.2/ext/session/mod_mm.c hardening-patch-4.4.2-0.4.8/ext/session/mod_mm.c
849--- php-4.4.2/ext/session/mod_mm.c 2006-01-01 14:46:56.000000000 +0100
850+++ hardening-patch-4.4.2-0.4.8/ext/session/mod_mm.c 2006-01-18 12:43:26.889211432 +0100
851@@ -425,6 +425,42 @@
852 return SUCCESS;
853 }
854
855+PS_VALIDATE_SID_FUNC(mm)
856+{
857+ PS_MM_DATA;
858+ ps_sd *sd;
859+ const char *p;
860+ char c;
861+ int ret = SUCCESS;
862+
863+ for (p = key; (c = *p); p++) {
864+ /* valid characters are a..z,A..Z,0..9 */
865+ if (!((c >= 'a' && c <= 'z')
866+ || (c >= 'A' && c <= 'Z')
867+ || (c >= '0' && c <= '9')
868+ || c == ','
869+ || c == '-')) {
870+ return FAILURE;
871+ }
872+ }
873+
874+ if (!PS(use_strict_mode)) {
875+ return SUCCESS;
876+ }
877+
878+ mm_lock(data->mm, MM_LOCK_RD);
879+
880+ sd = ps_sd_lookup(data, key, 0);
881+ if (sd) {
882+ mm_unlock(data->mm);
883+ return SUCCESS;
884+ }
885+
886+ mm_unlock(data->mm);
887+
888+ return FAILURE;
889+}
890+
891 #endif
892
893 /*
894diff -Nura php-4.4.2/ext/session/mod_user.c hardening-patch-4.4.2-0.4.8/ext/session/mod_user.c
895--- php-4.4.2/ext/session/mod_user.c 2006-01-01 14:46:56.000000000 +0100
896+++ hardening-patch-4.4.2-0.4.8/ext/session/mod_user.c 2006-01-18 12:43:26.889211432 +0100
897@@ -23,7 +23,7 @@
898 #include "mod_user.h"
899
900 ps_module ps_mod_user = {
901- PS_MOD(user)
902+ PS_MOD_SID(user)
903 };
904
905 #define SESS_ZVAL_LONG(val, a) \
906@@ -174,6 +174,83 @@
907 FINISH;
908 }
909
910+PS_CREATE_SID_FUNC(user)
911+{
912+ int i;
913+ char *val = NULL;
914+ zval *retval;
915+ ps_user *mdata = PS_GET_MOD_DATA();
916+
917+ if (!mdata)
918+ return estrndup("", 0);
919+
920+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
921+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
922+ }
923+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
924+
925+ if (retval) {
926+ if (Z_TYPE_P(retval) == IS_STRING) {
927+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
928+ } else {
929+ val = estrndup("", 0);
930+ }
931+ zval_ptr_dtor(&retval);
932+ } else {
933+ val = estrndup("", 0);
934+ }
935+
936+ return val;
937+}
938+
939+static int ps_user_valid_key(const char *key TSRMLS_DC)
940+{
941+ size_t len;
942+ const char *p;
943+ char c;
944+ int ret = SUCCESS;
945+
946+ for (p = key; (c = *p); p++) {
947+ /* valid characters are a..z,A..Z,0..9 */
948+ if (!((c >= 'a' && c <= 'z')
949+ || (c >= 'A' && c <= 'Z')
950+ || (c >= '0' && c <= '9')
951+ || c == ','
952+ || c == '-')) {
953+ ret = FAILURE;
954+ break;
955+ }
956+ }
957+
958+ len = p - key;
959+
960+ if (len == 0)
961+ ret = FAILURE;
962+
963+ return ret;
964+}
965+
966+PS_VALIDATE_SID_FUNC(user)
967+{
968+ zval *args[1];
969+ STDVARS;
970+
971+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
972+ return ps_user_valid_key(key TSRMLS_CC);
973+ }
974+ SESS_ZVAL_STRING(key, args[0]);
975+
976+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
977+
978+ if (retval) {
979+ convert_to_long(retval);
980+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
981+ zval_ptr_dtor(&retval);
982+ }
983+
984+ return ret;
985+}
986+
987 /*
988 * Local variables:
989 * tab-width: 4
990diff -Nura php-4.4.2/ext/session/mod_user.h hardening-patch-4.4.2-0.4.8/ext/session/mod_user.h
991--- php-4.4.2/ext/session/mod_user.h 2006-01-01 14:46:56.000000000 +0100
992+++ hardening-patch-4.4.2-0.4.8/ext/session/mod_user.h 2006-01-18 12:43:26.889211432 +0100
993@@ -22,7 +22,7 @@
994 #define MOD_USER_H
995
996 typedef union {
997- zval *names[6];
998+ zval *names[8];
999 struct {
1000 zval *ps_open;
1001 zval *ps_close;
1002@@ -30,6 +30,8 @@
1003 zval *ps_write;
1004 zval *ps_destroy;
1005 zval *ps_gc;
1006+ zval *ps_create;
1007+ zval *ps_validate;
1008 } name;
1009 } ps_user;
1010
1011diff -Nura php-4.4.2/ext/session/php_session.h hardening-patch-4.4.2-0.4.8/ext/session/php_session.h
1012--- php-4.4.2/ext/session/php_session.h 2006-01-01 14:46:56.000000000 +0100
1013+++ hardening-patch-4.4.2-0.4.8/ext/session/php_session.h 2006-01-18 12:43:26.890211280 +0100
1014@@ -23,7 +23,7 @@
1015
1016 #include "ext/standard/php_var.h"
1017
1018-#define PHP_SESSION_API 20020330
1019+#define PHP_SESSION_API 20051121
1020
1021 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
1022 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
1023@@ -32,6 +32,7 @@
1024 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
1025 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
1026 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
1027+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
1028
1029 /* default create id function */
1030 char *php_session_create_id(PS_CREATE_SID_ARGS);
1031@@ -45,6 +46,7 @@
1032 int (*s_destroy)(PS_DESTROY_ARGS);
1033 int (*s_gc)(PS_GC_ARGS);
1034 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
1035+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
1036 } ps_module;
1037
1038 #define PS_GET_MOD_DATA() *mod_data
1039@@ -57,6 +59,7 @@
1040 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
1041 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
1042 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
1043+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
1044
1045 #define PS_FUNCS(x) \
1046 PS_OPEN_FUNC(x); \
1047@@ -65,11 +68,12 @@
1048 PS_WRITE_FUNC(x); \
1049 PS_DESTROY_FUNC(x); \
1050 PS_GC_FUNC(x); \
1051- PS_CREATE_SID_FUNC(x)
1052+ PS_CREATE_SID_FUNC(x); \
1053+ PS_VALIDATE_SID_FUNC(x)
1054
1055 #define PS_MOD(x) \
1056 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1057- ps_delete_##x, ps_gc_##x, php_session_create_id
1058+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1059
1060 /* SID enabled module handler definitions */
1061 #define PS_FUNCS_SID(x) \
1062@@ -79,11 +83,12 @@
1063 PS_WRITE_FUNC(x); \
1064 PS_DESTROY_FUNC(x); \
1065 PS_GC_FUNC(x); \
1066- PS_CREATE_SID_FUNC(x)
1067+ PS_CREATE_SID_FUNC(x); \
1068+ PS_VALIDATE_SID(x)
1069
1070 #define PS_MOD_SID(x) \
1071 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1072- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1073+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1074
1075 typedef enum {
1076 php_session_disabled,
1077@@ -120,6 +125,7 @@
1078 zend_bool use_only_cookies;
1079 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1080 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1081+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1082 int send_cookie;
1083 int define_sid;
1084 } php_ps_globals;
1085diff -Nura php-4.4.2/ext/session/session.c hardening-patch-4.4.2-0.4.8/ext/session/session.c
1086--- php-4.4.2/ext/session/session.c 2006-01-01 14:46:56.000000000 +0100
1087+++ hardening-patch-4.4.2-0.4.8/ext/session/session.c 2006-01-18 12:43:26.891211128 +0100
1088@@ -155,6 +155,7 @@
1089 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1090 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1091 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1092+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1093 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1094 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1095 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateInt, entropy_length, php_ps_globals, ps_globals)
1096@@ -637,6 +638,15 @@
1097 return;
1098 }
1099
1100+ /* If there is an ID, use session module to verify it */
1101+ if (PS(id)) {
1102+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1103+ efree(PS(id));
1104+ PS(id) = NULL;
1105+ PS(send_cookie) = 1;
1106+ }
1107+ }
1108+
1109 /* If there is no ID, use session module to create one */
1110 if (!PS(id))
1111 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1112@@ -1256,22 +1266,31 @@
1113 }
1114 /* }}} */
1115
1116-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1117+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1118 Sets user-level functions */
1119 PHP_FUNCTION(session_set_save_handler)
1120 {
1121- zval **args[6];
1122- int i;
1123+ zval **args[8];
1124+ int i, numargs;
1125 ps_user *mdata;
1126 char *name;
1127
1128+ numargs = ZEND_NUM_ARGS();
1129+ args[6] = NULL;
1130+ args[7] = NULL;
1131+
1132+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1133+ WRONG_PARAM_COUNT;
1134 if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1135 WRONG_PARAM_COUNT;
1136
1137 if (PS(session_status) != php_session_none)
1138 RETURN_FALSE;
1139
1140- for (i = 0; i < 6; i++) {
1141+ for (i = 0; i < 8; i++) {
1142+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1143+ continue;
1144+ }
1145 if (!zend_is_callable(*args[i], 0, &name)) {
1146 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1147 efree(name);
1148@@ -1284,7 +1303,11 @@
1149
1150 mdata = emalloc(sizeof(*mdata));
1151
1152- for (i = 0; i < 6; i++) {
1153+ for (i = 0; i < 8; i++) {
1154+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1155+ mdata->names[i] = NULL;
1156+ continue;
1157+ }
1158 ZVAL_ADDREF(*args[i]);
1159 mdata->names[i] = *args[i];
1160 }
1161@@ -1345,8 +1368,20 @@
1162 Update the current session id with a newly generated one. */
1163 PHP_FUNCTION(session_regenerate_id)
1164 {
1165+ zend_bool del_ses = 0;
1166+
1167+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
1168+ WRONG_PARAM_COUNT;
1169+ }
1170+
1171 if (PS(session_status) == php_session_active) {
1172- if (PS(id)) efree(PS(id));
1173+ if (PS(id)) {
1174+ if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1175+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
1176+ RETURN_FALSE;
1177+ }
1178+ efree(PS(id));
1179+ }
1180
1181 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1182
1183diff -Nura php-4.4.2/ext/session/tests/014.phpt hardening-patch-4.4.2-0.4.8/ext/session/tests/014.phpt
1184--- php-4.4.2/ext/session/tests/014.phpt 2002-11-26 00:19:18.000000000 +0100
1185+++ hardening-patch-4.4.2-0.4.8/ext/session/tests/014.phpt 2006-01-18 12:43:26.892210976 +0100
1186@@ -5,6 +5,7 @@
1187 --INI--
1188 session.use_trans_sid=1
1189 session.use_cookies=0
1190+session.use_strict_mode=0
1191 session.cache_limiter=
1192 register_globals=1
1193 session.bug_compat_42=1
1194diff -Nura php-4.4.2/ext/session/tests/015.phpt hardening-patch-4.4.2-0.4.8/ext/session/tests/015.phpt
1195--- php-4.4.2/ext/session/tests/015.phpt 2002-11-26 00:19:19.000000000 +0100
1196+++ hardening-patch-4.4.2-0.4.8/ext/session/tests/015.phpt 2006-01-18 12:43:26.892210976 +0100
1197@@ -5,6 +5,7 @@
1198 --INI--
1199 session.use_trans_sid=1
1200 session.use_cookies=0
1201+session.use_strict_mode=0
1202 session.cache_limiter=
1203 arg_separator.output=&
1204 session.name=PHPSESSID
1205diff -Nura php-4.4.2/ext/session/tests/018.phpt hardening-patch-4.4.2-0.4.8/ext/session/tests/018.phpt
1206--- php-4.4.2/ext/session/tests/018.phpt 2002-11-26 00:19:19.000000000 +0100
1207+++ hardening-patch-4.4.2-0.4.8/ext/session/tests/018.phpt 2006-01-18 12:43:26.892210976 +0100
1208@@ -4,6 +4,7 @@
1209 <?php include('skipif.inc'); ?>
1210 --INI--
1211 session.use_cookies=0
1212+session.use_strict_mode=0
1213 session.cache_limiter=
1214 session.use_trans_sid=1
1215 session.name=PHPSESSID
1216diff -Nura php-4.4.2/ext/session/tests/020.phpt hardening-patch-4.4.2-0.4.8/ext/session/tests/020.phpt
1217--- php-4.4.2/ext/session/tests/020.phpt 2002-11-26 00:19:19.000000000 +0100
1218+++ hardening-patch-4.4.2-0.4.8/ext/session/tests/020.phpt 2006-01-18 12:43:26.893210824 +0100
1219@@ -4,6 +4,7 @@
1220 <?php include('skipif.inc'); ?>
1221 --INI--
1222 session.use_cookies=0
1223+session.use_strict_mode=0
1224 session.cache_limiter=
1225 session.use_trans_sid=1
1226 arg_separator.output=&amp;
1227diff -Nura php-4.4.2/ext/session/tests/021.phpt hardening-patch-4.4.2-0.4.8/ext/session/tests/021.phpt
1228--- php-4.4.2/ext/session/tests/021.phpt 2002-11-26 00:19:19.000000000 +0100
1229+++ hardening-patch-4.4.2-0.4.8/ext/session/tests/021.phpt 2006-01-18 12:43:26.893210824 +0100
1230@@ -4,6 +4,7 @@
1231 <?php include('skipif.inc'); ?>
1232 --INI--
1233 session.use_cookies=0
1234+session.use_strict_mode=0
1235 session.cache_limiter=
1236 session.use_trans_sid=1
1237 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1238diff -Nura php-4.4.2/ext/standard/array.c hardening-patch-4.4.2-0.4.8/ext/standard/array.c
1239--- php-4.4.2/ext/standard/array.c 2006-01-01 14:46:57.000000000 +0100
1240+++ hardening-patch-4.4.2-0.4.8/ext/standard/array.c 2006-01-18 12:43:26.895210520 +0100
1241@@ -1162,6 +1162,32 @@
1242 }
1243 }
1244 }
1245+
1246+ if (var_name[0] == 'H') {
1247+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1248+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1249+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1250+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1251+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1252+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1253+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1254+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1255+ return 0;
1256+ }
1257+ } else if (var_name[0] == '_') {
1258+ if ((strcmp(var_name, "_COOKIE")==0)||
1259+ (strcmp(var_name, "_ENV")==0)||
1260+ (strcmp(var_name, "_FILES")==0)||
1261+ (strcmp(var_name, "_GET")==0)||
1262+ (strcmp(var_name, "_POST")==0)||
1263+ (strcmp(var_name, "_REQUEST")==0)||
1264+ (strcmp(var_name, "_SESSION")==0)||
1265+ (strcmp(var_name, "_SERVER")==0)) {
1266+ return 0;
1267+ }
1268+ } else if (strcmp(var_name, "GLOBALS")==0) {
1269+ return 0;
1270+ }
1271
1272 return 1;
1273 }
1274diff -Nura php-4.4.2/ext/standard/basic_functions.c hardening-patch-4.4.2-0.4.8/ext/standard/basic_functions.c
1275--- php-4.4.2/ext/standard/basic_functions.c 2006-01-01 14:46:57.000000000 +0100
1276+++ hardening-patch-4.4.2-0.4.8/ext/standard/basic_functions.c 2006-01-18 12:43:26.898210064 +0100
1277@@ -107,12 +107,14 @@
1278 typedef struct _php_shutdown_function_entry {
1279 zval **arguments;
1280 int arg_count;
1281+ zend_bool created_by_eval;
1282 } php_shutdown_function_entry;
1283
1284 typedef struct _user_tick_function_entry {
1285 zval **arguments;
1286 int arg_count;
1287 int calling;
1288+ zend_bool created_by_eval;
1289 } user_tick_function_entry;
1290
1291 /* some prototypes for local functions */
1292@@ -295,6 +297,8 @@
1293 PHP_FE(get_html_translation_table, NULL)
1294 PHP_FE(sha1, NULL)
1295 PHP_FE(sha1_file, NULL)
1296+ PHP_FE(sha256, NULL)
1297+ PHP_FE(sha256_file, NULL)
1298 PHP_NAMED_FE(md5,php_if_md5, NULL)
1299 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1300 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1301@@ -676,7 +680,7 @@
1302 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1303
1304 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1305- PHP_FE(realpath, NULL)
1306+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1307 #endif
1308
1309 #ifdef HAVE_FNMATCH
1310@@ -2096,6 +2100,13 @@
1311 {
1312 zval retval;
1313 char *function_name = NULL;
1314+#if HARDENING_PATCH
1315+ zend_uint orig_code_type = EG(in_code_type);
1316+
1317+ if (shutdown_function_entry->created_by_eval) {
1318+ EG(in_code_type) = ZEND_EVAL_CODE;
1319+ }
1320+#endif
1321
1322 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1323 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1324@@ -2111,6 +2122,9 @@
1325 if (function_name) {
1326 efree(function_name);
1327 }
1328+#if HARDENING_PATCH
1329+ EG(in_code_type) = orig_code_type;
1330+#endif
1331 return 0;
1332 }
1333
1334@@ -2118,6 +2132,13 @@
1335 {
1336 zval retval;
1337 zval *function = tick_fe->arguments[0];
1338+#if HARDENING_PATCH
1339+ zend_uint orig_code_type = EG(in_code_type);
1340+
1341+ if (tick_fe->created_by_eval) {
1342+ EG(in_code_type) = ZEND_EVAL_CODE;
1343+ }
1344+#endif
1345
1346 /* Prevent reentrant calls to the same user ticks function */
1347 if (! tick_fe->calling) {
1348@@ -2149,6 +2170,9 @@
1349
1350 tick_fe->calling = 0;
1351 }
1352+#if HARDENING_PATCH
1353+ EG(in_code_type) = orig_code_type;
1354+#endif
1355 }
1356
1357 static void run_user_tick_functions(int tick_count)
1358@@ -2216,6 +2240,13 @@
1359 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1360 RETURN_FALSE;
1361 }
1362+#if HARDENING_PATCH
1363+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1364+ shutdown_function_entry.created_by_eval = 1;
1365+ } else {
1366+ shutdown_function_entry.created_by_eval = 0;
1367+ }
1368+#endif
1369
1370 /* Prevent entering of anything but valid callback (syntax check only!) */
1371 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
1372@@ -2753,6 +2784,13 @@
1373 }
1374
1375 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1376+#if HARDENING_PATCH
1377+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1378+ tick_fe.created_by_eval = 1;
1379+ } else {
1380+ tick_fe.created_by_eval = 0;
1381+ }
1382+#endif
1383
1384 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1385 RETURN_FALSE;
1386@@ -3050,6 +3088,35 @@
1387 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1388 }
1389
1390+ if (new_key[0] == 'H') {
1391+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1392+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1393+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1394+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1395+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1396+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1397+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1398+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1399+ efree(new_key);
1400+ return 0;
1401+ }
1402+ } else if (new_key[0] == '_') {
1403+ if ((strcmp(new_key, "_COOKIE")==0)||
1404+ (strcmp(new_key, "_ENV")==0)||
1405+ (strcmp(new_key, "_FILES")==0)||
1406+ (strcmp(new_key, "_GET")==0)||
1407+ (strcmp(new_key, "_POST")==0)||
1408+ (strcmp(new_key, "_REQUEST")==0)||
1409+ (strcmp(new_key, "_SESSION")==0)||
1410+ (strcmp(new_key, "_SERVER")==0)) {
1411+ efree(new_key);
1412+ return 0;
1413+ }
1414+ } else if (strcmp(new_key, "GLOBALS")==0) {
1415+ efree(new_key);
1416+ return 0;
1417+ }
1418+
1419 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1420 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1421
1422diff -Nura php-4.4.2/ext/standard/config.m4 hardening-patch-4.4.2-0.4.8/ext/standard/config.m4
1423--- php-4.4.2/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1424+++ hardening-patch-4.4.2-0.4.8/ext/standard/config.m4 2006-01-18 12:43:26.898210064 +0100
1425@@ -203,7 +203,7 @@
1426 if test "$ac_cv_crypt_blowfish" = "yes"; then
1427 ac_result=1
1428 else
1429- ac_result=0
1430+ ac_result=1
1431 fi
1432 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1433 ])
1434@@ -419,6 +419,6 @@
1435 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1436 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1437 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1438- var_unserializer.c ftok.c aggregation.c sha1.c )
1439+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1440
1441 PHP_ADD_MAKEFILE_FRAGMENT
1442diff -Nura php-4.4.2/ext/standard/crypt_blowfish.c hardening-patch-4.4.2-0.4.8/ext/standard/crypt_blowfish.c
1443--- php-4.4.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1444+++ hardening-patch-4.4.2-0.4.8/ext/standard/crypt_blowfish.c 2006-01-18 12:43:26.900209760 +0100
1445@@ -0,0 +1,748 @@
1446+/*
1447+ * This code comes from John the Ripper password cracker, with reentrant
1448+ * and crypt(3) interfaces added, but optimizations specific to password
1449+ * cracking removed.
1450+ *
1451+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1452+ * placed in the public domain.
1453+ *
1454+ * There's absolutely no warranty.
1455+ *
1456+ * It is my intent that you should be able to use this on your system,
1457+ * as a part of a software package, or anywhere else to improve security,
1458+ * ensure compatibility, or for any other purpose. I would appreciate
1459+ * it if you give credit where it is due and keep your modifications in
1460+ * the public domain as well, but I don't require that in order to let
1461+ * you place this code and any modifications you make under a license
1462+ * of your choice.
1463+ *
1464+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1465+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1466+ * ideas. The password hashing algorithm was designed by David Mazieres
1467+ * <dm at lcs.mit.edu>.
1468+ *
1469+ * There's a paper on the algorithm that explains its design decisions:
1470+ *
1471+ * http://www.usenix.org/events/usenix99/provos.html
1472+ *
1473+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1474+ * Blowfish library (I can't be sure if I would think of something if I
1475+ * hadn't seen his code).
1476+ */
1477+
1478+#include <string.h>
1479+
1480+#include <errno.h>
1481+#ifndef __set_errno
1482+#define __set_errno(val) errno = (val)
1483+#endif
1484+
1485+#undef __CONST
1486+#ifdef __GNUC__
1487+#define __CONST __const
1488+#else
1489+#define __CONST
1490+#endif
1491+
1492+#ifdef __i386__
1493+#define BF_ASM 0
1494+#define BF_SCALE 1
1495+#elif defined(__alpha__) || defined(__hppa__)
1496+#define BF_ASM 0
1497+#define BF_SCALE 1
1498+#else
1499+#define BF_ASM 0
1500+#define BF_SCALE 0
1501+#endif
1502+
1503+typedef unsigned int BF_word;
1504+
1505+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1506+#define BF_N 16
1507+
1508+typedef BF_word BF_key[BF_N + 2];
1509+
1510+typedef struct {
1511+ BF_word S[4][0x100];
1512+ BF_key P;
1513+} BF_ctx;
1514+
1515+/*
1516+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1517+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1518+ */
1519+static BF_word BF_magic_w[6] = {
1520+ 0x4F727068, 0x65616E42, 0x65686F6C,
1521+ 0x64657253, 0x63727944, 0x6F756274
1522+};
1523+
1524+/*
1525+ * P-box and S-box tables initialized with digits of Pi.
1526+ */
1527+static BF_ctx BF_init_state = {
1528+ {
1529+ {
1530+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1531+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1532+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1533+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1534+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1535+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1536+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1537+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1538+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1539+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1540+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1541+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1542+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1543+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1544+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1545+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1546+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1547+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1548+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1549+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1550+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1551+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1552+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1553+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1554+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1555+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1556+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1557+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1558+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1559+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1560+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1561+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1562+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1563+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1564+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1565+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1566+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1567+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1568+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1569+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1570+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1571+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1572+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1573+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1574+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1575+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1576+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1577+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1578+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1579+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1580+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1581+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1582+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1583+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1584+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1585+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1586+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1587+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1588+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1589+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1590+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1591+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1592+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1593+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1594+ }, {
1595+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1596+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1597+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1598+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1599+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1600+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1601+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1602+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1603+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1604+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1605+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1606+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1607+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1608+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1609+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1610+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1611+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1612+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1613+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1614+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1615+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1616+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1617+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1618+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1619+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1620+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1621+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1622+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1623+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1624+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1625+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1626+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1627+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1628+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1629+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1630+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1631+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1632+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1633+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1634+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1635+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1636+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1637+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1638+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1639+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1640+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1641+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1642+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1643+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1644+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1645+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1646+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1647+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1648+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1649+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1650+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1651+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1652+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1653+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1654+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1655+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1656+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1657+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1658+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1659+ }, {
1660+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1661+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1662+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1663+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1664+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1665+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1666+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1667+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1668+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1669+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1670+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1671+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1672+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1673+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1674+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1675+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1676+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1677+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1678+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1679+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1680+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1681+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1682+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1683+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1684+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1685+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1686+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1687+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1688+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1689+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1690+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1691+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1692+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1693+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1694+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1695+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1696+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1697+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1698+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1699+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1700+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1701+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1702+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1703+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1704+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1705+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1706+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1707+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1708+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1709+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1710+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1711+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1712+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1713+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1714+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1715+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1716+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1717+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1718+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1719+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1720+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1721+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1722+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1723+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1724+ }, {
1725+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1726+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1727+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1728+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1729+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1730+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1731+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1732+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1733+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1734+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1735+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1736+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1737+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1738+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1739+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1740+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1741+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1742+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1743+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1744+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1745+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1746+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1747+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1748+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1749+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1750+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1751+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1752+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1753+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1754+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1755+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1756+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1757+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1758+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1759+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1760+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1761+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1762+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1763+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1764+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1765+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1766+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1767+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1768+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1769+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1770+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1771+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1772+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1773+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1774+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1775+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1776+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1777+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1778+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1779+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1780+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1781+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1782+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1783+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1784+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1785+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1786+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1787+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1788+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1789+ }
1790+ }, {
1791+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1792+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1793+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1794+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1795+ 0x9216d5d9, 0x8979fb1b
1796+ }
1797+};
1798+
1799+static unsigned char BF_itoa64[64 + 1] =
1800+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1801+
1802+static unsigned char BF_atoi64[0x60] = {
1803+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1804+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1805+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1806+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1807+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1808+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1809+};
1810+
1811+/*
1812+ * This may be optimized out if built with function inlining and no BF_ASM.
1813+ */
1814+static void clean(void *data, int size)
1815+{
1816+#if BF_ASM
1817+ extern void _BF_clean(void *data);
1818+#endif
1819+ memset(data, 0, size);
1820+#if BF_ASM
1821+ _BF_clean(data);
1822+#endif
1823+}
1824+
1825+#define BF_safe_atoi64(dst, src) \
1826+{ \
1827+ tmp = (unsigned char)(src); \
1828+ if (tmp == '$') break; \
1829+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1830+ tmp = BF_atoi64[tmp]; \
1831+ if (tmp > 63) return -1; \
1832+ (dst) = tmp; \
1833+}
1834+
1835+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1836+{
1837+ unsigned char *dptr = (unsigned char *)dst;
1838+ unsigned char *end = dptr + size;
1839+ unsigned char *sptr = (unsigned char *)src;
1840+ unsigned int tmp, c1, c2, c3, c4;
1841+
1842+ do {
1843+ BF_safe_atoi64(c1, *sptr++);
1844+ BF_safe_atoi64(c2, *sptr++);
1845+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1846+ if (dptr >= end) break;
1847+
1848+ BF_safe_atoi64(c3, *sptr++);
1849+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1850+ if (dptr >= end) break;
1851+
1852+ BF_safe_atoi64(c4, *sptr++);
1853+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1854+ } while (dptr < end);
1855+
1856+ while (dptr < end)
1857+ *dptr++ = 0;
1858+
1859+ return 0;
1860+}
1861+
1862+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1863+{
1864+ unsigned char *sptr = (unsigned char *)src;
1865+ unsigned char *end = sptr + size;
1866+ unsigned char *dptr = (unsigned char *)dst;
1867+ unsigned int c1, c2;
1868+
1869+ do {
1870+ c1 = *sptr++;
1871+ *dptr++ = BF_itoa64[c1 >> 2];
1872+ c1 = (c1 & 0x03) << 4;
1873+ if (sptr >= end) {
1874+ *dptr++ = BF_itoa64[c1];
1875+ break;
1876+ }
1877+
1878+ c2 = *sptr++;
1879+ c1 |= c2 >> 4;
1880+ *dptr++ = BF_itoa64[c1];
1881+ c1 = (c2 & 0x0f) << 2;
1882+ if (sptr >= end) {
1883+ *dptr++ = BF_itoa64[c1];
1884+ break;
1885+ }
1886+
1887+ c2 = *sptr++;
1888+ c1 |= c2 >> 6;
1889+ *dptr++ = BF_itoa64[c1];
1890+ *dptr++ = BF_itoa64[c2 & 0x3f];
1891+ } while (sptr < end);
1892+}
1893+
1894+static void BF_swap(BF_word *x, int count)
1895+{
1896+ static int endianness_check = 1;
1897+ char *is_little_endian = (char *)&endianness_check;
1898+ BF_word tmp;
1899+
1900+ if (*is_little_endian)
1901+ do {
1902+ tmp = *x;
1903+ tmp = (tmp << 16) | (tmp >> 16);
1904+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1905+ } while (--count);
1906+}
1907+
1908+#if BF_SCALE
1909+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1910+#define BF_ROUND(L, R, N) \
1911+ tmp1 = L & 0xFF; \
1912+ tmp2 = L >> 8; \
1913+ tmp2 &= 0xFF; \
1914+ tmp3 = L >> 16; \
1915+ tmp3 &= 0xFF; \
1916+ tmp4 = L >> 24; \
1917+ tmp1 = data.ctx.S[3][tmp1]; \
1918+ tmp2 = data.ctx.S[2][tmp2]; \
1919+ tmp3 = data.ctx.S[1][tmp3]; \
1920+ tmp3 += data.ctx.S[0][tmp4]; \
1921+ tmp3 ^= tmp2; \
1922+ R ^= data.ctx.P[N + 1]; \
1923+ tmp3 += tmp1; \
1924+ R ^= tmp3;
1925+#else
1926+/* Architectures with no complicated addressing modes supported */
1927+#define BF_INDEX(S, i) \
1928+ (*((BF_word *)(((unsigned char *)S) + (i))))
1929+#define BF_ROUND(L, R, N) \
1930+ tmp1 = L & 0xFF; \
1931+ tmp1 <<= 2; \
1932+ tmp2 = L >> 6; \
1933+ tmp2 &= 0x3FC; \
1934+ tmp3 = L >> 14; \
1935+ tmp3 &= 0x3FC; \
1936+ tmp4 = L >> 22; \
1937+ tmp4 &= 0x3FC; \
1938+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1939+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1940+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1941+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1942+ tmp3 ^= tmp2; \
1943+ R ^= data.ctx.P[N + 1]; \
1944+ tmp3 += tmp1; \
1945+ R ^= tmp3;
1946+#endif
1947+
1948+/*
1949+ * Encrypt one block, BF_N is hardcoded here.
1950+ */
1951+#define BF_ENCRYPT \
1952+ L ^= data.ctx.P[0]; \
1953+ BF_ROUND(L, R, 0); \
1954+ BF_ROUND(R, L, 1); \
1955+ BF_ROUND(L, R, 2); \
1956+ BF_ROUND(R, L, 3); \
1957+ BF_ROUND(L, R, 4); \
1958+ BF_ROUND(R, L, 5); \
1959+ BF_ROUND(L, R, 6); \
1960+ BF_ROUND(R, L, 7); \
1961+ BF_ROUND(L, R, 8); \
1962+ BF_ROUND(R, L, 9); \
1963+ BF_ROUND(L, R, 10); \
1964+ BF_ROUND(R, L, 11); \
1965+ BF_ROUND(L, R, 12); \
1966+ BF_ROUND(R, L, 13); \
1967+ BF_ROUND(L, R, 14); \
1968+ BF_ROUND(R, L, 15); \
1969+ tmp4 = R; \
1970+ R = L; \
1971+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1972+
1973+#if BF_ASM
1974+#define BF_body() \
1975+ _BF_body_r(&data.ctx);
1976+#else
1977+#define BF_body() \
1978+ L = R = 0; \
1979+ ptr = data.ctx.P; \
1980+ do { \
1981+ ptr += 2; \
1982+ BF_ENCRYPT; \
1983+ *(ptr - 2) = L; \
1984+ *(ptr - 1) = R; \
1985+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1986+\
1987+ ptr = data.ctx.S[0]; \
1988+ do { \
1989+ ptr += 2; \
1990+ BF_ENCRYPT; \
1991+ *(ptr - 2) = L; \
1992+ *(ptr - 1) = R; \
1993+ } while (ptr < &data.ctx.S[3][0xFF]);
1994+#endif
1995+
1996+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1997+{
1998+ __CONST char *ptr = key;
1999+ int i, j;
2000+ BF_word tmp;
2001+
2002+ for (i = 0; i < BF_N + 2; i++) {
2003+ tmp = 0;
2004+ for (j = 0; j < 4; j++) {
2005+ tmp <<= 8;
2006+ tmp |= *ptr;
2007+
2008+ if (!*ptr) ptr = key; else ptr++;
2009+ }
2010+
2011+ expanded[i] = tmp;
2012+ initial[i] = BF_init_state.P[i] ^ tmp;
2013+ }
2014+}
2015+
2016+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2017+ char *output, int size)
2018+{
2019+#if BF_ASM
2020+ extern void _BF_body_r(BF_ctx *ctx);
2021+#endif
2022+ struct {
2023+ BF_ctx ctx;
2024+ BF_key expanded_key;
2025+ union {
2026+ BF_word salt[4];
2027+ BF_word output[6];
2028+ } binary;
2029+ } data;
2030+ BF_word L, R;
2031+ BF_word tmp1, tmp2, tmp3, tmp4;
2032+ BF_word *ptr;
2033+ BF_word count;
2034+ int i;
2035+
2036+ if (size < 7 + 22 + 31 + 1) {
2037+ __set_errno(ERANGE);
2038+ return NULL;
2039+ }
2040+
2041+ if (setting[0] != '$' ||
2042+ setting[1] != '2' ||
2043+ setting[2] != 'a' ||
2044+ setting[3] != '$' ||
2045+ setting[4] < '0' || setting[4] > '3' ||
2046+ setting[5] < '0' || setting[5] > '9' ||
2047+ setting[6] != '$') {
2048+ __set_errno(EINVAL);
2049+ return NULL;
2050+ }
2051+
2052+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2053+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2054+ clean(data.binary.salt, sizeof(data.binary.salt));
2055+ __set_errno(EINVAL);
2056+ return NULL;
2057+ }
2058+
2059+ BF_swap(data.binary.salt, 4);
2060+
2061+ BF_set_key(key, data.expanded_key, data.ctx.P);
2062+
2063+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2064+
2065+ L = R = 0;
2066+ for (i = 0; i < BF_N + 2; i += 2) {
2067+ L ^= data.binary.salt[i & 2];
2068+ R ^= data.binary.salt[(i & 2) + 1];
2069+ BF_ENCRYPT;
2070+ data.ctx.P[i] = L;
2071+ data.ctx.P[i + 1] = R;
2072+ }
2073+
2074+ ptr = data.ctx.S[0];
2075+ do {
2076+ ptr += 4;
2077+ L ^= data.binary.salt[(BF_N + 2) & 3];
2078+ R ^= data.binary.salt[(BF_N + 3) & 3];
2079+ BF_ENCRYPT;
2080+ *(ptr - 4) = L;
2081+ *(ptr - 3) = R;
2082+
2083+ L ^= data.binary.salt[(BF_N + 4) & 3];
2084+ R ^= data.binary.salt[(BF_N + 5) & 3];
2085+ BF_ENCRYPT;
2086+ *(ptr - 2) = L;
2087+ *(ptr - 1) = R;
2088+ } while (ptr < &data.ctx.S[3][0xFF]);
2089+
2090+ do {
2091+ data.ctx.P[0] ^= data.expanded_key[0];
2092+ data.ctx.P[1] ^= data.expanded_key[1];
2093+ data.ctx.P[2] ^= data.expanded_key[2];
2094+ data.ctx.P[3] ^= data.expanded_key[3];
2095+ data.ctx.P[4] ^= data.expanded_key[4];
2096+ data.ctx.P[5] ^= data.expanded_key[5];
2097+ data.ctx.P[6] ^= data.expanded_key[6];
2098+ data.ctx.P[7] ^= data.expanded_key[7];
2099+ data.ctx.P[8] ^= data.expanded_key[8];
2100+ data.ctx.P[9] ^= data.expanded_key[9];
2101+ data.ctx.P[10] ^= data.expanded_key[10];
2102+ data.ctx.P[11] ^= data.expanded_key[11];
2103+ data.ctx.P[12] ^= data.expanded_key[12];
2104+ data.ctx.P[13] ^= data.expanded_key[13];
2105+ data.ctx.P[14] ^= data.expanded_key[14];
2106+ data.ctx.P[15] ^= data.expanded_key[15];
2107+ data.ctx.P[16] ^= data.expanded_key[16];
2108+ data.ctx.P[17] ^= data.expanded_key[17];
2109+
2110+ BF_body();
2111+
2112+ tmp1 = data.binary.salt[0];
2113+ tmp2 = data.binary.salt[1];
2114+ tmp3 = data.binary.salt[2];
2115+ tmp4 = data.binary.salt[3];
2116+ data.ctx.P[0] ^= tmp1;
2117+ data.ctx.P[1] ^= tmp2;
2118+ data.ctx.P[2] ^= tmp3;
2119+ data.ctx.P[3] ^= tmp4;
2120+ data.ctx.P[4] ^= tmp1;
2121+ data.ctx.P[5] ^= tmp2;
2122+ data.ctx.P[6] ^= tmp3;
2123+ data.ctx.P[7] ^= tmp4;
2124+ data.ctx.P[8] ^= tmp1;
2125+ data.ctx.P[9] ^= tmp2;
2126+ data.ctx.P[10] ^= tmp3;
2127+ data.ctx.P[11] ^= tmp4;
2128+ data.ctx.P[12] ^= tmp1;
2129+ data.ctx.P[13] ^= tmp2;
2130+ data.ctx.P[14] ^= tmp3;
2131+ data.ctx.P[15] ^= tmp4;
2132+ data.ctx.P[16] ^= tmp1;
2133+ data.ctx.P[17] ^= tmp2;
2134+
2135+ BF_body();
2136+ } while (--count);
2137+
2138+ for (i = 0; i < 6; i += 2) {
2139+ L = BF_magic_w[i];
2140+ R = BF_magic_w[i + 1];
2141+
2142+ count = 64;
2143+ do {
2144+ BF_ENCRYPT;
2145+ } while (--count);
2146+
2147+ data.binary.output[i] = L;
2148+ data.binary.output[i + 1] = R;
2149+ }
2150+
2151+ memcpy(output, setting, 7 + 22 - 1);
2152+ output[7 + 22 - 1] = BF_itoa64[(int)
2153+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2154+
2155+/* This has to be bug-compatible with the original implementation, so
2156+ * only encode 23 of the 24 bytes. :-) */
2157+ BF_swap(data.binary.output, 6);
2158+ BF_encode(&output[7 + 22], data.binary.output, 23);
2159+ output[7 + 22 + 31] = '\0';
2160+
2161+/* Overwrite the most obvious sensitive data we have on the stack. Note
2162+ * that this does not guarantee there's no sensitive data left on the
2163+ * stack and/or in registers; I'm not aware of portable code that does. */
2164+ clean(&data, sizeof(data));
2165+
2166+ return output;
2167+}
2168+
2169+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2170+ __CONST char *input, int size, char *output, int output_size)
2171+{
2172+ if (size < 16 || output_size < 7 + 22 + 1 ||
2173+ (count && (count < 4 || count > 31))) {
2174+ if (output_size > 0) output[0] = '\0';
2175+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2176+ return NULL;
2177+ }
2178+
2179+ if (!count) count = 5;
2180+
2181+ output[0] = '$';
2182+ output[1] = '2';
2183+ output[2] = 'a';
2184+ output[3] = '$';
2185+ output[4] = '0' + count / 10;
2186+ output[5] = '0' + count % 10;
2187+ output[6] = '$';
2188+
2189+ BF_encode(&output[7], (BF_word *)input, 16);
2190+ output[7 + 22] = '\0';
2191+
2192+ return output;
2193+}
2194diff -Nura php-4.4.2/ext/standard/crypt.c hardening-patch-4.4.2-0.4.8/ext/standard/crypt.c
2195--- php-4.4.2/ext/standard/crypt.c 2006-01-01 14:46:57.000000000 +0100
2196+++ hardening-patch-4.4.2-0.4.8/ext/standard/crypt.c 2006-01-18 12:43:26.900209760 +0100
2197@@ -100,6 +100,8 @@
2198 return SUCCESS;
2199 }
2200
2201+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2202+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2203
2204 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2205
2206@@ -135,7 +137,14 @@
2207
2208 /* The automatic salt generation only covers standard DES and md5-crypt */
2209 if(!*salt) {
2210-#if PHP_MD5_CRYPT
2211+#if PHP_BLOWFISH_CRYPT
2212+ char randat[16];
2213+ int i;
2214+
2215+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2216+
2217+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2218+#elif PHP_MD5_CRYPT
2219 strcpy(salt, "$1$");
2220 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2221 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2222@@ -145,8 +154,24 @@
2223 salt[2] = '\0';
2224 #endif
2225 }
2226-
2227- RETVAL_STRING(crypt(str, salt), 1);
2228+
2229+ if (salt[0] == '$' &&
2230+ salt[1] == '2' &&
2231+ salt[2] == 'a' &&
2232+ salt[3] == '$' &&
2233+ salt[4] >= '0' && salt[4] <= '3' &&
2234+ salt[5] >= '0' && salt[5] <= '9' &&
2235+ salt[6] == '$') {
2236+
2237+ char output[PHP_MAX_SALT_LEN+1];
2238+
2239+ output[0] = 0;
2240+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2241+ RETVAL_STRING(output, 1);
2242+
2243+ } else {
2244+ RETVAL_STRING(crypt(str, salt), 1);
2245+ }
2246 }
2247 /* }}} */
2248 #endif
2249diff -Nura php-4.4.2/ext/standard/dl.c hardening-patch-4.4.2-0.4.8/ext/standard/dl.c
2250--- php-4.4.2/ext/standard/dl.c 2006-01-01 14:46:57.000000000 +0100
2251+++ hardening-patch-4.4.2-0.4.8/ext/standard/dl.c 2006-01-18 12:43:26.901209608 +0100
2252@@ -160,8 +160,35 @@
2253 RETURN_FALSE;
2254 }
2255 module_entry = get_module();
2256+
2257+ /* check if Hardening-Patch is installed */
2258+ if (module_entry->zend_api < 1000000000) {
2259+ php_error_docref(NULL TSRMLS_CC, error_type,
2260+ "%s: Unable to initialize module\n"
2261+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2262+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2263+ "These options need to match\n",
2264+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2265+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2266+ DL_UNLOAD(handle);
2267+ RETURN_FALSE;
2268+ }
2269+
2270+ /* check if correct Hardening-Patch is installed */
2271+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2272+ php_error_docref(NULL TSRMLS_CC, error_type,
2273+ "%s: Unable to initialize module\n"
2274+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2275+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2276+ "These options need to match\n",
2277+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2278+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2279+ DL_UNLOAD(handle);
2280+ RETURN_FALSE;
2281+ }
2282+
2283 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2284- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2285+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2286 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2287 struct pre_4_1_0_module_entry {
2288 char *name;
2289@@ -195,7 +222,7 @@
2290 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2291 } else {
2292 name = module_entry->name;
2293- zend_api = module_entry->zend_api;
2294+ zend_api = module_entry->real_zend_api;
2295 zend_debug = module_entry->zend_debug;
2296 zts = module_entry->zts;
2297 }
2298diff -Nura php-4.4.2/ext/standard/file.c hardening-patch-4.4.2-0.4.8/ext/standard/file.c
2299--- php-4.4.2/ext/standard/file.c 2006-01-01 14:46:57.000000000 +0100
2300+++ hardening-patch-4.4.2-0.4.8/ext/standard/file.c 2006-01-18 12:43:26.902209456 +0100
2301@@ -2522,7 +2522,7 @@
2302 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2303 /* {{{ proto string realpath(string path)
2304 Return the resolved path */
2305-PHP_FUNCTION(realpath)
2306+PHP_FUNCTION(real_path)
2307 {
2308 zval **path;
2309 char resolved_path_buff[MAXPATHLEN];
2310diff -Nura php-4.4.2/ext/standard/file.h hardening-patch-4.4.2-0.4.8/ext/standard/file.h
2311--- php-4.4.2/ext/standard/file.h 2006-01-01 14:46:57.000000000 +0100
2312+++ hardening-patch-4.4.2-0.4.8/ext/standard/file.h 2006-01-18 12:43:26.902209456 +0100
2313@@ -64,7 +64,7 @@
2314 PHP_FUNCTION(fd_set);
2315 PHP_FUNCTION(fd_isset);
2316 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2317-PHP_FUNCTION(realpath);
2318+PHP_FUNCTION(real_path);
2319 #endif
2320 #ifdef HAVE_FNMATCH
2321 PHP_FUNCTION(fnmatch);
2322diff -Nura php-4.4.2/ext/standard/head.c hardening-patch-4.4.2-0.4.8/ext/standard/head.c
2323--- php-4.4.2/ext/standard/head.c 2006-01-01 14:46:57.000000000 +0100
2324+++ hardening-patch-4.4.2-0.4.8/ext/standard/head.c 2006-01-18 12:43:26.903209304 +0100
2325@@ -44,7 +44,7 @@
2326 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2327 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2328 return;
2329-
2330+
2331 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2332 }
2333 /* }}} */
2334diff -Nura php-4.4.2/ext/standard/info.c hardening-patch-4.4.2-0.4.8/ext/standard/info.c
2335--- php-4.4.2/ext/standard/info.c 2006-01-01 14:46:57.000000000 +0100
2336+++ hardening-patch-4.4.2-0.4.8/ext/standard/info.c 2006-01-18 12:43:26.904209152 +0100
2337@@ -408,7 +408,7 @@
2338
2339 if (flag & PHP_INFO_GENERAL) {
2340 char *zend_version = get_zend_version();
2341- char temp_api[9];
2342+ char temp_api[11];
2343
2344 php_uname = php_get_uname('a');
2345
2346@@ -430,11 +430,22 @@
2347 }
2348 }
2349
2350+#if HARDENING_PATCH
2351+ if (!sapi_module.phpinfo_as_text) {
2352+ 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);
2353+ } else {
2354+ char temp_ver[40];
2355+
2356+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2357+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2358+ }
2359+#else
2360 if (!sapi_module.phpinfo_as_text) {
2361 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2362 } else {
2363 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2364 }
2365+#endif
2366 php_info_print_box_end();
2367 php_info_print_table_start();
2368 php_info_print_table_row(2, "System", php_uname );
2369diff -Nura php-4.4.2/ext/standard/php_standard.h hardening-patch-4.4.2-0.4.8/ext/standard/php_standard.h
2370--- php-4.4.2/ext/standard/php_standard.h 2006-01-01 14:46:58.000000000 +0100
2371+++ hardening-patch-4.4.2-0.4.8/ext/standard/php_standard.h 2006-01-18 12:43:26.904209152 +0100
2372@@ -28,6 +28,7 @@
2373 #include "php_mail.h"
2374 #include "md5.h"
2375 #include "sha1.h"
2376+#include "sha256.h"
2377 #include "html.h"
2378 #include "exec.h"
2379 #include "file.h"
2380diff -Nura php-4.4.2/ext/standard/sha256.c hardening-patch-4.4.2-0.4.8/ext/standard/sha256.c
2381--- php-4.4.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2382+++ hardening-patch-4.4.2-0.4.8/ext/standard/sha256.c 2006-01-18 12:43:26.905209000 +0100
2383@@ -0,0 +1,398 @@
2384+/*
2385+ +----------------------------------------------------------------------+
2386+ | PHP Version 5 |
2387+ +----------------------------------------------------------------------+
2388+ | Copyright (c) 1997-2004 The PHP Group |
2389+ +----------------------------------------------------------------------+
2390+ | This source file is subject to version 3.0 of the PHP license, |
2391+ | that is bundled with this package in the file LICENSE, and is |
2392+ | available through the world-wide-web at the following url: |
2393+ | http://www.php.net/license/3_0.txt. |
2394+ | If you did not receive a copy of the PHP license and are unable to |
2395+ | obtain it through the world-wide-web, please send a note to |
2396+ | license@php.net so we can mail you a copy immediately. |
2397+ +----------------------------------------------------------------------+
2398+ | Author: Stefan Esser <sesser@php.net> |
2399+ +----------------------------------------------------------------------+
2400+*/
2401+
2402+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2403+
2404+#include <stdio.h>
2405+#include "php.h"
2406+
2407+/* This code is heavily based on the PHP md5/sha1 implementations */
2408+
2409+#include "sha256.h"
2410+
2411+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2412+{
2413+ int i;
2414+
2415+ for (i = 0; i < 32; i++) {
2416+ sprintf(sha256str, "%02x", digest[i]);
2417+ sha256str += 2;
2418+ }
2419+
2420+ *sha256str = '\0';
2421+}
2422+
2423+/* {{{ proto string sha256(string str [, bool raw_output])
2424+ Calculate the sha256 hash of a string */
2425+PHP_FUNCTION(sha256)
2426+{
2427+ char *arg;
2428+ int arg_len;
2429+ zend_bool raw_output = 0;
2430+ char sha256str[65];
2431+ PHP_SHA256_CTX context;
2432+ unsigned char digest[32];
2433+
2434+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2435+ return;
2436+ }
2437+
2438+ sha256str[0] = '\0';
2439+ PHP_SHA256Init(&context);
2440+ PHP_SHA256Update(&context, arg, arg_len);
2441+ PHP_SHA256Final(digest, &context);
2442+ if (raw_output) {
2443+ RETURN_STRINGL(digest, 32, 1);
2444+ } else {
2445+ make_sha256_digest(sha256str, digest);
2446+ RETVAL_STRING(sha256str, 1);
2447+ }
2448+
2449+}
2450+
2451+/* }}} */
2452+
2453+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2454+ Calculate the sha256 hash of given filename */
2455+PHP_FUNCTION(sha256_file)
2456+{
2457+ char *arg;
2458+ int arg_len;
2459+ zend_bool raw_output = 0;
2460+ char sha256str[65];
2461+ unsigned char buf[1024];
2462+ unsigned char digest[32];
2463+ PHP_SHA256_CTX context;
2464+ int n;
2465+ FILE *fp;
2466+
2467+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2468+ return;
2469+ }
2470+
2471+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2472+ RETURN_FALSE;
2473+ }
2474+
2475+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2476+ RETURN_FALSE;
2477+ }
2478+
2479+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2480+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2481+ RETURN_FALSE;
2482+ }
2483+
2484+ PHP_SHA256Init(&context);
2485+
2486+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2487+ PHP_SHA256Update(&context, buf, n);
2488+ }
2489+
2490+ PHP_SHA256Final(digest, &context);
2491+
2492+ if (ferror(fp)) {
2493+ fclose(fp);
2494+ RETURN_FALSE;
2495+ }
2496+
2497+ fclose(fp);
2498+
2499+ if (raw_output) {
2500+ RETURN_STRINGL(digest, 32, 1);
2501+ } else {
2502+ make_sha256_digest(sha256str, digest);
2503+ RETVAL_STRING(sha256str, 1);
2504+ }
2505+}
2506+/* }}} */
2507+
2508+
2509+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2510+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2511+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2512+
2513+static unsigned char PADDING[64] =
2514+{
2515+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2516+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2517+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2518+};
2519+
2520+/* F, G, H and I are basic SHA256 functions.
2521+ */
2522+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2523+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2524+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2525+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2526+
2527+/* ROTATE_RIGHT rotates x right n bits.
2528+ */
2529+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2530+
2531+/* W[i]
2532+ */
2533+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2534+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2535+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2536+
2537+/* ROUND function of sha256
2538+ */
2539+
2540+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2541+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2542+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2543+ (d) += t1; \
2544+ }
2545+
2546+
2547+/* {{{ PHP_SHA256Init
2548+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2549+ */
2550+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2551+{
2552+ context->count[0] = context->count[1] = 0;
2553+ /* Load magic initialization constants.
2554+ */
2555+ context->state[0] = 0x6a09e667;
2556+ context->state[1] = 0xbb67ae85;
2557+ context->state[2] = 0x3c6ef372;
2558+ context->state[3] = 0xa54ff53a;
2559+ context->state[4] = 0x510e527f;
2560+ context->state[5] = 0x9b05688c;
2561+ context->state[6] = 0x1f83d9ab;
2562+ context->state[7] = 0x5be0cd19;
2563+}
2564+/* }}} */
2565+
2566+/* {{{ PHP_SHA256Update
2567+ SHA256 block update operation. Continues an SHA256 message-digest
2568+ operation, processing another message block, and updating the
2569+ context.
2570+ */
2571+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2572+ unsigned int inputLen)
2573+{
2574+ unsigned int i, index, partLen;
2575+
2576+ /* Compute number of bytes mod 64 */
2577+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2578+
2579+ /* Update number of bits */
2580+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2581+ < ((php_uint32) inputLen << 3))
2582+ context->count[1]++;
2583+ context->count[1] += ((php_uint32) inputLen >> 29);
2584+
2585+ partLen = 64 - index;
2586+
2587+ /* Transform as many times as possible.
2588+ */
2589+ if (inputLen >= partLen) {
2590+ memcpy
2591+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2592+ SHA256Transform(context->state, context->buffer);
2593+
2594+ for (i = partLen; i + 63 < inputLen; i += 64)
2595+ SHA256Transform(context->state, &input[i]);
2596+
2597+ index = 0;
2598+ } else
2599+ i = 0;
2600+
2601+ /* Buffer remaining input */
2602+ memcpy
2603+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2604+ inputLen - i);
2605+}
2606+/* }}} */
2607+
2608+/* {{{ PHP_SHA256Final
2609+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2610+ the message digest and zeroizing the context.
2611+ */
2612+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2613+{
2614+ unsigned char bits[8];
2615+ unsigned int index, padLen;
2616+
2617+ /* Save number of bits */
2618+ bits[7] = context->count[0] & 0xFF;
2619+ bits[6] = (context->count[0] >> 8) & 0xFF;
2620+ bits[5] = (context->count[0] >> 16) & 0xFF;
2621+ bits[4] = (context->count[0] >> 24) & 0xFF;
2622+ bits[3] = context->count[1] & 0xFF;
2623+ bits[2] = (context->count[1] >> 8) & 0xFF;
2624+ bits[1] = (context->count[1] >> 16) & 0xFF;
2625+ bits[0] = (context->count[1] >> 24) & 0xFF;
2626+
2627+ /* Pad out to 56 mod 64.
2628+ */
2629+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2630+ padLen = (index < 56) ? (56 - index) : (120 - index);
2631+ PHP_SHA256Update(context, PADDING, padLen);
2632+
2633+ /* Append length (before padding) */
2634+ PHP_SHA256Update(context, bits, 8);
2635+
2636+ /* Store state in digest */
2637+ SHA256Encode(digest, context->state, 32);
2638+
2639+ /* Zeroize sensitive information.
2640+ */
2641+ memset((unsigned char*) context, 0, sizeof(*context));
2642+}
2643+/* }}} */
2644+
2645+/* {{{ SHA256Transform
2646+ * SHA256 basic transformation. Transforms state based on block.
2647+ */
2648+static void SHA256Transform(state, block)
2649+php_uint32 state[8];
2650+const unsigned char block[64];
2651+{
2652+ php_uint32 a = state[0], b = state[1], c = state[2];
2653+ php_uint32 d = state[3], e = state[4], f = state[5];
2654+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2655+
2656+ SHA256Decode(x, block, 64);
2657+
2658+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2659+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2660+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2661+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2662+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2663+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2664+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2665+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2666+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2667+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2668+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2669+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2670+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2671+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2672+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2673+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2674+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2675+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2676+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2677+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2678+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2679+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2680+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2681+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2682+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2683+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2684+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2685+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2686+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2687+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2688+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2689+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2690+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2691+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2692+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2693+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2694+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2695+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2696+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2697+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2698+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2699+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2700+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2701+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2702+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2703+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2704+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2705+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2706+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2707+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2708+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2709+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2710+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2711+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2712+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2713+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2714+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2715+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2716+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2717+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2718+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2719+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2720+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2721+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2722+
2723+ state[0] += a;
2724+ state[1] += b;
2725+ state[2] += c;
2726+ state[3] += d;
2727+ state[4] += e;
2728+ state[5] += f;
2729+ state[6] += g;
2730+ state[7] += h;
2731+
2732+ /* Zeroize sensitive information. */
2733+ memset((unsigned char*) x, 0, sizeof(x));
2734+}
2735+/* }}} */
2736+
2737+/* {{{ SHA256Encode
2738+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2739+ a multiple of 4.
2740+ */
2741+static void SHA256Encode(output, input, len)
2742+unsigned char *output;
2743+php_uint32 *input;
2744+unsigned int len;
2745+{
2746+ unsigned int i, j;
2747+
2748+ for (i = 0, j = 0; j < len; i++, j += 4) {
2749+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2750+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2751+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2752+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2753+ }
2754+}
2755+/* }}} */
2756+
2757+/* {{{ SHA256Decode
2758+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2759+ a multiple of 4.
2760+ */
2761+static void SHA256Decode(output, input, len)
2762+php_uint32 *output;
2763+const unsigned char *input;
2764+unsigned int len;
2765+{
2766+ unsigned int i, j;
2767+
2768+ for (i = 0, j = 0; j < len; i++, j += 4)
2769+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2770+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2771+}
2772+/* }}} */
2773+
2774+/*
2775+ * Local variables:
2776+ * tab-width: 4
2777+ * c-basic-offset: 4
2778+ * End:
2779+ * vim600: sw=4 ts=4 fdm=marker
2780+ * vim<600: sw=4 ts=4
2781+ */
2782diff -Nura php-4.4.2/ext/standard/sha256.h hardening-patch-4.4.2-0.4.8/ext/standard/sha256.h
2783--- php-4.4.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2784+++ hardening-patch-4.4.2-0.4.8/ext/standard/sha256.h 2006-01-18 12:43:26.905209000 +0100
2785@@ -0,0 +1,40 @@
2786+/*
2787+ +----------------------------------------------------------------------+
2788+ | PHP Version 5 |
2789+ +----------------------------------------------------------------------+
2790+ | Copyright (c) 1997-2004 The PHP Group |
2791+ +----------------------------------------------------------------------+
2792+ | This source file is subject to version 3.0 of the PHP license, |
2793+ | that is bundled with this package in the file LICENSE, and is |
2794+ | available through the world-wide-web at the following url: |
2795+ | http://www.php.net/license/3_0.txt. |
2796+ | If you did not receive a copy of the PHP license and are unable to |
2797+ | obtain it through the world-wide-web, please send a note to |
2798+ | license@php.net so we can mail you a copy immediately. |
2799+ +----------------------------------------------------------------------+
2800+ | Author: Stefan Esser <sesser@php.net> |
2801+ +----------------------------------------------------------------------+
2802+*/
2803+
2804+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2805+
2806+#ifndef SHA256_H
2807+#define SHA256_H
2808+
2809+#include "ext/standard/basic_functions.h"
2810+
2811+/* SHA1 context. */
2812+typedef struct {
2813+ php_uint32 state[8]; /* state (ABCD) */
2814+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2815+ unsigned char buffer[64]; /* input buffer */
2816+} PHP_SHA256_CTX;
2817+
2818+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2819+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2820+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2821+
2822+PHP_FUNCTION(sha256);
2823+PHP_FUNCTION(sha256_file);
2824+
2825+#endif
2826diff -Nura php-4.4.2/ext/standard/syslog.c hardening-patch-4.4.2-0.4.8/ext/standard/syslog.c
2827--- php-4.4.2/ext/standard/syslog.c 2006-01-01 14:46:58.000000000 +0100
2828+++ hardening-patch-4.4.2-0.4.8/ext/standard/syslog.c 2006-01-18 12:43:26.905209000 +0100
2829@@ -42,6 +42,8 @@
2830 */
2831 PHP_MINIT_FUNCTION(syslog)
2832 {
2833+
2834+#if !HARDENING_PATCH
2835 /* error levels */
2836 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2837 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2838@@ -97,7 +99,7 @@
2839 /* AIX doesn't have LOG_PERROR */
2840 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2841 #endif
2842-
2843+#endif
2844 return SUCCESS;
2845 }
2846 /* }}} */
2847diff -Nura php-4.4.2/ext/varfilter/config.m4 hardening-patch-4.4.2-0.4.8/ext/varfilter/config.m4
2848--- php-4.4.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2849+++ hardening-patch-4.4.2-0.4.8/ext/varfilter/config.m4 2006-01-18 12:43:26.906208848 +0100
2850@@ -0,0 +1,11 @@
2851+dnl
2852+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2853+dnl
2854+
2855+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2856+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2857+
2858+if test "$PHP_VARFILTER" != "no"; then
2859+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2860+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2861+fi
2862diff -Nura php-4.4.2/ext/varfilter/CREDITS hardening-patch-4.4.2-0.4.8/ext/varfilter/CREDITS
2863--- php-4.4.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2864+++ hardening-patch-4.4.2-0.4.8/ext/varfilter/CREDITS 2006-01-18 12:43:26.906208848 +0100
2865@@ -0,0 +1,2 @@
2866+varfilter
2867+Stefan Esser
2868\ Kein Zeilenumbruch am Dateiende.
2869diff -Nura php-4.4.2/ext/varfilter/php_varfilter.h hardening-patch-4.4.2-0.4.8/ext/varfilter/php_varfilter.h
2870--- php-4.4.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2871+++ hardening-patch-4.4.2-0.4.8/ext/varfilter/php_varfilter.h 2006-01-18 12:43:26.907208696 +0100
2872@@ -0,0 +1,144 @@
2873+/*
2874+ +----------------------------------------------------------------------+
2875+ | Hardened-PHP Project's varfilter extension |
2876+ +----------------------------------------------------------------------+
2877+ | Copyright (c) 2004-2005 Stefan Esser |
2878+ +----------------------------------------------------------------------+
2879+ | This source file is subject to version 2.02 of the PHP license, |
2880+ | that is bundled with this package in the file LICENSE, and is |
2881+ | available at through the world-wide-web at |
2882+ | http://www.php.net/license/2_02.txt. |
2883+ | If you did not receive a copy of the PHP license and are unable to |
2884+ | obtain it through the world-wide-web, please send a note to |
2885+ | license@php.net so we can mail you a copy immediately. |
2886+ +----------------------------------------------------------------------+
2887+ | Author: Stefan Esser <sesser@hardened-php.net> |
2888+ +----------------------------------------------------------------------+
2889+
2890+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2891+*/
2892+
2893+#ifndef PHP_VARFILTER_H
2894+#define PHP_VARFILTER_H
2895+
2896+extern zend_module_entry varfilter_module_entry;
2897+#define phpext_varfilter_ptr &varfilter_module_entry
2898+
2899+#ifdef PHP_WIN32
2900+#define PHP_VARFILTER_API __declspec(dllexport)
2901+#else
2902+#define PHP_VARFILTER_API
2903+#endif
2904+
2905+#ifdef ZTS
2906+#include "TSRM.h"
2907+#endif
2908+
2909+#include "SAPI.h"
2910+
2911+#include "php_variables.h"
2912+
2913+#ifdef ZEND_ENGINE_2
2914+#define HASH_HTTP_GET_VARS 0x2095733f
2915+#define HASH_HTTP_POST_VARS 0xbfee1265
2916+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
2917+#define HASH_HTTP_ENV_VARS 0x1fe186a8
2918+#define HASH_HTTP_SERVER_VARS 0xc987afd6
2919+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
2920+#define HASH_HTTP_POST_FILES 0x98eb1ddc
2921+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
2922+#else
2923+#define HASH_HTTP_GET_VARS 0x8d8645bd
2924+#define HASH_HTTP_POST_VARS 0x7c699bf3
2925+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
2926+#define HASH_HTTP_ENV_VARS 0x84da3016
2927+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
2928+#define HASH_HTTP_SESSION_VARS 0x322906f5
2929+#define HASH_HTTP_POST_FILES 0xe4e4ce70
2930+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
2931+#endif
2932+
2933+PHP_MINIT_FUNCTION(varfilter);
2934+PHP_MSHUTDOWN_FUNCTION(varfilter);
2935+PHP_RINIT_FUNCTION(varfilter);
2936+PHP_RSHUTDOWN_FUNCTION(varfilter);
2937+PHP_MINFO_FUNCTION(varfilter);
2938+
2939+
2940+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2941+/* request variables */
2942+ long max_request_variables;
2943+ long cur_request_variables;
2944+ long max_varname_length;
2945+ long max_totalname_length;
2946+ long max_value_length;
2947+ long max_array_depth;
2948+ long max_array_index_length;
2949+ zend_bool disallow_nul;
2950+/* cookie variables */
2951+ long max_cookie_vars;
2952+ long cur_cookie_vars;
2953+ long max_cookie_name_length;
2954+ long max_cookie_totalname_length;
2955+ long max_cookie_value_length;
2956+ long max_cookie_array_depth;
2957+ long max_cookie_array_index_length;
2958+ zend_bool disallow_cookie_nul;
2959+/* get variables */
2960+ long max_get_vars;
2961+ long cur_get_vars;
2962+ long max_get_name_length;
2963+ long max_get_totalname_length;
2964+ long max_get_value_length;
2965+ long max_get_array_depth;
2966+ long max_get_array_index_length;
2967+ zend_bool disallow_get_nul;
2968+/* post variables */
2969+ long max_post_vars;
2970+ long cur_post_vars;
2971+ long max_post_name_length;
2972+ long max_post_totalname_length;
2973+ long max_post_value_length;
2974+ long max_post_array_depth;
2975+ long max_post_array_index_length;
2976+ zend_bool disallow_post_nul;
2977+/* fileupload */
2978+ long max_uploads;
2979+ long cur_uploads;
2980+ zend_bool disallow_elf_files;
2981+ char *verification_script;
2982+
2983+ zend_bool no_more_variables;
2984+ zend_bool no_more_get_variables;
2985+ zend_bool no_more_post_variables;
2986+ zend_bool no_more_cookie_variables;
2987+ zend_bool no_more_uploads;
2988+
2989+ZEND_END_MODULE_GLOBALS(varfilter)
2990+
2991+
2992+#ifdef ZTS
2993+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2994+#else
2995+#define VARFILTER_G(v) (varfilter_globals.v)
2996+#endif
2997+
2998+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2999+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3000+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3001+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3002+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3003+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3004+
3005+
3006+
3007+#endif /* PHP_VARFILTER_H */
3008+
3009+
3010+/*
3011+ * Local variables:
3012+ * tab-width: 4
3013+ * c-basic-offset: 4
3014+ * indent-tabs-mode: t
3015+ * End:
3016+ */
3017diff -Nura php-4.4.2/ext/varfilter/varfilter.c hardening-patch-4.4.2-0.4.8/ext/varfilter/varfilter.c
3018--- php-4.4.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3019+++ hardening-patch-4.4.2-0.4.8/ext/varfilter/varfilter.c 2006-01-18 12:43:26.908208544 +0100
3020@@ -0,0 +1,915 @@
3021+/*
3022+ +----------------------------------------------------------------------+
3023+ | Hardened-PHP Project's varfilter extension |
3024+ +----------------------------------------------------------------------+
3025+ | Copyright (c) 2004-2005 Stefan Esser |
3026+ +----------------------------------------------------------------------+
3027+ | This source file is subject to version 2.02 of the PHP license, |
3028+ | that is bundled with this package in the file LICENSE, and is |
3029+ | available at through the world-wide-web at |
3030+ | http://www.php.net/license/2_02.txt. |
3031+ | If you did not receive a copy of the PHP license and are unable to |
3032+ | obtain it through the world-wide-web, please send a note to |
3033+ | license@php.net so we can mail you a copy immediately. |
3034+ +----------------------------------------------------------------------+
3035+ | Author: Stefan Esser <sesser@hardened-php.net> |
3036+ +----------------------------------------------------------------------+
3037+
3038+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3039+*/
3040+
3041+#ifdef HAVE_CONFIG_H
3042+#include "config.h"
3043+#endif
3044+
3045+#include "php.h"
3046+#include "php_ini.h"
3047+#include "ext/standard/info.h"
3048+#include "php_varfilter.h"
3049+#include "hardening_patch.h"
3050+
3051+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3052+
3053+/* True global resources - no need for thread safety here */
3054+static int le_varfilter;
3055+
3056+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3057+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3058+static zend_bool hooked = 0;
3059+
3060+/* {{{ varfilter_module_entry
3061+ */
3062+zend_module_entry varfilter_module_entry = {
3063+#if ZEND_MODULE_API_NO >= 20010901
3064+ STANDARD_MODULE_HEADER,
3065+#endif
3066+ "varfilter",
3067+ NULL,
3068+ PHP_MINIT(varfilter),
3069+ PHP_MSHUTDOWN(varfilter),
3070+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3071+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3072+ PHP_MINFO(varfilter),
3073+#if ZEND_MODULE_API_NO >= 20010901
3074+ "0.4.8", /* Replace with version number for your extension */
3075+#endif
3076+ STANDARD_MODULE_PROPERTIES
3077+};
3078+/* }}} */
3079+
3080+#ifdef COMPILE_DL_VARFILTER
3081+ZEND_GET_MODULE(varfilter)
3082+#endif
3083+
3084+/* {{{ PHP_INI
3085+ */
3086+PHP_INI_BEGIN()
3087+ /* for backward compatibility */
3088+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3089+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3090+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3091+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3092+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3093+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3094+
3095+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3096+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3097+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3098+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3099+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3100+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3101+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3102+
3103+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3104+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3105+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3106+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3107+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3108+ 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)
3109+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3110+
3111+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3112+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3113+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3114+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3115+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3116+ 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)
3117+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3118+
3119+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3120+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3121+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3122+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3123+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3124+ 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)
3125+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3126+
3127+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3128+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3129+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3130+
3131+
3132+PHP_INI_END()
3133+/* }}} */
3134+
3135+/* {{{ php_varfilter_init_globals
3136+ */
3137+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3138+{
3139+ varfilter_globals->max_request_variables = 200;
3140+ varfilter_globals->max_varname_length = 64;
3141+ varfilter_globals->max_value_length = 10000;
3142+ varfilter_globals->max_array_depth = 100;
3143+ varfilter_globals->max_totalname_length = 256;
3144+ varfilter_globals->max_array_index_length = 64;
3145+ varfilter_globals->disallow_nul = 1;
3146+
3147+ varfilter_globals->max_cookie_vars = 100;
3148+ varfilter_globals->max_cookie_name_length = 64;
3149+ varfilter_globals->max_cookie_totalname_length = 256;
3150+ varfilter_globals->max_cookie_value_length = 10000;
3151+ varfilter_globals->max_cookie_array_depth = 100;
3152+ varfilter_globals->max_cookie_array_index_length = 64;
3153+ varfilter_globals->disallow_cookie_nul = 1;
3154+
3155+ varfilter_globals->max_get_vars = 100;
3156+ varfilter_globals->max_get_name_length = 64;
3157+ varfilter_globals->max_get_totalname_length = 256;
3158+ varfilter_globals->max_get_value_length = 512;
3159+ varfilter_globals->max_get_array_depth = 50;
3160+ varfilter_globals->max_get_array_index_length = 64;
3161+ varfilter_globals->disallow_get_nul = 1;
3162+
3163+ varfilter_globals->max_post_vars = 200;
3164+ varfilter_globals->max_post_name_length = 64;
3165+ varfilter_globals->max_post_totalname_length = 256;
3166+ varfilter_globals->max_post_value_length = 65000;
3167+ varfilter_globals->max_post_array_depth = 100;
3168+ varfilter_globals->max_post_array_index_length = 64;
3169+ varfilter_globals->disallow_post_nul = 1;
3170+
3171+ varfilter_globals->max_uploads = 25;
3172+ varfilter_globals->disallow_elf_files = 1;
3173+ varfilter_globals->verification_script = NULL;
3174+
3175+ varfilter_globals->no_more_variables = 0;
3176+ varfilter_globals->no_more_get_variables = 0;
3177+ varfilter_globals->no_more_post_variables = 0;
3178+ varfilter_globals->no_more_cookie_variables = 0;
3179+ varfilter_globals->no_more_uploads = 0;
3180+
3181+ varfilter_globals->cur_request_variables = 0;
3182+ varfilter_globals->cur_get_vars = 0;
3183+ varfilter_globals->cur_post_vars = 0;
3184+ varfilter_globals->cur_cookie_vars = 0;
3185+
3186+ varfilter_globals->cur_uploads = 0;
3187+
3188+}
3189+/* }}} */
3190+
3191+
3192+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3193+{
3194+ HashTable *svars;
3195+ int retval, failure=0;
3196+
3197+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3198+
3199+ svars = Z_ARRVAL_P(track_vars_array);
3200+
3201+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3202+ if (retval == SUCCESS) failure = 1;
3203+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3204+ if (retval == SUCCESS) failure = 1;
3205+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3206+ if (retval == SUCCESS) failure = 1;
3207+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3208+ if (retval == SUCCESS) failure = 1;
3209+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3210+ if (retval == SUCCESS) failure = 1;
3211+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3212+ if (retval == SUCCESS) failure = 1;
3213+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3214+ if (retval == SUCCESS) failure = 1;
3215+ 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);
3216+ if (retval == SUCCESS) failure = 1;
3217+
3218+ if (failure) {
3219+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3220+ }
3221+}
3222+
3223+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3224+{
3225+ int retval = SAPI_HEADER_ADD, i;
3226+ char *tmp;
3227+
3228+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3229+
3230+ tmp = sapi_header->header;
3231+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3232+ if (tmp[0] == 0) {
3233+ char *fname = get_active_function_name(TSRMLS_C);
3234+
3235+ if (!fname) {
3236+ fname = "unknown";
3237+ }
3238+
3239+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3240+ sapi_header->header_len = i;
3241+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3242+ char *fname = get_active_function_name(TSRMLS_C);
3243+
3244+ if (!fname) {
3245+ fname = "unknown";
3246+ }
3247+
3248+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3249+ sapi_header->header_len = i;
3250+ tmp[0] = 0;
3251+ }
3252+ }
3253+ }
3254+
3255+ if (orig_header_handler) {
3256+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3257+ }
3258+
3259+ return retval;
3260+}
3261+
3262+/* {{{ PHP_MINIT_FUNCTION
3263+ */
3264+PHP_MINIT_FUNCTION(varfilter)
3265+{
3266+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3267+ REGISTER_INI_ENTRIES();
3268+
3269+ if (!hooked) {
3270+ void *temp;
3271+ hooked = 1;
3272+
3273+ temp = (void *)sapi_module.register_server_variables;
3274+ if (temp != varfilter_register_server_variables) {
3275+ orig_register_server_variables = temp;
3276+ }
3277+ temp = (void *)sapi_module.header_handler;
3278+ if (temp != varfilter_header_handler) {
3279+ orig_header_handler = temp;
3280+ }
3281+ }
3282+
3283+ sapi_register_input_filter(varfilter_input_filter);
3284+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3285+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3286+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3287+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3288+
3289+ sapi_module.header_handler = varfilter_header_handler;
3290+ sapi_module.register_server_variables = varfilter_register_server_variables;
3291+
3292+
3293+ return SUCCESS;
3294+}
3295+/* }}} */
3296+
3297+/* {{{ PHP_MSHUTDOWN_FUNCTION
3298+ */
3299+PHP_MSHUTDOWN_FUNCTION(varfilter)
3300+{
3301+ UNREGISTER_INI_ENTRIES();
3302+
3303+ return SUCCESS;
3304+}
3305+/* }}} */
3306+
3307+/* Remove if there's nothing to do at request start */
3308+/* {{{ PHP_RINIT_FUNCTION
3309+ */
3310+PHP_RINIT_FUNCTION(varfilter)
3311+{
3312+ VARFILTER_G(cur_request_variables) = 0;
3313+ VARFILTER_G(cur_get_vars) = 0;
3314+ VARFILTER_G(cur_post_vars) = 0;
3315+ VARFILTER_G(cur_cookie_vars) = 0;
3316+
3317+ VARFILTER_G(cur_uploads) = 0;
3318+
3319+ VARFILTER_G(no_more_variables) = 0;
3320+ VARFILTER_G(no_more_get_variables) = 0;
3321+ VARFILTER_G(no_more_post_variables) = 0;
3322+ VARFILTER_G(no_more_cookie_variables) = 0;
3323+ VARFILTER_G(no_more_uploads) = 0;
3324+
3325+ return SUCCESS;
3326+}
3327+/* }}} */
3328+
3329+/* Remove if there's nothing to do at request end */
3330+/* {{{ PHP_RSHUTDOWN_FUNCTION
3331+ */
3332+PHP_RSHUTDOWN_FUNCTION(varfilter)
3333+{
3334+ return SUCCESS;
3335+}
3336+/* }}} */
3337+
3338+/* {{{ PHP_MINFO_FUNCTION
3339+ */
3340+PHP_MINFO_FUNCTION(varfilter)
3341+{
3342+ php_info_print_table_start();
3343+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3344+ php_info_print_table_end();
3345+
3346+ DISPLAY_INI_ENTRIES();
3347+}
3348+/* }}} */
3349+
3350+/* {{{ normalize_varname
3351+ */
3352+static void normalize_varname(char *varname)
3353+{
3354+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3355+
3356+ /* overjump leading space */
3357+ while (*s == ' ') {
3358+ s++;
3359+ }
3360+
3361+ /* and remove it */
3362+ if (s != varname) {
3363+ memmove(varname, s, strlen(s)+1);
3364+ }
3365+
3366+ for (p=varname; *p && *p != '['; p++) {
3367+ switch(*p) {
3368+ case ' ':
3369+ case '.':
3370+ *p='_';
3371+ break;
3372+ }
3373+ }
3374+
3375+ /* find index */
3376+ index = strchr(varname, '[');
3377+ if (index) {
3378+ index++;
3379+ s=index;
3380+ } else {
3381+ return;
3382+ }
3383+
3384+ /* done? */
3385+ while (index) {
3386+
3387+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3388+ index++;
3389+ }
3390+ indexend = strchr(index, ']');
3391+ indexend = indexend ? indexend + 1 : index + strlen(index);
3392+
3393+ if (s != index) {
3394+ memmove(s, index, strlen(index)+1);
3395+ s += indexend-index;
3396+ } else {
3397+ s = indexend;
3398+ }
3399+
3400+ if (*s == '[') {
3401+ s++;
3402+ index = s;
3403+ } else {
3404+ index = NULL;
3405+ }
3406+ }
3407+ *s++='\0';
3408+}
3409+/* }}} */
3410+
3411+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3412+ */
3413+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3414+{
3415+ char *index, *prev_index = NULL, *var;
3416+ unsigned int var_len, total_len, depth = 0;
3417+
3418+ var = estrdup(varname);
3419+
3420+ /* Normalize the variable name */
3421+ normalize_varname(var);
3422+
3423+ /* Find length of variable name */
3424+ index = strchr(var, '[');
3425+ total_len = strlen(var);
3426+ var_len = index ? index-var : total_len;
3427+
3428+ /* Drop this variable if it exceeds the varname/total length limit */
3429+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3430+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3431+ goto return_failure;
3432+ }
3433+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3434+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3435+ goto return_failure;
3436+ }
3437+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3438+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3439+
3440+ goto return_failure;
3441+ }
3442+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3443+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3444+ goto return_failure;
3445+ }
3446+
3447+ /* Find out array depth */
3448+ while (index) {
3449+ unsigned int index_length;
3450+
3451+ depth++;
3452+ index = strchr(index+1, '[');
3453+
3454+ if (prev_index) {
3455+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3456+
3457+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3458+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3459+ goto return_failure;
3460+ }
3461+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3462+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3463+ goto return_failure;
3464+ }
3465+ prev_index = index;
3466+ }
3467+
3468+ }
3469+
3470+ /* Drop this variable if it exceeds the array depth limit */
3471+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3472+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3473+ goto return_failure;
3474+ }
3475+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3476+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3477+ goto return_failure;
3478+ }
3479+
3480+
3481+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3482+ /* This is to protect several silly scripts that do globalizing themself */
3483+
3484+ switch (var_len) {
3485+ case 18:
3486+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3487+ break;
3488+ case 17:
3489+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3490+ break;
3491+ case 16:
3492+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3493+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3494+ break;
3495+ case 15:
3496+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3497+ break;
3498+ case 14:
3499+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3500+ break;
3501+ case 13:
3502+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3503+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3504+ break;
3505+ case 8:
3506+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3507+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3508+ break;
3509+ case 7:
3510+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3511+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3512+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3513+ break;
3514+ case 6:
3515+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3516+ break;
3517+ case 5:
3518+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3519+ break;
3520+ case 4:
3521+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3522+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3523+ break;
3524+ }
3525+
3526+ efree(var);
3527+ return SUCCESS;
3528+protected_varname2:
3529+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3530+return_failure:
3531+ efree(var);
3532+ return FAILURE;
3533+}
3534+/* }}} */
3535+
3536+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3537+ */
3538+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3539+{
3540+ /* Drop if no more variables flag is set */
3541+ if (VARFILTER_G(no_more_uploads)) {
3542+ return FAILURE;
3543+ }
3544+ /* Drop this fileupload if the limit is reached */
3545+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3546+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3547+ VARFILTER_G(no_more_uploads) = 1;
3548+ return FAILURE;
3549+ }
3550+
3551+ return SUCCESS;
3552+}
3553+/* }}} */
3554+
3555+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3556+ */
3557+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3558+{
3559+
3560+ if (VARFILTER_G(disallow_elf_files)) {
3561+
3562+ if (offset == 0 && buffer_len > 10) {
3563+
3564+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3565+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3566+ return FAILURE;
3567+ }
3568+ }
3569+
3570+ }
3571+
3572+ return SUCCESS;
3573+}
3574+/* }}} */
3575+
3576+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3577+ */
3578+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3579+{
3580+ int retval = SUCCESS;
3581+
3582+ if (VARFILTER_G(verification_script)) {
3583+ char cmd[8192];
3584+ FILE *in;
3585+ int first=1;
3586+
3587+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3588+
3589+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3590+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3591+ return FAILURE;
3592+ }
3593+
3594+ retval = FAILURE;
3595+
3596+ /* read and forget the result */
3597+ while (1) {
3598+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3599+ if (readbytes<=0) {
3600+ break;
3601+ }
3602+ if (first) {
3603+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3604+ first = 0;
3605+ }
3606+ }
3607+ pclose(in);
3608+ }
3609+
3610+ if (retval != SUCCESS) {
3611+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3612+ return FAILURE;
3613+ }
3614+
3615+ VARFILTER_G(cur_uploads)++;
3616+ return SUCCESS;
3617+}
3618+/* }}} */
3619+
3620+/* {{{ SAPI_INPUT_FILTER_FUNC
3621+ */
3622+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3623+{
3624+ char *index, *prev_index = NULL;
3625+ unsigned int var_len, total_len, depth = 0;
3626+
3627+ /* Drop this variable if the limit was reached */
3628+ switch (arg) {
3629+ case PARSE_GET:
3630+ if (VARFILTER_G(no_more_get_variables)) {
3631+ return 0;
3632+ }
3633+ break;
3634+ case PARSE_POST:
3635+ if (VARFILTER_G(no_more_post_variables)) {
3636+ return 0;
3637+ }
3638+ break;
3639+ case PARSE_COOKIE:
3640+ if (VARFILTER_G(no_more_cookie_variables)) {
3641+ return 0;
3642+ }
3643+ break;
3644+ default: /* we do not want to protect parse_str() and friends */
3645+ if (new_val_len) {
3646+ *new_val_len = val_len;
3647+ }
3648+ return 1;
3649+ }
3650+ if (VARFILTER_G(no_more_variables)) {
3651+ return 0;
3652+ }
3653+
3654+ /* Drop this variable if the limit is now reached */
3655+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3656+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3657+ VARFILTER_G(no_more_variables) = 1;
3658+ return 0;
3659+ }
3660+ switch (arg) {
3661+ case PARSE_GET:
3662+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3663+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3664+ VARFILTER_G(no_more_get_variables) = 1;
3665+ return 0;
3666+ }
3667+ break;
3668+ case PARSE_COOKIE:
3669+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3670+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3671+ VARFILTER_G(no_more_cookie_variables) = 1;
3672+ return 0;
3673+ }
3674+ break;
3675+ case PARSE_POST:
3676+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3677+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3678+ VARFILTER_G(no_more_post_variables) = 1;
3679+ return 0;
3680+ }
3681+ break;
3682+ }
3683+
3684+
3685+ /* Drop this variable if it exceeds the value length limit */
3686+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3687+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3688+ return 0;
3689+ }
3690+ switch (arg) {
3691+ case PARSE_GET:
3692+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3693+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3694+ return 0;
3695+ }
3696+ break;
3697+ case PARSE_COOKIE:
3698+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3699+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3700+ return 0;
3701+ }
3702+ break;
3703+ case PARSE_POST:
3704+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3705+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3706+ return 0;
3707+ }
3708+ break;
3709+ }
3710+
3711+ /* Normalize the variable name */
3712+ normalize_varname(var);
3713+
3714+ /* Find length of variable name */
3715+ index = strchr(var, '[');
3716+ total_len = strlen(var);
3717+ var_len = index ? index-var : total_len;
3718+
3719+ /* Drop this variable if it exceeds the varname/total length limit */
3720+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3721+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3722+ return 0;
3723+ }
3724+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3725+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3726+ return 0;
3727+ }
3728+ switch (arg) {
3729+ case PARSE_GET:
3730+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3731+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3732+ return 0;
3733+ }
3734+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3735+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3736+ return 0;
3737+ }
3738+ break;
3739+ case PARSE_COOKIE:
3740+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3741+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3742+ return 0;
3743+ }
3744+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3745+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3746+ return 0;
3747+ }
3748+ break;
3749+ case PARSE_POST:
3750+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3751+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3752+ return 0;
3753+ }
3754+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3755+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3756+ return 0;
3757+ }
3758+ break;
3759+ }
3760+
3761+ /* Find out array depth */
3762+ while (index) {
3763+ unsigned int index_length;
3764+
3765+ depth++;
3766+ index = strchr(index+1, '[');
3767+
3768+ if (prev_index) {
3769+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3770+
3771+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3772+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3773+ return 0;
3774+ }
3775+ switch (arg) {
3776+ case PARSE_GET:
3777+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3778+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3779+ return 0;
3780+ }
3781+ break;
3782+ case PARSE_COOKIE:
3783+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3784+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3785+ return 0;
3786+ }
3787+ break;
3788+ case PARSE_POST:
3789+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3790+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3791+ return 0;
3792+ }
3793+ break;
3794+ }
3795+ prev_index = index;
3796+ }
3797+
3798+ }
3799+
3800+ /* Drop this variable if it exceeds the array depth limit */
3801+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3802+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3803+ return 0;
3804+ }
3805+ switch (arg) {
3806+ case PARSE_GET:
3807+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3808+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3809+ return 0;
3810+ }
3811+ break;
3812+ case PARSE_COOKIE:
3813+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3814+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3815+ return 0;
3816+ }
3817+ break;
3818+ case PARSE_POST:
3819+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3820+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3821+ return 0;
3822+ }
3823+ break;
3824+ }
3825+
3826+ /* Check if variable value is truncated by a \0 */
3827+
3828+ if (val && *val && val_len != strlen(*val)) {
3829+
3830+ if (VARFILTER_G(disallow_nul)) {
3831+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3832+ return 0;
3833+ }
3834+ switch (arg) {
3835+ case PARSE_GET:
3836+ if (VARFILTER_G(disallow_get_nul)) {
3837+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3838+ return 0;
3839+ }
3840+ break;
3841+ case PARSE_COOKIE:
3842+ if (VARFILTER_G(disallow_cookie_nul)) {
3843+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3844+ return 0;
3845+ }
3846+ break;
3847+ case PARSE_POST:
3848+ if (VARFILTER_G(disallow_post_nul)) {
3849+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3850+ return 0;
3851+ }
3852+ break;
3853+ }
3854+ }
3855+
3856+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3857+ /* This is to protect several silly scripts that do globalizing themself */
3858+
3859+ switch (var_len) {
3860+ case 18:
3861+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3862+ break;
3863+ case 17:
3864+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3865+ break;
3866+ case 16:
3867+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3868+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3869+ break;
3870+ case 15:
3871+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3872+ break;
3873+ case 14:
3874+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3875+ break;
3876+ case 13:
3877+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3878+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3879+ break;
3880+ case 8:
3881+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3882+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3883+ break;
3884+ case 7:
3885+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3886+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3887+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3888+ break;
3889+ case 6:
3890+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3891+ break;
3892+ case 5:
3893+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3894+ break;
3895+ case 4:
3896+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3897+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3898+ break;
3899+ }
3900+
3901+ /* Okay let PHP register this variable */
3902+ VARFILTER_G(cur_request_variables)++;
3903+ switch (arg) {
3904+ case PARSE_GET:
3905+ VARFILTER_G(cur_get_vars)++;
3906+ break;
3907+ case PARSE_COOKIE:
3908+ VARFILTER_G(cur_cookie_vars)++;
3909+ break;
3910+ case PARSE_POST:
3911+ VARFILTER_G(cur_post_vars)++;
3912+ break;
3913+ }
3914+
3915+ if (new_val_len) {
3916+ *new_val_len = val_len;
3917+ }
3918+
3919+ return 1;
3920+protected_varname:
3921+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3922+ return 0;
3923+}
3924+/* }}} */
3925+
3926+/*
3927+ * Local variables:
3928+ * tab-width: 4
3929+ * c-basic-offset: 4
3930+ * End:
3931+ * vim600: noet sw=4 ts=4 fdm=marker
3932+ * vim<600: noet sw=4 ts=4
3933+ */
3934+
3935+
3936diff -Nura php-4.4.2/main/fopen_wrappers.c hardening-patch-4.4.2-0.4.8/main/fopen_wrappers.c
3937--- php-4.4.2/main/fopen_wrappers.c 2006-01-01 14:46:59.000000000 +0100
3938+++ hardening-patch-4.4.2-0.4.8/main/fopen_wrappers.c 2006-01-18 12:43:26.909208392 +0100
3939@@ -156,6 +156,21 @@
3940 char *pathbuf;
3941 char *ptr;
3942 char *end;
3943+ char path_copy[MAXPATHLEN];
3944+ int path_len;
3945+
3946+ /* Special case path ends with a trailing slash */
3947+ path_len = strlen(path);
3948+ if (path_len >= MAXPATHLEN) {
3949+ errno = EPERM; /* we deny permission to open it */
3950+ return -1;
3951+ }
3952+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3953+ memcpy(path_copy, path, path_len+1);
3954+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3955+ path_copy[path_len] = '\0';
3956+ path = (const char *)&path_copy;
3957+ }
3958
3959 pathbuf = estrdup(PG(open_basedir));
3960
3961diff -Nura php-4.4.2/main/hardened_globals.h hardening-patch-4.4.2-0.4.8/main/hardened_globals.h
3962--- php-4.4.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3963+++ hardening-patch-4.4.2-0.4.8/main/hardened_globals.h 2006-01-18 12:43:26.909208392 +0100
3964@@ -0,0 +1,62 @@
3965+/*
3966+ +----------------------------------------------------------------------+
3967+ | Hardening-Patch for PHP |
3968+ +----------------------------------------------------------------------+
3969+ | Copyright (c) 2004-2005 Stefan Esser |
3970+ +----------------------------------------------------------------------+
3971+ | This source file is subject to version 2.02 of the PHP license, |
3972+ | that is bundled with this package in the file LICENSE, and is |
3973+ | available at through the world-wide-web at |
3974+ | http://www.php.net/license/2_02.txt. |
3975+ | If you did not receive a copy of the PHP license and are unable to |
3976+ | obtain it through the world-wide-web, please send a note to |
3977+ | license@php.net so we can mail you a copy immediately. |
3978+ +----------------------------------------------------------------------+
3979+ | Author: Stefan Esser <sesser@hardened-php.net> |
3980+ +----------------------------------------------------------------------+
3981+ */
3982+
3983+#ifndef HARDENED_GLOBALS_H
3984+#define HARDENED_GLOBALS_H
3985+
3986+typedef struct _hardened_globals hardened_globals_struct;
3987+
3988+#ifdef ZTS
3989+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3990+extern int hardened_globals_id;
3991+#else
3992+# define HG(v) (hardened_globals.v)
3993+extern struct _hardened_globals hardened_globals;
3994+#endif
3995+
3996+
3997+struct _hardened_globals {
3998+#if HARDENING_PATCH_MM_PROTECT
3999+ unsigned int canary_1;
4000+ unsigned int canary_2;
4001+#endif
4002+#if HARDENING_PATCH_LL_PROTECT
4003+ unsigned int canary_3;
4004+ unsigned int canary_4;
4005+ unsigned int ll_canary_inited;
4006+#endif
4007+ zend_bool hphp_sql_bailout_on_error;
4008+ zend_bool hphp_multiheader;
4009+ HashTable *eval_whitelist;
4010+ HashTable *eval_blacklist;
4011+ HashTable *func_whitelist;
4012+ HashTable *func_blacklist;
4013+ HashTable *include_whitelist;
4014+ HashTable *include_blacklist;
4015+ unsigned int dummy;
4016+};
4017+
4018+
4019+#endif /* HARDENED_GLOBALS_H */
4020+
4021+/*
4022+ * Local variables:
4023+ * tab-width: 4
4024+ * c-basic-offset: 4
4025+ * End:
4026+ */
4027diff -Nura php-4.4.2/main/hardening_patch.c hardening-patch-4.4.2-0.4.8/main/hardening_patch.c
4028--- php-4.4.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4029+++ hardening-patch-4.4.2-0.4.8/main/hardening_patch.c 2006-01-18 12:43:26.910208240 +0100
4030@@ -0,0 +1,430 @@
4031+/*
4032+ +----------------------------------------------------------------------+
4033+ | Hardening Patch for PHP |
4034+ +----------------------------------------------------------------------+
4035+ | Copyright (c) 2004-2005 Stefan Esser |
4036+ +----------------------------------------------------------------------+
4037+ | This source file is subject to version 2.02 of the PHP license, |
4038+ | that is bundled with this package in the file LICENSE, and is |
4039+ | available at through the world-wide-web at |
4040+ | http://www.php.net/license/2_02.txt. |
4041+ | If you did not receive a copy of the PHP license and are unable to |
4042+ | obtain it through the world-wide-web, please send a note to |
4043+ | license@php.net so we can mail you a copy immediately. |
4044+ +----------------------------------------------------------------------+
4045+ | Author: Stefan Esser <sesser@hardened-php.net> |
4046+ +----------------------------------------------------------------------+
4047+ */
4048+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4049+
4050+#include "php.h"
4051+
4052+#include <stdio.h>
4053+#include <stdlib.h>
4054+
4055+#if HAVE_UNISTD_H
4056+#include <unistd.h>
4057+#endif
4058+#include "SAPI.h"
4059+#include "php_globals.h"
4060+
4061+#if HARDENING_PATCH
4062+
4063+#ifdef HAVE_SYS_SOCKET_H
4064+#include <sys/socket.h>
4065+#endif
4066+
4067+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4068+#undef AF_UNIX
4069+#endif
4070+
4071+#if defined(AF_UNIX)
4072+#include <sys/un.h>
4073+#endif
4074+
4075+#define SYSLOG_PATH "/dev/log"
4076+
4077+#include "snprintf.h"
4078+
4079+#include "hardening_patch.h"
4080+
4081+#ifdef ZTS
4082+#include "hardened_globals.h"
4083+int hardened_globals_id;
4084+#else
4085+struct _hardened_globals hardened_globals;
4086+#endif
4087+
4088+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4089+{
4090+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4091+}
4092+
4093+
4094+PHPAPI void hardened_startup()
4095+{
4096+#ifdef ZTS
4097+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4098+#else
4099+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4100+#endif
4101+}
4102+
4103+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4104+{
4105+ HG(canary_1) = php_canary();
4106+ HG(canary_2) = php_canary();
4107+}
4108+
4109+char *loglevel2string(int loglevel)
4110+{
4111+ switch (loglevel) {
4112+ case S_FILES:
4113+ return "FILES";
4114+ case S_INCLUDE:
4115+ return "INCLUDE";
4116+ case S_MEMORY:
4117+ return "MEMORY";
4118+ case S_MISC:
4119+ return "MISC";
4120+ case S_SQL:
4121+ return "SQL";
4122+ case S_EXECUTOR:
4123+ return "EXECUTOR";
4124+ case S_VARS:
4125+ return "VARS";
4126+ default:
4127+ return "UNKNOWN";
4128+ }
4129+}
4130+
4131+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4132+{
4133+#if defined(AF_UNIX)
4134+ int s, r, i=0;
4135+ struct sockaddr_un saun;
4136+ char buf[4096+64];
4137+ char error[4096+100];
4138+ char *ip_address;
4139+ char *fname;
4140+ int lineno;
4141+ va_list ap;
4142+ TSRMLS_FETCH();
4143+
4144+ if (EG(hphp_log_use_x_forwarded_for)) {
4145+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4146+ if (ip_address == NULL) {
4147+ ip_address = "X-FORWARDED-FOR not set";
4148+ }
4149+ } else {
4150+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4151+ if (ip_address == NULL) {
4152+ ip_address = "REMOTE_ADDR not set";
4153+ }
4154+ }
4155+
4156+
4157+ va_start(ap, fmt);
4158+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4159+ va_end(ap);
4160+ while (error[i]) {
4161+ if (error[i] < 32) error[i] = '.';
4162+ i++;
4163+ }
4164+
4165+ if (zend_is_executing(TSRMLS_C)) {
4166+ lineno = zend_get_executed_lineno(TSRMLS_C);
4167+ fname = zend_get_executed_filename(TSRMLS_C);
4168+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4169+ } else {
4170+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4171+ if (fname==NULL) {
4172+ fname = "unknown";
4173+ }
4174+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4175+ }
4176+
4177+ /* Syslog-Logging disabled? */
4178+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4179+ goto log_sapi;
4180+ }
4181+
4182+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4183+
4184+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4185+ if (s == -1) {
4186+ goto log_sapi;
4187+ }
4188+
4189+ memset(&saun, 0, sizeof(saun));
4190+ saun.sun_family = AF_UNIX;
4191+ strcpy(saun.sun_path, SYSLOG_PATH);
4192+ /*saun.sun_len = sizeof(saun);*/
4193+
4194+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4195+ if (r) {
4196+ close(s);
4197+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4198+ if (s == -1) {
4199+ goto log_sapi;
4200+ }
4201+
4202+ memset(&saun, 0, sizeof(saun));
4203+ saun.sun_family = AF_UNIX;
4204+ strcpy(saun.sun_path, SYSLOG_PATH);
4205+ /*saun.sun_len = sizeof(saun);*/
4206+
4207+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4208+ if (r) {
4209+ close(s);
4210+ goto log_sapi;
4211+ }
4212+ }
4213+ send(s, error, strlen(error), 0);
4214+
4215+ close(s);
4216+
4217+log_sapi:
4218+ /* SAPI Logging activated? */
4219+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4220+ sapi_module.log_message(buf);
4221+ }
4222+
4223+log_script:
4224+ /* script logging activaed? */
4225+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4226+ char cmd[8192], *cmdpos, *bufpos;
4227+ FILE *in;
4228+ int space;
4229+
4230+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4231+ space = sizeof(cmd) - strlen(cmd);
4232+ cmdpos = cmd + strlen(cmd);
4233+ bufpos = buf;
4234+ if (space <= 1) return;
4235+ while (space > 2 && *bufpos) {
4236+ if (*bufpos == '\'') {
4237+ if (space<=5) break;
4238+ *cmdpos++ = '\'';
4239+ *cmdpos++ = '\\';
4240+ *cmdpos++ = '\'';
4241+ *cmdpos++ = '\'';
4242+ bufpos++;
4243+ space-=4;
4244+ } else {
4245+ *cmdpos++ = *bufpos++;
4246+ space--;
4247+ }
4248+ }
4249+ *cmdpos++ = '\'';
4250+ *cmdpos = 0;
4251+
4252+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4253+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4254+ return;
4255+ }
4256+ /* read and forget the result */
4257+ while (1) {
4258+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4259+ if (readbytes<=0) {
4260+ break;
4261+ }
4262+ }
4263+ pclose(in);
4264+ }
4265+
4266+#endif
4267+}
4268+#endif
4269+
4270+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4271+
4272+/* will be replaced later with more compatible method */
4273+PHPAPI unsigned int php_canary()
4274+{
4275+ time_t t;
4276+ unsigned int canary;
4277+ int fd;
4278+
4279+ fd = open("/dev/urandom", 0);
4280+ if (fd != -1) {
4281+ int r = read(fd, &canary, sizeof(canary));
4282+ close(fd);
4283+ if (r == sizeof(canary)) {
4284+ return (canary);
4285+ }
4286+ }
4287+ /* not good but we never want to do this */
4288+ time(&t);
4289+ canary = *(unsigned int *)&t + getpid() << 16;
4290+ return (canary);
4291+}
4292+#endif
4293+
4294+#if HARDENING_PATCH_INC_PROTECT
4295+
4296+PHPAPI int php_is_valid_include(zval *z)
4297+{
4298+ char *filename;
4299+ int len, i;
4300+ TSRMLS_FETCH();
4301+
4302+ /* must be of type string */
4303+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4304+ return (0);
4305+ }
4306+
4307+ /* short cut */
4308+ filename = z->value.str.val;
4309+ len = z->value.str.len;
4310+
4311+ /* 1. must be shorter than MAXPATHLEN */
4312+ if (len > MAXPATHLEN) {
4313+ char *fname = estrndup(filename, len);
4314+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4315+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4316+ efree(fname);
4317+ return (0);
4318+ }
4319+
4320+ /* 2. must not be cutted */
4321+ if (len != strlen(filename)) {
4322+ char *fname = estrndup(filename, len);
4323+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4324+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4325+ efree(fname);
4326+ return (0);
4327+ }
4328+
4329+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4330+ if (strstr(filename, "://")) {
4331+ char *fname = estrndup(filename, len);
4332+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4333+
4334+ /* no black or whitelist then disallow all */
4335+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4336+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4337+ efree(fname);
4338+ return (0);
4339+ }
4340+
4341+ /* whitelist is stronger than blacklist */
4342+ if (HG(include_whitelist)) {
4343+ char *s, *t, *h, *index;
4344+ uint indexlen;
4345+ ulong numindex;
4346+
4347+ s = filename;
4348+
4349+ do {
4350+ zend_bool isOk = 0;
4351+ int tlen;
4352+
4353+ t = h = strstr(s, "://");
4354+ if (h == NULL) break;
4355+
4356+
4357+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4358+ t--;
4359+ }
4360+
4361+ tlen = strlen(t);
4362+
4363+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4364+ do {
4365+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4366+
4367+ if (r==HASH_KEY_NON_EXISTANT) {
4368+ break;
4369+ }
4370+ if (r==HASH_KEY_IS_STRING) {
4371+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4372+ if (strncmp(t, index, indexlen-1)==0) {
4373+ isOk = 1;
4374+ break;
4375+ }
4376+ }
4377+ }
4378+
4379+ zend_hash_move_forward(HG(include_whitelist));
4380+ } while (1);
4381+
4382+ /* not found in whitelist */
4383+ if (!isOk) {
4384+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4385+ efree(fname);
4386+ return 0;
4387+ }
4388+
4389+ s = h + 3;
4390+ } while (1);
4391+ } else {
4392+ /* okay then handle the blacklist */
4393+ char *s, *t, *h, *index;
4394+ uint indexlen;
4395+ ulong numindex;
4396+
4397+ s = filename;
4398+
4399+ do {
4400+ int tlen;
4401+
4402+ t = h = strstr(s, "://");
4403+ if (h == NULL) break;
4404+
4405+
4406+ while (t > s) {
4407+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4408+ }
4409+
4410+ tlen = strlen(t);
4411+
4412+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4413+ do {
4414+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4415+
4416+ if (r==HASH_KEY_NON_EXISTANT) {
4417+ break;
4418+ }
4419+ if (r==HASH_KEY_IS_STRING) {
4420+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4421+ if (strncmp(t, index, indexlen-1)==0) {
4422+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4423+ efree(fname);
4424+ return 0;
4425+ }
4426+ }
4427+ }
4428+
4429+ zend_hash_move_forward(HG(include_blacklist));
4430+ } while (1);
4431+
4432+ s = h + 3;
4433+ } while (1);
4434+ }
4435+
4436+ efree(fname);
4437+ }
4438+
4439+ /* 4. must not be an uploaded file */
4440+ if (SG(rfc1867_uploaded_files)) {
4441+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4442+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4443+ return (0);
4444+ }
4445+ }
4446+
4447+ /* passed all tests */
4448+ return (1);
4449+}
4450+
4451+#endif
4452+
4453+/*
4454+ * Local variables:
4455+ * tab-width: 4
4456+ * c-basic-offset: 4
4457+ * End:
4458+ * vim600: sw=4 ts=4 fdm=marker
4459+ * vim<600: sw=4 ts=4
4460+ */
4461diff -Nura php-4.4.2/main/hardening_patch.h hardening-patch-4.4.2-0.4.8/main/hardening_patch.h
4462--- php-4.4.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4463+++ hardening-patch-4.4.2-0.4.8/main/hardening_patch.h 2006-01-18 12:43:26.910208240 +0100
4464@@ -0,0 +1,46 @@
4465+/*
4466+ +----------------------------------------------------------------------+
4467+ | Hardening Patch for PHP |
4468+ +----------------------------------------------------------------------+
4469+ | Copyright (c) 2004-2005 Stefan Esser |
4470+ +----------------------------------------------------------------------+
4471+ | This source file is subject to version 2.02 of the PHP license, |
4472+ | that is bundled with this package in the file LICENSE, and is |
4473+ | available at through the world-wide-web at |
4474+ | http://www.php.net/license/2_02.txt. |
4475+ | If you did not receive a copy of the PHP license and are unable to |
4476+ | obtain it through the world-wide-web, please send a note to |
4477+ | license@php.net so we can mail you a copy immediately. |
4478+ +----------------------------------------------------------------------+
4479+ | Author: Stefan Esser <sesser@hardened-php.net> |
4480+ +----------------------------------------------------------------------+
4481+ */
4482+
4483+#ifndef HARDENING_PATCH_H
4484+#define HARDENING_PATCH_H
4485+
4486+#include "zend.h"
4487+
4488+#if HARDENING_PATCH
4489+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4490+PHPAPI void hardened_startup();
4491+#define HARDENING_PATCH_VERSION "0.4.8"
4492+
4493+#endif
4494+
4495+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4496+PHPAPI unsigned int php_canary();
4497+#endif
4498+
4499+#if HARDENING_PATCH_INC_PROTECT
4500+PHPAPI int php_is_valid_include(zval *z);
4501+#endif
4502+
4503+#endif /* HARDENING_PATCH_H */
4504+
4505+/*
4506+ * Local variables:
4507+ * tab-width: 4
4508+ * c-basic-offset: 4
4509+ * End:
4510+ */
4511diff -Nura php-4.4.2/main/hardening_patch.m4 hardening-patch-4.4.2-0.4.8/main/hardening_patch.m4
4512--- php-4.4.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4513+++ hardening-patch-4.4.2-0.4.8/main/hardening_patch.m4 2006-01-18 12:43:26.910208240 +0100
4514@@ -0,0 +1,95 @@
4515+dnl
4516+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4517+dnl
4518+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4519+dnl
4520+
4521+AC_ARG_ENABLE(hardening-patch-mm-protect,
4522+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4523+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4524+],[
4525+ DO_HARDENING_PATCH_MM_PROTECT=yes
4526+])
4527+
4528+AC_ARG_ENABLE(hardening-patch-ll-protect,
4529+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4530+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4531+],[
4532+ DO_HARDENING_PATCH_LL_PROTECT=yes
4533+])
4534+
4535+AC_ARG_ENABLE(hardening-patch-inc-protect,
4536+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4537+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4538+],[
4539+ DO_HARDENING_PATCH_INC_PROTECT=yes
4540+])
4541+
4542+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4543+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4544+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4545+],[
4546+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4547+])
4548+
4549+AC_ARG_ENABLE(hardening-patch-hash-protect,
4550+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4551+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4552+],[
4553+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4554+])
4555+
4556+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4557+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4558+
4559+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4560+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4561+
4562+AC_MSG_CHECKING(whether to protect include/require statements)
4563+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4564+
4565+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4566+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4567+
4568+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4569+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4570+
4571+
4572+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4573+
4574+
4575+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4576+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4577+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4578+else
4579+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4580+fi
4581+
4582+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4583+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4584+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4585+else
4586+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4587+fi
4588+
4589+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4590+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4591+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4592+else
4593+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4594+fi
4595+
4596+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4597+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4598+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4599+else
4600+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4601+fi
4602+
4603+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4604+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4605+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4606+else
4607+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4608+fi
4609+
4610diff -Nura php-4.4.2/main/main.c hardening-patch-4.4.2-0.4.8/main/main.c
4611--- php-4.4.2/main/main.c 2006-01-01 14:46:59.000000000 +0100
4612+++ hardening-patch-4.4.2-0.4.8/main/main.c 2006-01-18 12:43:26.912207936 +0100
4613@@ -92,6 +92,10 @@
4614 PHPAPI int core_globals_id;
4615 #endif
4616
4617+#if HARDENING_PATCH
4618+#include "hardened_globals.h"
4619+#endif
4620+
4621 #define ERROR_BUF_LEN 1024
4622
4623 typedef struct {
4624@@ -142,10 +146,33 @@
4625 */
4626 static PHP_INI_MH(OnChangeMemoryLimit)
4627 {
4628+#if HARDENING_PATCH
4629+ long orig_memory_limit;
4630+
4631+ if (entry->modified) {
4632+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4633+ } else {
4634+ orig_memory_limit = 1<<30;
4635+ }
4636+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4637+ orig_memory_limit = 1<<30;
4638+ }
4639+#endif
4640 if (new_value) {
4641 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4642+#if HARDENING_PATCH
4643+ if (PG(memory_limit) > orig_memory_limit) {
4644+ PG(memory_limit) = orig_memory_limit;
4645+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4646+ return FAILURE;
4647+ }
4648+#endif
4649 } else {
4650+#if HARDENING_PATCH
4651+ PG(memory_limit) = orig_memory_limit;
4652+#else
4653 PG(memory_limit) = 1<<30; /* effectively, no limit */
4654+#endif
4655 }
4656 return zend_set_memory_limit(PG(memory_limit));
4657 }
4658@@ -1008,6 +1035,9 @@
4659
4660 zend_try {
4661 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4662+#if HARDENING_PATCH
4663+ hardened_clear_mm_canaries(TSRMLS_C);
4664+#endif
4665 } zend_end_try();
4666
4667 zend_try {
4668@@ -1098,6 +1128,10 @@
4669 tsrm_ls = ts_resource(0);
4670 #endif
4671
4672+#if HARDENING_PATCH
4673+ hardened_startup();
4674+#endif
4675+
4676 sapi_initialize_empty_request(TSRMLS_C);
4677 sapi_activate(TSRMLS_C);
4678
4679@@ -1110,6 +1144,12 @@
4680 php_output_startup();
4681 php_output_activate(TSRMLS_C);
4682
4683+#if HARDENING_PATCH_INC_PROTECT
4684+ zuf.is_valid_include = php_is_valid_include;
4685+#endif
4686+#if HARDENING_PATCH
4687+ zuf.security_log_function = php_security_log;
4688+#endif
4689 zuf.error_function = php_error_cb;
4690 zuf.printf_function = php_printf;
4691 zuf.write_function = php_body_write_wrapper;
4692@@ -1211,6 +1251,10 @@
4693 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4694 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);
4695 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4696+#if HARDENING_PATCH
4697+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4698+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4699+#endif
4700 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4701 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4702 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4703@@ -1318,7 +1362,7 @@
4704 */
4705 static inline void php_register_server_variables(TSRMLS_D)
4706 {
4707- zval *array_ptr=NULL;
4708+ zval *array_ptr=NULL, *vptr;
4709
4710 ALLOC_ZVAL(array_ptr);
4711 array_init(array_ptr);
4712diff -Nura php-4.4.2/main/php_config.h.in hardening-patch-4.4.2-0.4.8/main/php_config.h.in
4713--- php-4.4.2/main/php_config.h.in 2006-01-12 19:24:28.000000000 +0100
4714+++ hardening-patch-4.4.2-0.4.8/main/php_config.h.in 2006-01-18 12:43:26.914207632 +0100
4715@@ -865,6 +865,39 @@
4716 /* Enabling BIND8 compatibility for Panther */
4717 #undef BIND_8_COMPAT
4718
4719+/* Hardening-Patch */
4720+#undef HARDENING_PATCH
4721+
4722+/* Memory Manager Protection */
4723+#undef HARDENING_PATCH_MM_PROTECT
4724+
4725+/* Memory Manager Protection */
4726+#undef HARDENING_PATCH_MM_PROTECT
4727+
4728+/* Linked List Protection */
4729+#undef HARDENING_PATCH_LL_PROTECT
4730+
4731+/* Linked List Protection */
4732+#undef HARDENING_PATCH_LL_PROTECT
4733+
4734+/* Include/Require Protection */
4735+#undef HARDENING_PATCH_INC_PROTECT
4736+
4737+/* Include/Require Protection */
4738+#undef HARDENING_PATCH_INC_PROTECT
4739+
4740+/* Fmt String Protection */
4741+#undef HARDENING_PATCH_FMT_PROTECT
4742+
4743+/* Fmt String Protection */
4744+#undef HARDENING_PATCH_FMT_PROTECT
4745+
4746+/* HashTable DTOR Protection */
4747+#undef HARDENING_PATCH_HASH_PROTECT
4748+
4749+/* HashTable DTOR Protection */
4750+#undef HARDENING_PATCH_HASH_PROTECT
4751+
4752 /* Whether you have AOLserver */
4753 #undef HAVE_AOLSERVER
4754
4755@@ -1148,6 +1181,12 @@
4756 /* Define if you have the getaddrinfo function */
4757 #undef HAVE_GETADDRINFO
4758
4759+/* Whether realpath is broken */
4760+#undef PHP_BROKEN_REALPATH
4761+
4762+/* Whether realpath is broken */
4763+#undef PHP_BROKEN_REALPATH
4764+
4765 /* Whether system headers declare timezone */
4766 #undef HAVE_DECLARED_TIMEZONE
4767
4768diff -Nura php-4.4.2/main/php_content_types.c hardening-patch-4.4.2-0.4.8/main/php_content_types.c
4769--- php-4.4.2/main/php_content_types.c 2006-01-01 14:46:59.000000000 +0100
4770+++ hardening-patch-4.4.2-0.4.8/main/php_content_types.c 2006-01-18 12:43:26.915207480 +0100
4771@@ -77,6 +77,7 @@
4772 sapi_register_post_entries(php_post_entries);
4773 sapi_register_default_post_reader(php_default_post_reader);
4774 sapi_register_treat_data(php_default_treat_data);
4775+ sapi_register_input_filter(php_default_input_filter);
4776 return SUCCESS;
4777 }
4778 /* }}} */
4779diff -Nura php-4.4.2/main/php.h hardening-patch-4.4.2-0.4.8/main/php.h
4780--- php-4.4.2/main/php.h 2006-01-01 14:46:59.000000000 +0100
4781+++ hardening-patch-4.4.2-0.4.8/main/php.h 2006-01-18 12:43:26.915207480 +0100
4782@@ -35,11 +35,19 @@
4783 #include "zend_qsort.h"
4784 #include "php_compat.h"
4785
4786+
4787 #include "zend_API.h"
4788
4789 #undef sprintf
4790 #define sprintf php_sprintf
4791
4792+#if HARDENING_PATCH
4793+#if HAVE_REALPATH
4794+#undef realpath
4795+#define realpath php_realpath
4796+#endif
4797+#endif
4798+
4799 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4800 #undef PHP_DEBUG
4801 #define PHP_DEBUG ZEND_DEBUG
4802@@ -409,6 +417,10 @@
4803 #endif
4804 #endif /* !XtOffsetOf */
4805
4806+#if HARDENING_PATCH
4807+#include "hardening_patch.h"
4808+#endif
4809+
4810 #endif
4811
4812 /*
4813diff -Nura php-4.4.2/main/php_variables.c hardening-patch-4.4.2-0.4.8/main/php_variables.c
4814--- php-4.4.2/main/php_variables.c 2006-01-01 14:47:00.000000000 +0100
4815+++ hardening-patch-4.4.2-0.4.8/main/php_variables.c 2006-01-18 12:43:26.916207328 +0100
4816@@ -236,17 +236,28 @@
4817 while (var) {
4818 val = strchr(var, '=');
4819 if (val) { /* have a value */
4820- int val_len;
4821+ unsigned int val_len, new_val_len;
4822
4823 *val++ = '\0';
4824 php_url_decode(var, strlen(var));
4825 val_len = php_url_decode(val, strlen(val));
4826- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4827+ val = estrndup(val, val_len);
4828+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4829+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4830+ }
4831+ efree(val);
4832 }
4833 var = php_strtok_r(NULL, "&", &strtok_buf);
4834 }
4835 }
4836
4837+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
4838+{
4839+ /* TODO: check .ini setting here and apply user-defined input filter */
4840+ *new_val_len = val_len;
4841+ return 1;
4842+}
4843+
4844 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
4845 {
4846 char *res = NULL, *var, *val, *separator=NULL;
4847@@ -324,15 +335,26 @@
4848 while (var) {
4849 val = strchr(var, '=');
4850 if (val) { /* have a value */
4851- int val_len;
4852+ unsigned int val_len, new_val_len;
4853
4854 *val++ = '\0';
4855 php_url_decode(var, strlen(var));
4856 val_len = php_url_decode(val, strlen(val));
4857- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4858+ val = estrndup(val, val_len);
4859+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4860+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4861+ }
4862+ efree(val);
4863 } else {
4864+ unsigned int val_len, new_val_len;
4865+
4866 php_url_decode(var, strlen(var));
4867- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
4868+ val_len = 0;
4869+ val = estrndup("", 0);
4870+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4871+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4872+ }
4873+ efree(val);
4874 }
4875 var = php_strtok_r(NULL, separator, &strtok_buf);
4876 }
4877diff -Nura php-4.4.2/main/rfc1867.c hardening-patch-4.4.2-0.4.8/main/rfc1867.c
4878--- php-4.4.2/main/rfc1867.c 2006-01-01 14:47:00.000000000 +0100
4879+++ hardening-patch-4.4.2-0.4.8/main/rfc1867.c 2006-01-18 12:43:26.917207176 +0100
4880@@ -128,6 +128,8 @@
4881 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4882 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4883 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4884+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
4885+
4886
4887 void php_rfc1867_register_constants(TSRMLS_D)
4888 {
4889@@ -138,6 +140,7 @@
4890 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4891 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4892 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4893+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4894 }
4895
4896 static void normalize_protected_variable(char *varname TSRMLS_DC)
4897@@ -849,6 +852,7 @@
4898 char buff[FILLUNIT];
4899 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4900 int blen=0, wlen=0;
4901+ unsigned long offset;
4902
4903 zend_llist_clean(&header);
4904
4905@@ -897,21 +901,24 @@
4906 if (!filename && param) {
4907
4908 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
4909+ unsigned int new_val_len; /* Dummy variable */
4910
4911 if (!value) {
4912 value = estrdup("");
4913 }
4914
4915+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
4916 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
4917- if (php_mb_encoding_translation(TSRMLS_C)) {
4918- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4919- &num_vars, &num_vars_max TSRMLS_CC);
4920- } else {
4921- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4922- }
4923+ if (php_mb_encoding_translation(TSRMLS_C)) {
4924+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4925+ &num_vars, &num_vars_max TSRMLS_CC);
4926+ } else {
4927+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4928+ }
4929 #else
4930- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4931+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4932 #endif
4933+ }
4934 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
4935 max_file_size = atol(value);
4936 }
4937@@ -963,7 +970,11 @@
4938 tmp++;
4939 }
4940 }
4941-
4942+
4943+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4944+ skip_upload = 1;
4945+ }
4946+
4947 total_bytes = cancel_upload = 0;
4948
4949 if (!skip_upload) {
4950@@ -987,6 +998,11 @@
4951 cancel_upload = UPLOAD_ERROR_D;
4952 }
4953
4954+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4955+ cancel_upload = UPLOAD_ERROR_X;
4956+ }
4957+
4958+ offset = 0;
4959 end = 0;
4960 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4961 {
4962@@ -997,6 +1013,11 @@
4963 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
4964 cancel_upload = UPLOAD_ERROR_B;
4965 } else if (blen > 0) {
4966+
4967+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4968+ cancel_upload = UPLOAD_ERROR_X;
4969+ }
4970+
4971 wlen = write(fd, buff, blen);
4972
4973 if (wlen < blen) {
4974@@ -1004,6 +1025,7 @@
4975 cancel_upload = UPLOAD_ERROR_F;
4976 } else {
4977 total_bytes += wlen;
4978+ offset += wlen;
4979 }
4980 }
4981 }
4982@@ -1025,6 +1047,10 @@
4983 }
4984 #endif
4985
4986+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4987+ cancel_upload = UPLOAD_ERROR_X;
4988+ }
4989+
4990 if (cancel_upload) {
4991 if (temp_filename) {
4992 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4993diff -Nura php-4.4.2/main/SAPI.c hardening-patch-4.4.2-0.4.8/main/SAPI.c
4994--- php-4.4.2/main/SAPI.c 2006-01-01 14:46:59.000000000 +0100
4995+++ hardening-patch-4.4.2-0.4.8/main/SAPI.c 2006-01-18 12:43:26.918207024 +0100
4996@@ -854,6 +854,37 @@
4997 return SUCCESS;
4998 }
4999
5000+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))
5001+{
5002+ sapi_module.input_filter = input_filter;
5003+ return SUCCESS;
5004+}
5005+
5006+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
5007+{
5008+ sapi_module.upload_varname_filter = upload_varname_filter;
5009+ return SUCCESS;
5010+}
5011+
5012+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
5013+{
5014+ sapi_module.pre_upload_filter = pre_upload_filter;
5015+ return SUCCESS;
5016+}
5017+
5018+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))
5019+{
5020+ sapi_module.upload_content_filter = upload_content_filter;
5021+ return SUCCESS;
5022+}
5023+
5024+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
5025+{
5026+ sapi_module.post_upload_filter = post_upload_filter;
5027+ return SUCCESS;
5028+}
5029+
5030+
5031
5032 SAPI_API int sapi_flush(TSRMLS_D)
5033 {
5034diff -Nura php-4.4.2/main/SAPI.h hardening-patch-4.4.2-0.4.8/main/SAPI.h
5035--- php-4.4.2/main/SAPI.h 2006-01-01 14:46:59.000000000 +0100
5036+++ hardening-patch-4.4.2-0.4.8/main/SAPI.h 2006-01-18 12:43:26.918207024 +0100
5037@@ -101,9 +101,10 @@
5038 char *current_user;
5039 int current_user_length;
5040
5041- /* this is necessary for CLI module */
5042- int argc;
5043- char **argv;
5044+ /* this is necessary for CLI module */
5045+ int argc;
5046+ char **argv;
5047+
5048 } sapi_request_info;
5049
5050
5051@@ -177,6 +178,10 @@
5052 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
5053 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
5054 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
5055+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));
5056+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
5057+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));
5058+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
5059
5060 SAPI_API int sapi_flush(TSRMLS_D);
5061 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
5062@@ -238,8 +243,16 @@
5063 int (*get_target_uid)(uid_t * TSRMLS_DC);
5064 int (*get_target_gid)(gid_t * TSRMLS_DC);
5065
5066+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5067+
5068+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5069+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5070+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5071+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5072+
5073 void (*ini_defaults)(HashTable *configuration_hash);
5074 int phpinfo_as_text;
5075+
5076 };
5077
5078
5079@@ -262,16 +275,27 @@
5080
5081 #define SAPI_DEFAULT_MIMETYPE "text/html"
5082 #define SAPI_DEFAULT_CHARSET ""
5083+
5084+#if HARDENING_PATCH
5085+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5086+#else
5087 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5088+#endif
5089
5090 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5091 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5092
5093 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5094+#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)
5095+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5096+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5097+#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)
5098+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5099
5100 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5101 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5102 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
5103+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
5104
5105 #define STANDARD_SAPI_MODULE_PROPERTIES
5106
5107diff -Nura php-4.4.2/main/snprintf.c hardening-patch-4.4.2-0.4.8/main/snprintf.c
5108--- php-4.4.2/main/snprintf.c 2006-01-01 14:47:00.000000000 +0100
5109+++ hardening-patch-4.4.2-0.4.8/main/snprintf.c 2006-01-18 12:43:26.919206872 +0100
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 break;
5120
5121 /*
5122diff -Nura php-4.4.2/main/spprintf.c hardening-patch-4.4.2-0.4.8/main/spprintf.c
5123--- php-4.4.2/main/spprintf.c 2006-01-01 14:47:00.000000000 +0100
5124+++ hardening-patch-4.4.2-0.4.8/main/spprintf.c 2006-01-18 12:43:26.920206720 +0100
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 break;
5135
5136 /*
5137diff -Nura php-4.4.2/php.ini-dist hardening-patch-4.4.2-0.4.8/php.ini-dist
5138--- php-4.4.2/php.ini-dist 2005-12-30 18:19:43.000000000 +0100
5139+++ hardening-patch-4.4.2-0.4.8/php.ini-dist 2006-01-18 12:43:26.921206568 +0100
5140@@ -1114,6 +1114,209 @@
5141 ;exif.decode_jis_motorola = JIS
5142 ;exif.decode_jis_intel = JIS
5143
5144+[hardening-patch]
5145+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5146+; Hardening-Patch's logging ;
5147+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5148+
5149+;
5150+; hphp.log.syslog - Configures level for alerts reported through syslog
5151+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5152+; hphp.log.script - Configures level for alerts reported through external script
5153+;
5154+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5155+; Or each number up to get desired Hardening-Patch's reporting level
5156+;
5157+; S_ALL - All alerts
5158+; S_MEMORY - All canary violations and the safe unlink protection use this class
5159+; S_VARS - All variable filters trigger this class
5160+; S_FILES - All violation of uploaded files filter use this class
5161+; S_INCLUDE - The protection against malicious include filenames use this class
5162+; S_SQL - Failed SQL queries in MySQL are logged with this class
5163+; S_EXECUTOR - The execution depth protection uses this logging class
5164+; S_MISC - All other log messages (f.e. format string protection) use this class
5165+;
5166+; Example:
5167+;
5168+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5169+; memory alerts through syslog and SQL+Include alerts fo the script
5170+;
5171+;hphp.log.syslog = S_MEMORY
5172+;hphp.log.sapi = S_ALL & ~S_MEMORY
5173+;hphp.log.script = S_INCLUDE | S_SQL
5174+;
5175+; Syslog logging:
5176+;
5177+; - Facility configuration: one of the following facilities
5178+;
5179+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5180+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5181+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5182+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5183+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5184+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5185+; LOG_PERROR
5186+;
5187+; - Priority configuration: one of the followinf priorities
5188+;
5189+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5190+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5191+;
5192+hphp.log.syslog.priority = LOG_ALERT
5193+hphp.log.syslog.facility = LOG_USER
5194+;
5195+; Script logging:
5196+;
5197+;hphp.log.script.name = /home/hphp/log_script
5198+;
5199+; Alert configuration:
5200+;
5201+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5202+;
5203+;hphp.log.use-x-forwarded-for = On
5204+;
5205+
5206+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5207+; Hardening-Patch's Executor options ;
5208+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5209+
5210+; Execution depth limit
5211+;hphp.executor.max_depth = 8000
5212+
5213+; White-/blacklist for function calls during normal execution
5214+;hphp.executor.func.whitelist = ord,chr
5215+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5216+
5217+; White-/blacklist for function calls during eval() execution
5218+;hphp.executor.eval.whitelist = ord,chr
5219+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5220+
5221+; White-/blacklist for URLs allowes in include filenames
5222+;
5223+; - When both options are not set all URLs are forbidden
5224+;
5225+; - When both options are set whitelist is taken and blacklist ignored
5226+;
5227+; - An entry in the lists is either a URL sheme like: http, https
5228+; or the beginning of an URL like: php://input
5229+;
5230+;hphp.executor.include.whitelist = cookietest
5231+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5232+
5233+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5234+; Hardening-Patch's REQUEST variable filters ;
5235+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5236+
5237+; Limits the number of REQUEST variables
5238+hphp.request.max_vars = 200
5239+
5240+; Limits the length of variable names (without indices)
5241+hphp.request.max_varname_length = 64
5242+
5243+; Limits the length of complete variable names (with indices)
5244+hphp.request.max_totalname_length = 256
5245+
5246+; Limits the length of array indices
5247+hphp.request.max_array_index_length = 64
5248+
5249+; Limits the depth of arrays
5250+hphp.request.max_array_depth = 100
5251+
5252+; Limits the length of variable values
5253+hphp.request.max_value_length = 65000
5254+
5255+; Disallow ASCII-NUL characters in input
5256+hphp.request.disallow_nul = 1
5257+
5258+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5259+; Hardening-Patch's COOKIE variable filters ;
5260+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5261+
5262+; Limits the number of COOKIE variables
5263+hphp.cookie.max_vars = 100
5264+
5265+; Limits the length of variable names (without indices)
5266+hphp.cookie.max_name_length = 64
5267+
5268+; Limits the length of complete variable names (with indices)
5269+hphp.cookie.max_totalname_length = 256
5270+
5271+; Limits the length of array indices
5272+hphp.cookie.max_array_index_length = 64
5273+
5274+; Limits the depth of arrays
5275+hphp.cookie.max_array_depth = 100
5276+
5277+; Limits the length of variable values
5278+hphp.cookie.max_value_length = 10000
5279+
5280+; Disallow ASCII-NUL characters in input
5281+hphp.cookie.disallow_nul = 1
5282+
5283+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5284+; Hardening-Patch's GET variable filters ;
5285+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5286+
5287+; Limits the number of COOKIE variables
5288+hphp.get.max_vars = 100
5289+
5290+; Limits the length of variable names (without indices)
5291+hphp.get.max_name_length = 64
5292+
5293+; Limits the length of complete variable names (with indices)
5294+hphp.get.max_totalname_length = 256
5295+
5296+; Limits the length of array indices
5297+hphp.get.max_array_index_length = 64
5298+
5299+; Limits the depth of arrays
5300+hphp.get.max_array_depth = 50
5301+
5302+; Limits the length of variable values
5303+hphp.get.max_value_length = 512
5304+
5305+; Disallow ASCII-NUL characters in input
5306+hphp.get.disallow_nul = 1
5307+
5308+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5309+; Hardening-Patch's POST variable filters ;
5310+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5311+
5312+; Limits the number of POST variables
5313+hphp.post.max_vars = 200
5314+
5315+; Limits the length of variable names (without indices)
5316+hphp.post.max_name_length = 64
5317+
5318+; Limits the length of complete variable names (with indices)
5319+hphp.post.max_totalname_length = 256
5320+
5321+; Limits the length of array indices
5322+hphp.post.max_array_index_length = 64
5323+
5324+; Limits the depth of arrays
5325+hphp.post.max_array_depth = 100
5326+
5327+; Limits the length of variable values
5328+hphp.post.max_value_length = 65000
5329+
5330+; Disallow ASCII-NUL characters in input
5331+hphp.post.disallow_nul = 1
5332+
5333+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5334+; Hardening-Patch's fileupload variable filters ;
5335+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5336+
5337+; Limits the number of uploadable files
5338+hphp.upload.max_uploads = 25
5339+
5340+; Filter out the upload of ELF executables
5341+hphp.upload.disallow_elf_files = On
5342+
5343+; External filterscript for upload verification
5344+;hphp.upload.verification_script = /home/hphp/verify_script
5345+
5346+
5347 ; Local Variables:
5348 ; tab-width: 4
5349 ; End:
5350diff -Nura php-4.4.2/php.ini-recommended hardening-patch-4.4.2-0.4.8/php.ini-recommended
5351--- php-4.4.2/php.ini-recommended 2005-12-30 18:19:43.000000000 +0100
5352+++ hardening-patch-4.4.2-0.4.8/php.ini-recommended 2006-01-18 12:43:26.922206416 +0100
5353@@ -1112,6 +1112,209 @@
5354 ;exif.decode_jis_motorola = JIS
5355 ;exif.decode_jis_intel = JIS
5356
5357+[hardening-patch]
5358+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5359+; Hardening-Patch's logging ;
5360+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5361+
5362+;
5363+; hphp.log.syslog - Configures level for alerts reported through syslog
5364+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5365+; hphp.log.script - Configures level for alerts reported through external script
5366+;
5367+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5368+; Or each number up to get desired Hardening-Patch's reporting level
5369+;
5370+; S_ALL - All alerts
5371+; S_MEMORY - All canary violations and the safe unlink protection use this class
5372+; S_VARS - All variable filters trigger this class
5373+; S_FILES - All violation of uploaded files filter use this class
5374+; S_INCLUDE - The protection against malicious include filenames use this class
5375+; S_SQL - Failed SQL queries in MySQL are logged with this class
5376+; S_EXECUTOR - The execution depth protection uses this logging class
5377+; S_MISC - All other log messages (f.e. format string protection) use this class
5378+;
5379+; Example:
5380+;
5381+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5382+; memory alerts through syslog and SQL+Include alerts fo the script
5383+;
5384+;hphp.log.syslog = S_MEMORY
5385+;hphp.log.sapi = S_ALL & ~S_MEMORY
5386+;hphp.log.script = S_INCLUDE | S_SQL
5387+;
5388+; Syslog logging:
5389+;
5390+; - Facility configuration: one of the following facilities
5391+;
5392+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5393+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5394+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5395+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5396+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5397+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5398+; LOG_PERROR
5399+;
5400+; - Priority configuration: one of the followinf priorities
5401+;
5402+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5403+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5404+;
5405+hphp.log.syslog.priority = LOG_ALERT
5406+hphp.log.syslog.facility = LOG_USER
5407+;
5408+; Script logging:
5409+;
5410+;hphp.log.script.name = /home/hphp/log_script
5411+;
5412+; Alert configuration:
5413+;
5414+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5415+;
5416+;hphp.log.use-x-forwarded-for = On
5417+;
5418+
5419+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5420+; Hardening-Patch's Executor options ;
5421+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5422+
5423+; Execution depth limit
5424+;hphp.executor.max_depth = 8000
5425+
5426+; White-/blacklist for function calls during normal execution
5427+;hphp.executor.func.whitelist = ord,chr
5428+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5429+
5430+; White-/blacklist for function calls during eval() execution
5431+;hphp.executor.eval.whitelist = ord,chr
5432+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5433+
5434+; White-/blacklist for URLs allowes in include filenames
5435+;
5436+; - When both options are not set all URLs are forbidden
5437+;
5438+; - When both options are set whitelist is taken and blacklist ignored
5439+;
5440+; - An entry in the lists is either a URL sheme like: http, https
5441+; or the beginning of an URL like: php://input
5442+;
5443+;hphp.executor.include.whitelist = cookietest
5444+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5445+
5446+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5447+; Hardening-Patch's REQUEST variable filters ;
5448+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5449+
5450+; Limits the number of REQUEST variables
5451+hphp.request.max_vars = 200
5452+
5453+; Limits the length of variable names (without indices)
5454+hphp.request.max_varname_length = 64
5455+
5456+; Limits the length of complete variable names (with indices)
5457+hphp.request.max_totalname_length = 256
5458+
5459+; Limits the length of array indices
5460+hphp.request.max_array_index_length = 64
5461+
5462+; Limits the depth of arrays
5463+hphp.request.max_array_depth = 100
5464+
5465+; Limits the length of variable values
5466+hphp.request.max_value_length = 65000
5467+
5468+; Disallow ASCII-NUL characters in input
5469+hphp.request.disallow_nul = 1
5470+
5471+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5472+; Hardening-Patch's COOKIE variable filters ;
5473+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5474+
5475+; Limits the number of COOKIE variables
5476+hphp.cookie.max_vars = 100
5477+
5478+; Limits the length of variable names (without indices)
5479+hphp.cookie.max_name_length = 64
5480+
5481+; Limits the length of complete variable names (with indices)
5482+hphp.cookie.max_totalname_length = 256
5483+
5484+; Limits the length of array indices
5485+hphp.cookie.max_array_index_length = 64
5486+
5487+; Limits the depth of arrays
5488+hphp.cookie.max_array_depth = 100
5489+
5490+; Limits the length of variable values
5491+hphp.cookie.max_value_length = 10000
5492+
5493+; Disallow ASCII-NUL characters in input
5494+hphp.cookie.disallow_nul = 1
5495+
5496+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5497+; Hardening-Patch's GET variable filters ;
5498+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5499+
5500+; Limits the number of COOKIE variables
5501+hphp.get.max_vars = 100
5502+
5503+; Limits the length of variable names (without indices)
5504+hphp.get.max_name_length = 64
5505+
5506+; Limits the length of complete variable names (with indices)
5507+hphp.get.max_totalname_length = 256
5508+
5509+; Limits the length of array indices
5510+hphp.get.max_array_index_length = 64
5511+
5512+; Limits the depth of arrays
5513+hphp.get.max_array_depth = 50
5514+
5515+; Limits the length of variable values
5516+hphp.get.max_value_length = 512
5517+
5518+; Disallow ASCII-NUL characters in input
5519+hphp.get.disallow_nul = 1
5520+
5521+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5522+; Hardening-Patch's POST variable filters ;
5523+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5524+
5525+; Limits the number of POST variables
5526+hphp.post.max_vars = 200
5527+
5528+; Limits the length of variable names (without indices)
5529+hphp.post.max_name_length = 64
5530+
5531+; Limits the length of complete variable names (with indices)
5532+hphp.post.max_totalname_length = 256
5533+
5534+; Limits the length of array indices
5535+hphp.post.max_array_index_length = 64
5536+
5537+; Limits the depth of arrays
5538+hphp.post.max_array_depth = 100
5539+
5540+; Limits the length of variable values
5541+hphp.post.max_value_length = 65000
5542+
5543+; Disallow ASCII-NUL characters in input
5544+hphp.post.disallow_nul = 1
5545+
5546+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5547+; Hardening-Patch's fileupload variable filters ;
5548+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5549+
5550+; Limits the number of uploadable files
5551+hphp.upload.max_uploads = 25
5552+
5553+; Filter out the upload of ELF executables
5554+hphp.upload.disallow_elf_files = On
5555+
5556+; External filterscript for upload verification
5557+;hphp.upload.verification_script = /home/hphp/verify_script
5558+
5559+
5560 ; Local Variables:
5561 ; tab-width: 4
5562 ; End:
5563diff -Nura php-4.4.2/README.input_filter hardening-patch-4.4.2-0.4.8/README.input_filter
5564--- php-4.4.2/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5565+++ hardening-patch-4.4.2-0.4.8/README.input_filter 2006-01-18 12:43:26.923206264 +0100
5566@@ -0,0 +1,193 @@
5567+Input Filter Support ported from PHP 5
5568+--------------------------------------
5569+
5570+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5571+and can be quite difficult to prevent. Whenever you accept user data
5572+and somehow display this data back to users, you are likely vulnerable
5573+to XSS hacks.
5574+
5575+The Input Filter support in PHP 5 is aimed at providing the framework
5576+through which a company-wide or site-wide security policy can be
5577+enforced. It is implemented as a SAPI hook and is called from the
5578+treat_data and post handler functions. To implement your own security
5579+policy you will need to write a standard PHP extension.
5580+
5581+A simple implementation might look like the following. This stores the
5582+original raw user data and adds a my_get_raw() function while the normal
5583+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5584+data. In this simple example all I am doing is calling strip_tags() on
5585+the data. If register_globals is turned on, the default globals that
5586+are created will be stripped ($foo) while a $RAW_foo is created with the
5587+original user input.
5588+
5589+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5590+ zval *post_array;
5591+ zval *get_array;
5592+ zval *cookie_array;
5593+ZEND_END_MODULE_GLOBALS(my_input_filter)
5594+
5595+#ifdef ZTS
5596+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5597+#else
5598+#define IF_G(v) (my_input_filter_globals.v)
5599+#endif
5600+
5601+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5602+
5603+function_entry my_input_filter_functions[] = {
5604+ PHP_FE(my_get_raw, NULL)
5605+ {NULL, NULL, NULL}
5606+};
5607+
5608+zend_module_entry my_input_filter_module_entry = {
5609+ STANDARD_MODULE_HEADER,
5610+ "my_input_filter",
5611+ my_input_filter_functions,
5612+ PHP_MINIT(my_input_filter),
5613+ PHP_MSHUTDOWN(my_input_filter),
5614+ NULL,
5615+ PHP_RSHUTDOWN(my_input_filter),
5616+ PHP_MINFO(my_input_filter),
5617+ "0.1",
5618+ STANDARD_MODULE_PROPERTIES
5619+};
5620+
5621+PHP_MINIT_FUNCTION(my_input_filter)
5622+{
5623+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5624+
5625+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5626+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5627+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5628+
5629+ sapi_register_input_filter(my_sapi_input_filter);
5630+ return SUCCESS;
5631+}
5632+
5633+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5634+{
5635+ if(IF_G(get_array)) {
5636+ zval_ptr_dtor(&IF_G(get_array));
5637+ IF_G(get_array) = NULL;
5638+ }
5639+ if(IF_G(post_array)) {
5640+ zval_ptr_dtor(&IF_G(post_array));
5641+ IF_G(post_array) = NULL;
5642+ }
5643+ if(IF_G(cookie_array)) {
5644+ zval_ptr_dtor(&IF_G(cookie_array));
5645+ IF_G(cookie_array) = NULL;
5646+ }
5647+ return SUCCESS;
5648+}
5649+
5650+PHP_MINFO_FUNCTION(my_input_filter)
5651+{
5652+ php_info_print_table_start();
5653+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5654+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5655+ php_info_print_table_end();
5656+}
5657+
5658+/* The filter handler. If you return 1 from it, then PHP also registers the
5659+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5660+ * you can use this if your filter already registers the variable under a
5661+ * different name, or if you just don't want the variable registered at all. */
5662+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5663+{
5664+ zval new_var;
5665+ zval *array_ptr = NULL;
5666+ char *raw_var;
5667+ int var_len;
5668+
5669+ assert(*val != NULL);
5670+
5671+ switch(arg) {
5672+ case PARSE_GET:
5673+ if(!IF_G(get_array)) {
5674+ ALLOC_ZVAL(array_ptr);
5675+ array_init(array_ptr);
5676+ INIT_PZVAL(array_ptr);
5677+ }
5678+ IF_G(get_array) = array_ptr;
5679+ break;
5680+ case PARSE_POST:
5681+ if(!IF_G(post_array)) {
5682+ ALLOC_ZVAL(array_ptr);
5683+ array_init(array_ptr);
5684+ INIT_PZVAL(array_ptr);
5685+ }
5686+ IF_G(post_array) = array_ptr;
5687+ break;
5688+ case PARSE_COOKIE:
5689+ if(!IF_G(cookie_array)) {
5690+ ALLOC_ZVAL(array_ptr);
5691+ array_init(array_ptr);
5692+ INIT_PZVAL(array_ptr);
5693+ }
5694+ IF_G(cookie_array) = array_ptr;
5695+ break;
5696+ }
5697+ Z_STRLEN(new_var) = val_len;
5698+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5699+ Z_TYPE(new_var) = IS_STRING;
5700+
5701+ var_len = strlen(var);
5702+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5703+ strcpy(raw_var, "RAW_");
5704+ strlcat(raw_var,var,var_len+5);
5705+
5706+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5707+
5708+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5709+
5710+ *new_val_len = strlen(*val);
5711+ return 1;
5712+}
5713+
5714+PHP_FUNCTION(my_get_raw)
5715+{
5716+ long arg;
5717+ char *var;
5718+ int var_len;
5719+ zval **tmp;
5720+ zval *array_ptr = NULL;
5721+ HashTable *hash_ptr;
5722+ char *raw_var;
5723+
5724+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
5725+ return;
5726+ }
5727+
5728+ switch(arg) {
5729+ case PARSE_GET:
5730+ array_ptr = IF_G(get_array);
5731+ break;
5732+ case PARSE_POST:
5733+ array_ptr = IF_G(post_array);
5734+ break;
5735+ case PARSE_COOKIE:
5736+ array_ptr = IF_G(post_array);
5737+ break;
5738+ }
5739+
5740+ if(!array_ptr) RETURN_FALSE;
5741+
5742+ /*
5743+ * I'm changing the variable name here because when running with register_globals on,
5744+ * the variable will end up in the global symbol table
5745+ */
5746+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5747+ strcpy(raw_var, "RAW_");
5748+ strlcat(raw_var,var,var_len+5);
5749+ hash_ptr = HASH_OF(array_ptr);
5750+
5751+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
5752+ *return_value = **tmp;
5753+ zval_copy_ctor(return_value);
5754+ } else {
5755+ RETVAL_FALSE;
5756+ }
5757+ efree(raw_var);
5758+}
5759+
5760diff -Nura php-4.4.2/run-tests.php hardening-patch-4.4.2-0.4.8/run-tests.php
5761--- php-4.4.2/run-tests.php 2006-01-01 14:46:48.000000000 +0100
5762+++ hardening-patch-4.4.2-0.4.8/run-tests.php 2006-01-18 12:43:26.924206112 +0100
5763@@ -152,6 +152,10 @@
5764 'error_reporting=2047',
5765 'display_errors=1',
5766 'log_errors=0',
5767+ 'hphp.executor.include.whitelist=cookietest',
5768+ 'hphp.log.syslog=0',
5769+ 'hphp.log.sapi=0',
5770+ 'hphp.log.script=0',
5771 'html_errors=0',
5772 'track_errors=1',
5773 'report_memleaks=1',
5774diff -Nura php-4.4.2/sapi/apache/mod_php4.c hardening-patch-4.4.2-0.4.8/sapi/apache/mod_php4.c
5775--- php-4.4.2/sapi/apache/mod_php4.c 2006-01-01 14:47:01.000000000 +0100
5776+++ hardening-patch-4.4.2-0.4.8/sapi/apache/mod_php4.c 2006-01-18 12:43:26.924206112 +0100
5777@@ -452,7 +452,7 @@
5778 sapi_apache_get_fd,
5779 sapi_apache_force_http_10,
5780 sapi_apache_get_target_uid,
5781- sapi_apache_get_target_gid
5782+ sapi_apache_get_target_gid,
5783 };
5784 /* }}} */
5785
5786@@ -898,7 +898,11 @@
5787 {
5788 TSRMLS_FETCH();
5789 if (PG(expose_php)) {
5790+#if HARDENING_PATCH
5791+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5792+#else
5793 ap_add_version_component("PHP/" PHP_VERSION);
5794+#endif
5795 }
5796 }
5797 #endif
5798diff -Nura php-4.4.2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.2-0.4.8/sapi/apache2filter/sapi_apache2.c
5799--- php-4.4.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
5800+++ hardening-patch-4.4.2-0.4.8/sapi/apache2filter/sapi_apache2.c 2006-01-18 12:43:26.925205960 +0100
5801@@ -562,7 +562,11 @@
5802 {
5803 TSRMLS_FETCH();
5804 if (PG(expose_php)) {
5805+#if HARDENING_PATCH
5806+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5807+#else
5808 ap_add_version_component(p, "PHP/" PHP_VERSION);
5809+#endif
5810 }
5811 }
5812
5813diff -Nura php-4.4.2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.2-0.4.8/sapi/apache2handler/sapi_apache2.c
5814--- php-4.4.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 14:47:01.000000000 +0100
5815+++ hardening-patch-4.4.2-0.4.8/sapi/apache2handler/sapi_apache2.c 2006-01-18 12:43:26.926205808 +0100
5816@@ -340,7 +340,11 @@
5817 {
5818 TSRMLS_FETCH();
5819 if (PG(expose_php)) {
5820+#if HARDENING_PATCH
5821+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5822+#else
5823 ap_add_version_component(p, "PHP/" PHP_VERSION);
5824+#endif
5825 }
5826 }
5827
5828diff -Nura php-4.4.2/sapi/cgi/cgi_main.c hardening-patch-4.4.2-0.4.8/sapi/cgi/cgi_main.c
5829--- php-4.4.2/sapi/cgi/cgi_main.c 2006-01-01 14:47:01.000000000 +0100
5830+++ hardening-patch-4.4.2-0.4.8/sapi/cgi/cgi_main.c 2006-01-18 12:48:25.870759328 +0100
5831@@ -1432,11 +1432,19 @@
5832 SG(headers_sent) = 1;
5833 SG(request_info).no_headers = 1;
5834 }
5835+#if HARDENING_PATCH
5836+#if ZEND_DEBUG
5837+ 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());
5838+#else
5839+ 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());
5840+#endif
5841+#else
5842 #if ZEND_DEBUG
5843 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());
5844 #else
5845 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());
5846 #endif
5847+#endif
5848 php_end_ob_buffers(1 TSRMLS_CC);
5849 exit(0);
5850 break;
5851diff -Nura php-4.4.2/sapi/cli/php_cli.c hardening-patch-4.4.2-0.4.8/sapi/cli/php_cli.c
5852--- php-4.4.2/sapi/cli/php_cli.c 2006-01-01 14:47:01.000000000 +0100
5853+++ hardening-patch-4.4.2-0.4.8/sapi/cli/php_cli.c 2006-01-18 12:47:52.846779736 +0100
5854@@ -654,11 +654,19 @@
5855 if (php_request_startup(TSRMLS_C)==FAILURE) {
5856 goto err;
5857 }
5858+#if HARDENING_PATCH
5859+#if ZEND_DEBUG
5860+ 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());
5861+#else
5862+ 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());
5863+#endif
5864+#else
5865 #if ZEND_DEBUG
5866 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());
5867 #else
5868 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());
5869 #endif
5870+#endif
5871 php_end_ob_buffers(1 TSRMLS_CC);
5872 exit_status=0;
5873 goto out;
5874diff -Nura php-4.4.2/TSRM/TSRM.h hardening-patch-4.4.2-0.4.8/TSRM/TSRM.h
5875--- php-4.4.2/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
5876+++ hardening-patch-4.4.2-0.4.8/TSRM/TSRM.h 2006-01-18 12:43:26.929205352 +0100
5877@@ -33,6 +33,13 @@
5878 # define TSRM_API
5879 #endif
5880
5881+#if HARDENING_PATCH
5882+# if HAVE_REALPATH
5883+# undef realpath
5884+# define realpath php_realpath
5885+# endif
5886+#endif
5887+
5888 /* Only compile multi-threading functions if we're in ZTS mode */
5889 #ifdef ZTS
5890
5891@@ -84,6 +91,7 @@
5892
5893 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5894
5895+
5896 #ifdef __cplusplus
5897 extern "C" {
5898 #endif
5899diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.2-0.4.8/TSRM/tsrm_virtual_cwd.c
5900--- php-4.4.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 14:46:48.000000000 +0100
5901+++ hardening-patch-4.4.2-0.4.8/TSRM/tsrm_virtual_cwd.c 2006-01-18 12:43:26.930205200 +0100
5902@@ -179,6 +179,165 @@
5903 return p;
5904 }
5905
5906+#if HARDENING_PATCH
5907+CWD_API char *php_realpath(const char *path, char *resolved)
5908+{
5909+ struct stat sb;
5910+ char *p, *q, *s;
5911+ size_t left_len, resolved_len;
5912+ unsigned symlinks;
5913+ int serrno, slen;
5914+ int is_dir = 1;
5915+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5916+
5917+ serrno = errno;
5918+ symlinks = 0;
5919+ if (path[0] == '/') {
5920+ resolved[0] = '/';
5921+ resolved[1] = '\0';
5922+ if (path[1] == '\0')
5923+ return (resolved);
5924+ resolved_len = 1;
5925+ left_len = strlcpy(left, path + 1, sizeof(left));
5926+ } else {
5927+ if (getcwd(resolved, PATH_MAX) == NULL) {
5928+ strlcpy(resolved, ".", PATH_MAX);
5929+ return (NULL);
5930+ }
5931+ resolved_len = strlen(resolved);
5932+ left_len = strlcpy(left, path, sizeof(left));
5933+ }
5934+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5935+ errno = ENAMETOOLONG;
5936+ return (NULL);
5937+ }
5938+
5939+ /*
5940+ * Iterate over path components in `left'.
5941+ */
5942+ while (left_len != 0) {
5943+ /*
5944+ * Extract the next path component and adjust `left'
5945+ * and its length.
5946+ */
5947+ p = strchr(left, '/');
5948+ s = p ? p : left + left_len;
5949+ if (s - left >= sizeof(next_token)) {
5950+ errno = ENAMETOOLONG;
5951+ return (NULL);
5952+ }
5953+ memcpy(next_token, left, s - left);
5954+ next_token[s - left] = '\0';
5955+ left_len -= s - left;
5956+ if (p != NULL)
5957+ memmove(left, s + 1, left_len + 1);
5958+ if (resolved[resolved_len - 1] != '/') {
5959+ if (resolved_len + 1 >= PATH_MAX) {
5960+ errno = ENAMETOOLONG;
5961+ return (NULL);
5962+ }
5963+ resolved[resolved_len++] = '/';
5964+ resolved[resolved_len] = '\0';
5965+ }
5966+ if (next_token[0] == '\0')
5967+ continue;
5968+ else if (strcmp(next_token, ".") == 0)
5969+ continue;
5970+ else if (strcmp(next_token, "..") == 0) {
5971+ /*
5972+ * Strip the last path component except when we have
5973+ * single "/"
5974+ */
5975+ if (!is_dir) {
5976+ errno = ENOENT;
5977+ return (NULL);
5978+ }
5979+ if (resolved_len > 1) {
5980+ resolved[resolved_len - 1] = '\0';
5981+ q = strrchr(resolved, '/');
5982+ *q = '\0';
5983+ resolved_len = q - resolved;
5984+ }
5985+ continue;
5986+ }
5987+
5988+ /*
5989+ * Append the next path component and lstat() it. If
5990+ * lstat() fails we still can return successfully if
5991+ * there are no more path components left.
5992+ */
5993+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
5994+ if (resolved_len >= PATH_MAX) {
5995+ errno = ENAMETOOLONG;
5996+ return (NULL);
5997+ }
5998+ if (lstat(resolved, &sb) != 0) {
5999+ if (errno == ENOENT && p == NULL) {
6000+ errno = serrno;
6001+ return (resolved);
6002+ }
6003+ return (NULL);
6004+ }
6005+ if (S_ISLNK(sb.st_mode)) {
6006+ if (symlinks++ > MAXSYMLINKS) {
6007+ errno = ELOOP;
6008+ return (NULL);
6009+ }
6010+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
6011+ if (slen < 0)
6012+ return (NULL);
6013+ symlink[slen] = '\0';
6014+ if (symlink[0] == '/') {
6015+ resolved[1] = 0;
6016+ resolved_len = 1;
6017+ } else if (resolved_len > 1) {
6018+ /* Strip the last path component. */
6019+ resolved[resolved_len - 1] = '\0';
6020+ q = strrchr(resolved, '/');
6021+ *q = '\0';
6022+ resolved_len = q - resolved;
6023+ }
6024+
6025+ /*
6026+ * If there are any path components left, then
6027+ * append them to symlink. The result is placed
6028+ * in `left'.
6029+ */
6030+ if (p != NULL) {
6031+ if (symlink[slen - 1] != '/') {
6032+ if (slen + 1 >= sizeof(symlink)) {
6033+ errno = ENAMETOOLONG;
6034+ return (NULL);
6035+ }
6036+ symlink[slen] = '/';
6037+ symlink[slen + 1] = 0;
6038+ }
6039+ left_len = strlcat(symlink, left, sizeof(left));
6040+ if (left_len >= sizeof(left)) {
6041+ errno = ENAMETOOLONG;
6042+ return (NULL);
6043+ }
6044+ }
6045+ left_len = strlcpy(left, symlink, sizeof(left));
6046+ } else {
6047+ if (S_ISDIR(sb.st_mode)) {
6048+ is_dir = 1;
6049+ } else {
6050+ is_dir = 0;
6051+ }
6052+ }
6053+ }
6054+
6055+ /*
6056+ * Remove trailing slash except when the resolved pathname
6057+ * is a single "/".
6058+ */
6059+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
6060+ resolved[resolved_len - 1] = '\0';
6061+ return (resolved);
6062+}
6063+#endif
6064+
6065 CWD_API void virtual_cwd_startup(void)
6066 {
6067 char cwd[MAXPATHLEN];
6068@@ -300,8 +459,11 @@
6069
6070 if (path_length == 0)
6071 return (0);
6072- if (path_length >= MAXPATHLEN)
6073+ if (path_length >= MAXPATHLEN) {
6074+ state->cwd[0] = 0;
6075+ state->cwd_length = 0;
6076 return (1);
6077+ }
6078
6079 #if !defined(TSRM_WIN32) && !defined(NETWARE)
6080 /* cwd_length can be 0 when getcwd() fails.
6081@@ -313,8 +475,9 @@
6082 path = resolved_path;
6083 path_length = strlen(path);
6084 } else {
6085- /* disable for now
6086- return 1; */
6087+ state->cwd[0] = 0;
6088+ state->cwd_length = 0;
6089+ return 1;
6090 }
6091 }
6092 } else { /* Concat current directory with relative path and then run realpath() on it */
6093@@ -323,6 +486,8 @@
6094
6095 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
6096 if (!tmp) {
6097+ state->cwd[0] = 0;
6098+ state->cwd_length = 0;
6099 return 1;
6100 }
6101 memcpy(ptr, state->cwd, state->cwd_length);
6102@@ -332,6 +497,8 @@
6103 ptr += path_length;
6104 *ptr = '\0';
6105 if (strlen(tmp) >= MAXPATHLEN) {
6106+ state->cwd[0] = 0;
6107+ state->cwd_length = 0;
6108 free(tmp);
6109 return 1;
6110 }
6111@@ -340,9 +507,10 @@
6112 path = resolved_path;
6113 path_length = strlen(path);
6114 } else {
6115- /* disable for now
6116+ state->cwd[0] = 0;
6117+ state->cwd_length = 0;
6118 free(tmp);
6119- return 1; */
6120+ return 1;
6121 }
6122 }
6123 free(tmp);
6124diff -Nura php-4.4.2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.2-0.4.8/TSRM/tsrm_virtual_cwd.h
6125--- php-4.4.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 14:46:49.000000000 +0100
6126+++ hardening-patch-4.4.2-0.4.8/TSRM/tsrm_virtual_cwd.h 2006-01-18 12:43:26.931205048 +0100
6127@@ -128,6 +128,22 @@
6128
6129 typedef int (*verify_path_func)(const cwd_state *);
6130
6131+#ifndef HAVE_STRLCPY
6132+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
6133+#undef strlcpy
6134+#define strlcpy php_strlcpy
6135+#endif
6136+
6137+#ifndef HAVE_STRLCAT
6138+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
6139+#undef strlcat
6140+#define strlcat php_strlcat
6141+#endif
6142+
6143+
6144+#if HARDENING_PATCH
6145+CWD_API char *php_realpath(const char *path, char *resolved);
6146+#endif
6147 CWD_API void virtual_cwd_startup(void);
6148 CWD_API void virtual_cwd_shutdown(void);
6149 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
6150diff -Nura php-4.4.2/Zend/zend_alloc.c hardening-patch-4.4.2-0.4.8/Zend/zend_alloc.c
6151--- php-4.4.2/Zend/zend_alloc.c 2006-01-01 14:46:49.000000000 +0100
6152+++ hardening-patch-4.4.2-0.4.8/Zend/zend_alloc.c 2006-01-18 12:43:26.932204896 +0100
6153@@ -56,6 +56,11 @@
6154 # define END_MAGIC_SIZE 0
6155 #endif
6156
6157+#if HARDENING_PATCH_MM_PROTECT
6158+# define CANARY_SIZE sizeof(unsigned int)
6159+#else
6160+# define CANARY_SIZE 0
6161+#endif
6162
6163 # if MEMORY_LIMIT
6164 # if ZEND_DEBUG
6165@@ -96,9 +101,17 @@
6166 if (p==AG(head)) { \
6167 AG(head) = p->pNext; \
6168 } else { \
6169+ if (p != p->pLast->pNext) { \
6170+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6171+ exit(1); \
6172+ } \
6173 p->pLast->pNext = p->pNext; \
6174 } \
6175 if (p->pNext) { \
6176+ if (p != p->pNext->pLast) { \
6177+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
6178+ exit(1); \
6179+ } \
6180 p->pNext->pLast = p->pLast; \
6181 }
6182
6183@@ -130,6 +143,12 @@
6184 DECLARE_CACHE_VARS();
6185 TSRMLS_FETCH();
6186
6187+#if HARDENING_PATCH_MM_PROTECT
6188+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
6189+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
6190+ exit(1);
6191+ }
6192+#endif
6193 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
6194
6195 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
6196@@ -147,6 +166,10 @@
6197 AG(cache_stats)[CACHE_INDEX][1]++;
6198 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6199 #endif
6200+#if HARDENING_PATCH_MM_PROTECT
6201+ p->canary = HG(canary_1);
6202+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6203+#endif
6204 p->cached = 0;
6205 p->size = size;
6206 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6207@@ -162,7 +185,7 @@
6208 AG(allocated_memory_peak) = AG(allocated_memory);
6209 }
6210 #endif
6211- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
6212+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
6213 }
6214
6215 HANDLE_BLOCK_INTERRUPTIONS();
6216@@ -192,7 +215,10 @@
6217 # endif
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+ p->canary = HG(canary_1);
6223+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6224+#endif
6225 HANDLE_UNBLOCK_INTERRUPTIONS();
6226 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
6227 }
6228@@ -219,17 +245,36 @@
6229 return emalloc_rel(lval + offset);
6230 }
6231 }
6232-
6233+
6234+#if HARDENING_PATCH
6235+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6236+#endif
6237 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
6238 return 0;
6239 }
6240
6241 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6242 {
6243+#if HARDENING_PATCH_MM_PROTECT
6244+ unsigned int canary_2;
6245+#endif
6246 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6247 DECLARE_CACHE_VARS();
6248 TSRMLS_FETCH();
6249
6250+#if HARDENING_PATCH_MM_PROTECT
6251+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6252+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6253+ if (canary_2 != HG(canary_2)) {
6254+efree_canary_mismatch:
6255+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6256+ exit(1);
6257+ }
6258+ /* to catch double efree()s */
6259+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6260+ p->canary = 0;
6261+#endif
6262+
6263 #if defined(ZTS) && TSRM_DEBUG
6264 if (p->thread_id != tsrm_thread_id()) {
6265 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
6266@@ -274,6 +319,9 @@
6267 size_t _size = nmemb * size;
6268
6269 if (nmemb && (_size/nmemb!=size)) {
6270+#if HARDENING_PATCH
6271+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6272+#endif
6273 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6274 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6275 kill(getpid(), SIGSEGV);
6276@@ -293,6 +341,9 @@
6277
6278 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6279 {
6280+#if HARDENING_PATCH_MM_PROTECT
6281+ unsigned int canary_2;
6282+#endif
6283 zend_mem_header *p;
6284 zend_mem_header *orig;
6285 DECLARE_CACHE_VARS();
6286@@ -304,6 +355,16 @@
6287
6288 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6289
6290+#if HARDENING_PATCH_MM_PROTECT
6291+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6292+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6293+ if (canary_2 != HG(canary_2)) {
6294+erealloc_canary_mismatch:
6295+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6296+ exit(1);
6297+ }
6298+#endif
6299+
6300 #if defined(ZTS) && TSRM_DEBUG
6301 if (p->thread_id != tsrm_thread_id()) {
6302 void *new_p;
6303@@ -327,7 +388,7 @@
6304 }
6305 #endif
6306 REMOVE_POINTER_FROM_LIST(p);
6307- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6308+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6309 if (!p) {
6310 if (!allow_failure) {
6311 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6312@@ -349,6 +410,9 @@
6313 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6314 #endif
6315
6316+#if HARDENING_PATCH_MM_PROTECT
6317+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6318+#endif
6319 p->size = size;
6320
6321 HANDLE_UNBLOCK_INTERRUPTIONS();
6322@@ -423,6 +487,10 @@
6323 {
6324 AG(head) = NULL;
6325
6326+#if HARDENING_PATCH_MM_PROTECT
6327+ HG(canary_1) = zend_canary();
6328+ HG(canary_2) = zend_canary();
6329+#endif
6330 #if MEMORY_LIMIT
6331 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6332 AG(allocated_memory) = 0;
6333diff -Nura php-4.4.2/Zend/zend_alloc.h hardening-patch-4.4.2-0.4.8/Zend/zend_alloc.h
6334--- php-4.4.2/Zend/zend_alloc.h 2006-01-01 14:46:49.000000000 +0100
6335+++ hardening-patch-4.4.2-0.4.8/Zend/zend_alloc.h 2006-01-18 12:43:26.932204896 +0100
6336@@ -32,6 +32,9 @@
6337 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6338
6339 typedef struct _zend_mem_header {
6340+#if HARDENING_PATCH_MM_PROTECT
6341+ unsigned int canary;
6342+#endif
6343 #if ZEND_DEBUG
6344 long magic;
6345 char *filename;
6346diff -Nura php-4.4.2/Zend/zend_builtin_functions.c hardening-patch-4.4.2-0.4.8/Zend/zend_builtin_functions.c
6347--- php-4.4.2/Zend/zend_builtin_functions.c 2006-01-01 14:46:49.000000000 +0100
6348+++ hardening-patch-4.4.2-0.4.8/Zend/zend_builtin_functions.c 2006-01-18 12:43:26.933204744 +0100
6349@@ -49,6 +49,9 @@
6350 static ZEND_FUNCTION(crash);
6351 #endif
6352 #endif
6353+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6354+static ZEND_FUNCTION(heap_overflow);
6355+#endif
6356 static ZEND_FUNCTION(get_included_files);
6357 static ZEND_FUNCTION(is_subclass_of);
6358 static ZEND_FUNCTION(is_a);
6359@@ -101,6 +104,9 @@
6360 ZEND_FE(crash, NULL)
6361 #endif
6362 #endif
6363+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6364+ ZEND_FE(heap_overflow, NULL)
6365+#endif
6366 ZEND_FE(get_included_files, NULL)
6367 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6368 ZEND_FE(is_subclass_of, NULL)
6369@@ -805,6 +811,19 @@
6370
6371 #endif /* ZEND_DEBUG */
6372
6373+
6374+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6375+ZEND_FUNCTION(heap_overflow)
6376+{
6377+ char *nowhere = emalloc(10);
6378+
6379+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6380+
6381+ efree(nowhere);
6382+}
6383+#endif
6384+
6385+
6386 /* {{{ proto array get_included_files(void)
6387 Returns an array with the file names that were include_once()'d */
6388 ZEND_FUNCTION(get_included_files)
6389diff -Nura php-4.4.2/Zend/zend.c hardening-patch-4.4.2-0.4.8/Zend/zend.c
6390--- php-4.4.2/Zend/zend.c 2006-01-01 14:46:49.000000000 +0100
6391+++ hardening-patch-4.4.2-0.4.8/Zend/zend.c 2006-01-18 12:43:26.934204592 +0100
6392@@ -53,6 +53,12 @@
6393 ZEND_API void (*zend_unblock_interruptions)(void);
6394 ZEND_API void (*zend_ticks_function)(int ticks);
6395 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6396+#if HARDENING_PATCH
6397+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6398+#endif
6399+#if HARDENING_PATCH_INC_PROTECT
6400+ZEND_API int (*zend_is_valid_include)(zval *z);
6401+#endif
6402
6403 void (*zend_on_timeout)(int seconds TSRMLS_DC);
6404
6405@@ -70,9 +76,390 @@
6406 return SUCCESS;
6407 }
6408
6409+#if HARDENING_PATCH
6410+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6411+{
6412+ if (!new_value) {
6413+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6414+ } else {
6415+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6416+ }
6417+ return SUCCESS;
6418+}
6419+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6420+{
6421+ if (!new_value) {
6422+ EG(hphp_log_syslog_facility) = LOG_USER;
6423+ } else {
6424+ EG(hphp_log_syslog_facility) = atoi(new_value);
6425+ }
6426+ return SUCCESS;
6427+}
6428+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6429+{
6430+ if (!new_value) {
6431+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6432+ } else {
6433+ EG(hphp_log_syslog_priority) = atoi(new_value);
6434+ }
6435+ return SUCCESS;
6436+}
6437+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6438+{
6439+ if (!new_value) {
6440+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6441+ } else {
6442+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6443+ }
6444+ return SUCCESS;
6445+}
6446+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6447+{
6448+ if (!new_value) {
6449+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
6450+ } else {
6451+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6452+ }
6453+ return SUCCESS;
6454+}
6455+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6456+{
6457+ if (EG(hphp_log_scriptname)) {
6458+ pefree(EG(hphp_log_scriptname),1);
6459+ }
6460+ EG(hphp_log_scriptname) = NULL;
6461+ if (new_value) {
6462+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6463+ }
6464+ return SUCCESS;
6465+}
6466+
6467+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6468+{
6469+ char *s = NULL, *e, *val;
6470+ unsigned long dummy = 1;
6471+
6472+ if (!new_value) {
6473+include_whitelist_destroy:
6474+ if (HG(include_whitelist)) {
6475+ zend_hash_destroy(HG(include_whitelist));
6476+ pefree(HG(include_whitelist),1);
6477+ }
6478+ HG(include_whitelist) = NULL;
6479+ return SUCCESS;
6480+ }
6481+ if (!(*new_value)) {
6482+ goto include_whitelist_destroy;
6483+ }
6484+
6485+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6486+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6487+
6488+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6489+ e = val;
6490+
6491+ while (*e) {
6492+ switch (*e) {
6493+ case ' ':
6494+ case ',':
6495+ if (s) {
6496+ *e = '\0';
6497+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6498+ s = NULL;
6499+ }
6500+ break;
6501+ default:
6502+ if (!s) {
6503+ s = e;
6504+ }
6505+ break;
6506+ }
6507+ e++;
6508+ }
6509+ if (s) {
6510+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6511+ }
6512+ efree(val);
6513+
6514+ return SUCCESS;
6515+}
6516+
6517+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6518+{
6519+ char *s = NULL, *e, *val;
6520+ unsigned long dummy = 1;
6521+
6522+ if (!new_value) {
6523+include_blacklist_destroy:
6524+ if (HG(include_blacklist)) {
6525+ zend_hash_destroy(HG(include_blacklist));
6526+ pefree(HG(include_blacklist),1);
6527+ }
6528+ HG(include_blacklist) = NULL;
6529+ return SUCCESS;
6530+ }
6531+ if (!(*new_value)) {
6532+ goto include_blacklist_destroy;
6533+ }
6534+
6535+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6536+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6537+
6538+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6539+ e = val;
6540+
6541+ while (*e) {
6542+ switch (*e) {
6543+ case ' ':
6544+ case ',':
6545+ if (s) {
6546+ *e = '\0';
6547+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6548+ s = NULL;
6549+ }
6550+ break;
6551+ default:
6552+ if (!s) {
6553+ s = e;
6554+ }
6555+ break;
6556+ }
6557+ e++;
6558+ }
6559+ if (s) {
6560+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6561+ }
6562+ efree(val);
6563+
6564+ return SUCCESS;
6565+}
6566+
6567+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6568+{
6569+ char *s = NULL, *e, *val;
6570+ unsigned long dummy = 1;
6571+
6572+ if (!new_value) {
6573+eval_whitelist_destroy:
6574+ if (HG(eval_whitelist)) {
6575+ zend_hash_destroy(HG(eval_whitelist));
6576+ pefree(HG(eval_whitelist),1);
6577+ }
6578+ HG(eval_whitelist) = NULL;
6579+ return SUCCESS;
6580+ }
6581+ if (!(*new_value)) {
6582+ goto eval_whitelist_destroy;
6583+ }
6584+
6585+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6586+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6587+
6588+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6589+ e = val;
6590+
6591+ while (*e) {
6592+ switch (*e) {
6593+ case ' ':
6594+ case ',':
6595+ if (s) {
6596+ *e = '\0';
6597+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6598+ s = NULL;
6599+ }
6600+ break;
6601+ default:
6602+ if (!s) {
6603+ s = e;
6604+ }
6605+ break;
6606+ }
6607+ e++;
6608+ }
6609+ if (s) {
6610+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6611+ }
6612+ efree(val);
6613+
6614+ return SUCCESS;
6615+}
6616+
6617+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6618+{
6619+ char *s = NULL, *e, *val;
6620+ unsigned long dummy = 1;
6621+
6622+ if (!new_value) {
6623+eval_blacklist_destroy:
6624+ if (HG(eval_blacklist)) {
6625+ zend_hash_destroy(HG(eval_blacklist));
6626+ pefree(HG(eval_blacklist), 1);
6627+ }
6628+ HG(eval_blacklist) = NULL;
6629+ return SUCCESS;
6630+ }
6631+ if (!(*new_value)) {
6632+ goto eval_blacklist_destroy;
6633+ }
6634+
6635+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6636+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6637+
6638+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6639+ e = val;
6640+
6641+ while (*e) {
6642+ switch (*e) {
6643+ case ' ':
6644+ case ',':
6645+ if (s) {
6646+ *e = '\0';
6647+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6648+ s = NULL;
6649+ }
6650+ break;
6651+ default:
6652+ if (!s) {
6653+ s = e;
6654+ }
6655+ break;
6656+ }
6657+ e++;
6658+ }
6659+ if (s) {
6660+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6661+ }
6662+ efree(val);
6663+
6664+
6665+ return SUCCESS;
6666+}
6667+
6668+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6669+{
6670+ char *s = NULL, *e, *val;
6671+ unsigned long dummy = 1;
6672+
6673+ if (!new_value) {
6674+func_whitelist_destroy:
6675+ if (HG(func_whitelist)) {
6676+ zend_hash_destroy(HG(func_whitelist));
6677+ pefree(HG(func_whitelist),1);
6678+ }
6679+ HG(func_whitelist) = NULL;
6680+ return SUCCESS;
6681+ }
6682+ if (!(*new_value)) {
6683+ goto func_whitelist_destroy;
6684+ }
6685+
6686+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6687+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6688+
6689+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6690+ e = val;
6691+
6692+ while (*e) {
6693+ switch (*e) {
6694+ case ' ':
6695+ case ',':
6696+ if (s) {
6697+ *e = '\0';
6698+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6699+ s = NULL;
6700+ }
6701+ break;
6702+ default:
6703+ if (!s) {
6704+ s = e;
6705+ }
6706+ break;
6707+ }
6708+ e++;
6709+ }
6710+ if (s) {
6711+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6712+ }
6713+ efree(val);
6714+
6715+ return SUCCESS;
6716+}
6717+
6718+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6719+{
6720+ char *s = NULL, *e, *val;
6721+ unsigned long dummy = 1;
6722+
6723+ if (!new_value) {
6724+func_blacklist_destroy:
6725+ if (HG(func_blacklist)) {
6726+ zend_hash_destroy(HG(func_blacklist));
6727+ pefree(HG(func_blacklist),1);
6728+ }
6729+ HG(func_blacklist) = NULL;
6730+ return SUCCESS;
6731+ }
6732+ if (!(*new_value)) {
6733+ goto func_blacklist_destroy;
6734+ }
6735+
6736+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6737+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6738+
6739+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6740+ e = val;
6741+
6742+ while (*e) {
6743+ switch (*e) {
6744+ case ' ':
6745+ case ',':
6746+ if (s) {
6747+ *e = '\0';
6748+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6749+ s = NULL;
6750+ }
6751+ break;
6752+ default:
6753+ if (!s) {
6754+ s = e;
6755+ }
6756+ break;
6757+ }
6758+ e++;
6759+ }
6760+ if (s) {
6761+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6762+ }
6763+ efree(val);
6764+
6765+
6766+ return SUCCESS;
6767+}
6768+
6769+#endif
6770
6771 ZEND_INI_BEGIN()
6772 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6773+#if HARDENING_PATCH
6774+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6775+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6776+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6777+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6778+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6779+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6780+ 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)
6781+
6782+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6783+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6784+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6785+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6786+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6787+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6788+
6789+ 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)
6790+ 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)
6791+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6792+#endif
6793 ZEND_INI_END()
6794
6795
6796@@ -354,8 +741,12 @@
6797 zend_init_rsrc_plist(TSRMLS_C);
6798 EG(lambda_count)=0;
6799 EG(user_error_handler) = NULL;
6800+ EG(in_code_type) = 0;
6801 EG(in_execution) = 0;
6802 EG(current_execute_data) = NULL;
6803+#if HARDENING_PATCH
6804+ EG(hphp_log_scriptname) = NULL;
6805+#endif
6806 }
6807
6808
6809@@ -420,6 +811,14 @@
6810 extern zend_scanner_globals language_scanner_globals;
6811 #endif
6812
6813+ /* Set up Hardening-Patch utility functions first */
6814+#if HARDENING_PATCH
6815+ zend_security_log = utility_functions->security_log_function;
6816+#endif
6817+#if HARDENING_PATCH_INC_PROTECT
6818+ zend_is_valid_include = utility_functions->is_valid_include;
6819+#endif
6820+
6821 #ifdef ZTS
6822 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6823 #else
6824@@ -619,6 +1018,7 @@
6825 }
6826 CG(unclean_shutdown) = 1;
6827 CG(in_compilation) = EG(in_execution) = 0;
6828+ EG(in_code_type) = 0;
6829 EG(current_execute_data) = NULL;
6830 longjmp(EG(bailout), FAILURE);
6831 }
6832diff -Nura php-4.4.2/Zend/zend_canary.c hardening-patch-4.4.2-0.4.8/Zend/zend_canary.c
6833--- php-4.4.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6834+++ hardening-patch-4.4.2-0.4.8/Zend/zend_canary.c 2006-01-18 12:43:26.935204440 +0100
6835@@ -0,0 +1,58 @@
6836+/*
6837+ +----------------------------------------------------------------------+
6838+ | Hardening-Patch for PHP |
6839+ +----------------------------------------------------------------------+
6840+ | Copyright (c) 2004-2005 Stefan Esser |
6841+ +----------------------------------------------------------------------+
6842+ | This source file is subject to version 2.02 of the PHP license, |
6843+ | that is bundled with this package in the file LICENSE, and is |
6844+ | available at through the world-wide-web at |
6845+ | http://www.php.net/license/2_02.txt. |
6846+ | If you did not receive a copy of the PHP license and are unable to |
6847+ | obtain it through the world-wide-web, please send a note to |
6848+ | license@php.net so we can mail you a copy immediately. |
6849+ +----------------------------------------------------------------------+
6850+ | Author: Stefan Esser <sesser@hardened-php.net> |
6851+ +----------------------------------------------------------------------+
6852+ */
6853+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6854+
6855+#include "zend.h"
6856+
6857+#include <stdio.h>
6858+#include <stdlib.h>
6859+
6860+
6861+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6862+
6863+/* will be replaced later with more compatible method */
6864+ZEND_API unsigned int zend_canary()
6865+{
6866+ time_t t;
6867+ unsigned int canary;
6868+ int fd;
6869+
6870+ fd = open("/dev/urandom", 0);
6871+ if (fd != -1) {
6872+ int r = read(fd, &canary, sizeof(canary));
6873+ close(fd);
6874+ if (r == sizeof(canary)) {
6875+ return (canary);
6876+ }
6877+ }
6878+ /* not good but we never want to do this */
6879+ time(&t);
6880+ canary = *(unsigned int *)&t + getpid() << 16;
6881+ return (canary);
6882+}
6883+#endif
6884+
6885+
6886+/*
6887+ * Local variables:
6888+ * tab-width: 4
6889+ * c-basic-offset: 4
6890+ * End:
6891+ * vim600: sw=4 ts=4 fdm=marker
6892+ * vim<600: sw=4 ts=4
6893+ */
6894diff -Nura php-4.4.2/Zend/zend_compile.c hardening-patch-4.4.2-0.4.8/Zend/zend_compile.c
6895--- php-4.4.2/Zend/zend_compile.c 2006-01-01 14:46:49.000000000 +0100
6896+++ hardening-patch-4.4.2-0.4.8/Zend/zend_compile.c 2006-01-18 12:43:26.936204288 +0100
6897@@ -768,6 +768,13 @@
6898 op_array.function_name = name;
6899 op_array.arg_types = NULL;
6900 op_array.return_reference = return_reference;
6901+#if HARDENING_PATCH
6902+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6903+ op_array.created_by_eval = 1;
6904+ } else {
6905+ op_array.created_by_eval = 0;
6906+ }
6907+#endif
6908
6909 if (is_method) {
6910 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) {
6911diff -Nura php-4.4.2/Zend/zend_compile.h hardening-patch-4.4.2-0.4.8/Zend/zend_compile.h
6912--- php-4.4.2/Zend/zend_compile.h 2006-01-01 14:46:49.000000000 +0100
6913+++ hardening-patch-4.4.2-0.4.8/Zend/zend_compile.h 2006-01-18 12:43:26.937204136 +0100
6914@@ -106,6 +106,9 @@
6915 char *filename;
6916
6917 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6918+#if HARDENING_PATCH
6919+ zend_bool created_by_eval;
6920+#endif
6921 };
6922
6923
6924@@ -549,6 +552,7 @@
6925 #define ZEND_USER_FUNCTION 2
6926 #define ZEND_OVERLOADED_FUNCTION 3
6927 #define ZEND_EVAL_CODE 4
6928+#define ZEND_SANDBOX_CODE 6
6929
6930 #define ZEND_INTERNAL_CLASS 1
6931 #define ZEND_USER_CLASS 2
6932diff -Nura php-4.4.2/Zend/zend_constants.c hardening-patch-4.4.2-0.4.8/Zend/zend_constants.c
6933--- php-4.4.2/Zend/zend_constants.c 2006-01-01 14:46:49.000000000 +0100
6934+++ hardening-patch-4.4.2-0.4.8/Zend/zend_constants.c 2006-01-18 12:43:26.938203984 +0100
6935@@ -111,6 +111,73 @@
6936 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6937
6938 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6939+#if HARDENING_PATCH
6940+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6941+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6942+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6943+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6944+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6945+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6946+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6947+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6948+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6949+
6950+ /* error levels */
6951+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6952+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6953+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6954+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6955+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6956+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6957+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6958+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6959+ /* facility: type of program logging the message */
6960+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6961+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6962+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6963+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6964+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6965+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6966+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6967+#ifdef LOG_NEWS
6968+ /* No LOG_NEWS on HP-UX */
6969+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6970+#endif
6971+#ifdef LOG_UUCP
6972+ /* No LOG_UUCP on HP-UX */
6973+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6974+#endif
6975+#ifdef LOG_CRON
6976+ /* apparently some systems don't have this one */
6977+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6978+#endif
6979+#ifdef LOG_AUTHPRIV
6980+ /* AIX doesn't have LOG_AUTHPRIV */
6981+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
6982+#endif
6983+#if !defined(PHP_WIN32) && !defined(NETWARE)
6984+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
6985+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
6986+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
6987+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
6988+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
6989+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
6990+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
6991+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
6992+#endif
6993+ /* options */
6994+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
6995+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
6996+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
6997+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
6998+#ifdef LOG_NOWAIT
6999+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
7000+#endif
7001+#ifdef LOG_PERROR
7002+ /* AIX doesn't have LOG_PERROR */
7003+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
7004+#endif
7005+#endif
7006
7007 /* true/false constants */
7008 {
7009diff -Nura php-4.4.2/Zend/zend_errors.h hardening-patch-4.4.2-0.4.8/Zend/zend_errors.h
7010--- php-4.4.2/Zend/zend_errors.h 2006-01-01 14:46:49.000000000 +0100
7011+++ hardening-patch-4.4.2-0.4.8/Zend/zend_errors.h 2006-01-18 12:43:26.938203984 +0100
7012@@ -36,5 +36,17 @@
7013 #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)
7014 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
7015
7016+#if HARDENING_PATCH
7017+#define S_MEMORY (1<<0L)
7018+#define S_VARS (1<<1L)
7019+#define S_FILES (1<<2L)
7020+#define S_INCLUDE (1<<3L)
7021+#define S_SQL (1<<4L)
7022+#define S_EXECUTOR (1<<5L)
7023+#define S_MISC (1<<30L)
7024+#define S_INTERNAL (1<<29L)
7025+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
7026+#endif
7027+
7028 #endif /* ZEND_ERRORS_H */
7029
7030diff -Nura php-4.4.2/Zend/zend_execute_API.c hardening-patch-4.4.2-0.4.8/Zend/zend_execute_API.c
7031--- php-4.4.2/Zend/zend_execute_API.c 2006-01-01 14:46:49.000000000 +0100
7032+++ hardening-patch-4.4.2-0.4.8/Zend/zend_execute_API.c 2006-01-18 12:43:26.939203832 +0100
7033@@ -142,6 +142,7 @@
7034 EG(class_table) = CG(class_table);
7035
7036 EG(in_execution) = 0;
7037+ EG(in_code_type) = 0;
7038
7039 zend_ptr_stack_init(&EG(argument_stack));
7040
7041@@ -431,12 +432,14 @@
7042 zend_execute_data execute_data;
7043
7044 /* Initialize execute_data */
7045+ memset(&execute_data, 0, sizeof(execute_data));
7046 EX(fbc) = NULL;
7047 EX(object).ptr = NULL;
7048 EX(ce) = NULL;
7049 EX(Ts) = NULL;
7050 EX(op_array) = NULL;
7051 EX(opline) = NULL;
7052+ EX(execute_depth) = 0;
7053
7054 *retval_ptr_ptr = NULL;
7055
7056@@ -494,6 +497,39 @@
7057 zval_dtor(&function_name_copy);
7058 return FAILURE;
7059 }
7060+#if HARDENING_PATCH
7061+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
7062+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7063+ if (HG(eval_whitelist) != NULL) {
7064+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7065+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
7066+ zval_dtor(&function_name_copy);
7067+ zend_bailout();
7068+ }
7069+ } else if (HG(eval_blacklist) != NULL) {
7070+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7071+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
7072+ zval_dtor(&function_name_copy);
7073+ zend_bailout();
7074+ }
7075+ }
7076+ }
7077+
7078+ if (HG(func_whitelist) != NULL) {
7079+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7080+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
7081+ zval_dtor(&function_name_copy);
7082+ zend_bailout();
7083+ }
7084+ } else if (HG(func_blacklist) != NULL) {
7085+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
7086+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
7087+ zval_dtor(&function_name_copy);
7088+ zend_bailout();
7089+ }
7090+ }
7091+ }
7092+#endif
7093 zval_dtor(&function_name_copy);
7094
7095 for (i=0; i<param_count; i++) {
7096@@ -606,8 +642,7 @@
7097 return SUCCESS;
7098 }
7099
7100-
7101-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7102+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
7103 {
7104 zval pv;
7105 zend_op_array *new_op_array;
7106@@ -640,6 +675,7 @@
7107 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
7108 zend_op **original_opline_ptr = EG(opline_ptr);
7109
7110+ new_op_array->type = type;
7111 EG(return_value_ptr_ptr) = &local_retval_ptr;
7112 EG(active_op_array) = new_op_array;
7113 EG(no_extensions)=1;
7114@@ -673,6 +709,10 @@
7115 return retval;
7116 }
7117
7118+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
7119+{
7120+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
7121+}
7122
7123 void execute_new_code(TSRMLS_D)
7124 {
7125diff -Nura php-4.4.2/Zend/zend_execute.c hardening-patch-4.4.2-0.4.8/Zend/zend_execute.c
7126--- php-4.4.2/Zend/zend_execute.c 2006-01-01 14:46:49.000000000 +0100
7127+++ hardening-patch-4.4.2-0.4.8/Zend/zend_execute.c 2006-01-18 12:43:26.940203680 +0100
7128@@ -1042,6 +1042,7 @@
7129 zend_execute_data execute_data;
7130
7131 /* Initialize execute_data */
7132+ memset(&execute_data, 0, sizeof(execute_data));
7133 EX(fbc) = NULL;
7134 EX(ce) = NULL;
7135 EX(object).ptr = NULL;
7136@@ -1053,9 +1054,21 @@
7137 }
7138 EX(prev_execute_data) = EG(current_execute_data);
7139 EX(original_in_execution)=EG(in_execution);
7140+ EX(original_in_code_type)=EG(in_code_type);
7141
7142 EG(current_execute_data) = &execute_data;
7143
7144+#if HARDENING_PATCH
7145+ EX(execute_depth) = 0;
7146+
7147+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
7148+ EG(in_code_type) = ZEND_EVAL_CODE;
7149+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7150+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7151+ op_array->type = ZEND_EVAL_CODE;
7152+ }
7153+#endif
7154+
7155 EG(in_execution) = 1;
7156 if (op_array->start_op) {
7157 EX(opline) = op_array->start_op;
7158@@ -1087,6 +1100,19 @@
7159 }
7160 }
7161
7162+#if HARDENING_PATCH
7163+ if (EX(prev_execute_data) == NULL) {
7164+ EX(execute_depth) = 0;
7165+ } else {
7166+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7167+ }
7168+
7169+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7170+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7171+ zend_bailout();
7172+ }
7173+#endif
7174+
7175 while (1) {
7176 #ifdef ZEND_WIN32
7177 if (EG(timed_out)) {
7178@@ -1634,6 +1660,36 @@
7179 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
7180 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
7181 }
7182+#if HARDENING_PATCH
7183+ if (active_function_table == EG(function_table)) {
7184+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7185+ if (HG(eval_whitelist) != NULL) {
7186+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7187+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
7188+ zend_bailout();
7189+ }
7190+ } else if (HG(eval_blacklist) != NULL) {
7191+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7192+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
7193+ zend_bailout();
7194+ }
7195+ }
7196+ }
7197+
7198+ if (HG(func_whitelist) != NULL) {
7199+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
7200+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
7201+ zend_bailout();
7202+ }
7203+ } else if (HG(func_blacklist) != NULL) {
7204+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
7205+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
7206+ zend_bailout();
7207+ }
7208+ }
7209+ }
7210+#endif
7211+
7212 zval_dtor(&tmp);
7213 EX(fbc) = function;
7214 overloaded_function_call_cont:
7215@@ -1649,6 +1705,35 @@
7216 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7217 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7218 }
7219+#if HARDENING_PATCH
7220+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
7221+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7222+ if (HG(eval_whitelist) != NULL) {
7223+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7224+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7225+ zend_bailout();
7226+ }
7227+ } else if (HG(eval_blacklist) != NULL) {
7228+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7229+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7230+ zend_bailout();
7231+ }
7232+ }
7233+ }
7234+
7235+ if (HG(func_whitelist) != NULL) {
7236+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7237+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7238+ zend_bailout();
7239+ }
7240+ } else if (HG(func_blacklist) != NULL) {
7241+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7242+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7243+ zend_bailout();
7244+ }
7245+ }
7246+ }
7247+#endif
7248 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
7249 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
7250 EX(object).ptr = NULL;
7251@@ -1821,6 +1906,7 @@
7252 efree(EX(Ts));
7253 }
7254 EG(in_execution) = EX(original_in_execution);
7255+ EG(in_code_type) = EX(original_in_code_type);
7256 EG(current_execute_data) = EX(prev_execute_data);
7257 return;
7258 }
7259@@ -2210,7 +2296,12 @@
7260 int dummy = 1;
7261 zend_file_handle file_handle = {0};
7262
7263+#if HARDENING_PATCH_INC_PROTECT
7264+ if (zend_is_valid_include(inc_filename)
7265+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7266+#else
7267 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
7268+#endif
7269 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
7270
7271 file_handle.filename = inc_filename->value.str.val;
7272@@ -2239,6 +2330,11 @@
7273 break;
7274 case ZEND_INCLUDE:
7275 case ZEND_REQUIRE:
7276+#if HARDENING_PATCH_INC_PROTECT
7277+ if (!zend_is_valid_include(inc_filename)) {
7278+ break;
7279+ }
7280+#endif
7281 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7282 break;
7283 case ZEND_EVAL: {
7284diff -Nura php-4.4.2/Zend/zend_execute_globals.h hardening-patch-4.4.2-0.4.8/Zend/zend_execute_globals.h
7285--- php-4.4.2/Zend/zend_execute_globals.h 2006-01-01 14:46:49.000000000 +0100
7286+++ hardening-patch-4.4.2-0.4.8/Zend/zend_execute_globals.h 2006-01-18 12:43:26.941203528 +0100
7287@@ -60,6 +60,8 @@
7288 object_info object;
7289 temp_variable *Ts;
7290 zend_bool original_in_execution;
7291+ zend_uint original_in_code_type;
7292+ zend_uint execute_depth;
7293 zend_op_array *op_array;
7294 struct _zend_execute_data *prev_execute_data;
7295 } zend_execute_data;
7296diff -Nura php-4.4.2/Zend/zend_extensions.c hardening-patch-4.4.2-0.4.8/Zend/zend_extensions.c
7297--- php-4.4.2/Zend/zend_extensions.c 2006-01-01 14:46:49.000000000 +0100
7298+++ hardening-patch-4.4.2-0.4.8/Zend/zend_extensions.c 2006-01-18 12:43:26.941203528 +0100
7299@@ -54,23 +54,44 @@
7300 return FAILURE;
7301 }
7302
7303+ /* check if module is compiled against Hardening-Patch */
7304+ if (extension_version_info->zend_extension_api_no < 1000000000) {
7305+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
7306+ "The Hardening-Patch version %d is installed.\n\n",
7307+ new_extension->name,
7308+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7309+ DL_UNLOAD(handle);
7310+ return FAILURE;
7311+ }
7312+
7313+
7314+ /* check if module is compiled against correct Hardening-Patch version */
7315+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
7316+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
7317+ "The Hardening-Patch version %d is installed.\n\n",
7318+ new_extension->name,
7319+ extension_version_info->zend_extension_api_no,
7320+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7321+ DL_UNLOAD(handle);
7322+ return FAILURE;
7323+ }
7324
7325 /* allow extension to proclaim compatibility with any Zend version */
7326- 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)) {
7327- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7328+ 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)) {
7329+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7330 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7331 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7332 new_extension->name,
7333- extension_version_info->zend_extension_api_no,
7334+ extension_version_info->real_zend_extension_api_no,
7335 ZEND_EXTENSION_API_NO);
7336 DL_UNLOAD(handle);
7337 return FAILURE;
7338- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7339+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7340 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7341 "The Zend Engine API version %d which is installed, is newer.\n"
7342 "Contact %s at %s for a later version of %s.\n\n",
7343 new_extension->name,
7344- extension_version_info->zend_extension_api_no,
7345+ extension_version_info->real_zend_extension_api_no,
7346 ZEND_EXTENSION_API_NO,
7347 new_extension->author,
7348 new_extension->URL,
7349diff -Nura php-4.4.2/Zend/zend_extensions.h hardening-patch-4.4.2-0.4.8/Zend/zend_extensions.h
7350--- php-4.4.2/Zend/zend_extensions.h 2006-01-01 14:46:49.000000000 +0100
7351+++ hardening-patch-4.4.2-0.4.8/Zend/zend_extensions.h 2006-01-18 12:43:26.942203376 +0100
7352@@ -23,6 +23,9 @@
7353
7354 #include "zend_compile.h"
7355
7356+/* Create own API version number for Hardening-Patch */
7357+
7358+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
7359 #define ZEND_EXTENSION_API_NO 20050606
7360
7361 typedef struct _zend_extension_version_info {
7362@@ -30,6 +33,7 @@
7363 char *required_zend_version;
7364 unsigned char thread_safe;
7365 unsigned char debug;
7366+ int real_zend_extension_api_no;
7367 } zend_extension_version_info;
7368
7369
7370@@ -96,7 +100,7 @@
7371
7372
7373 #define ZEND_EXTENSION() \
7374- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7375+ 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 }
7376
7377 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7378 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7379diff -Nura php-4.4.2/Zend/zend_globals.h hardening-patch-4.4.2-0.4.8/Zend/zend_globals.h
7380--- php-4.4.2/Zend/zend_globals.h 2006-01-01 14:46:49.000000000 +0100
7381+++ hardening-patch-4.4.2-0.4.8/Zend/zend_globals.h 2006-01-18 12:43:26.942203376 +0100
7382@@ -163,6 +163,16 @@
7383
7384 int error_reporting;
7385 int orig_error_reporting;
7386+#if HARDENING_PATCH
7387+ int hphp_log_syslog;
7388+ int hphp_log_syslog_facility;
7389+ int hphp_log_syslog_priority;
7390+ int hphp_log_sapi;
7391+ int hphp_log_script;
7392+ char *hphp_log_scriptname;
7393+ zend_bool hphp_log_use_x_forwarded_for;
7394+ long hphp_executor_max_depth;
7395+#endif
7396 int exit_status;
7397
7398 zend_op_array *active_op_array;
7399@@ -176,6 +186,7 @@
7400 int ticks_count;
7401
7402 zend_bool in_execution;
7403+ zend_uint in_code_type;
7404 zend_bool bailout_set;
7405 zend_bool full_tables_cleanup;
7406
7407diff -Nura php-4.4.2/Zend/zend.h hardening-patch-4.4.2-0.4.8/Zend/zend.h
7408--- php-4.4.2/Zend/zend.h 2006-01-01 14:46:49.000000000 +0100
7409+++ hardening-patch-4.4.2-0.4.8/Zend/zend.h 2006-01-18 12:43:26.943203224 +0100
7410@@ -274,9 +274,10 @@
7411 struct _zval_struct {
7412 /* Variable information */
7413 zvalue_value value; /* value */
7414+ zend_uint refcount;
7415+ zend_ushort flags;
7416 zend_uchar type; /* active type */
7417 zend_uchar is_ref;
7418- zend_ushort refcount;
7419 };
7420
7421
7422@@ -337,6 +338,12 @@
7423 void (*ticks_function)(int ticks);
7424 void (*on_timeout)(int seconds TSRMLS_DC);
7425 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
7426+#if HARDENING_PATCH
7427+ void (*security_log_function)(int loglevel, char *fmt, ...);
7428+#endif
7429+#if HARDENING_PATCH_INC_PROTECT
7430+ int (*is_valid_include)(zval *z);
7431+#endif
7432 } zend_utility_functions;
7433
7434
7435@@ -468,7 +475,16 @@
7436 extern ZEND_API void (*zend_ticks_function)(int ticks);
7437 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);
7438 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
7439+#if HARDENING_PATCH
7440+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7441+#endif
7442+#if HARDENING_PATCH_INC_PROTECT
7443+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7444+#endif
7445
7446+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7447+ZEND_API unsigned int zend_canary(void);
7448+#endif
7449
7450 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
7451
7452@@ -575,6 +591,11 @@
7453
7454 #define ZEND_MAX_RESERVED_RESOURCES 4
7455
7456+#if HARDENING_PATCH
7457+#include "hardened_globals.h"
7458+#include "php_syslog.h"
7459+#endif
7460+
7461 #endif /* ZEND_H */
7462
7463 /*
7464diff -Nura php-4.4.2/Zend/zend_hash.c hardening-patch-4.4.2-0.4.8/Zend/zend_hash.c
7465--- php-4.4.2/Zend/zend_hash.c 2006-01-01 14:46:49.000000000 +0100
7466+++ hardening-patch-4.4.2-0.4.8/Zend/zend_hash.c 2006-01-18 12:43:26.944203072 +0100
7467@@ -26,6 +26,17 @@
7468 # include <stdlib.h>
7469 #endif
7470
7471+#if HARDENING_PATCH_HASH_PROTECT
7472+ unsigned int zend_hash_canary = 0x1234567;
7473+ zend_bool zend_hash_canary_inited = 0;
7474+#endif
7475+
7476+#define CHECK_HASH_CANARY(hash) \
7477+ if (zend_hash_canary != (hash)->canary) { \
7478+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7479+ exit(1); \
7480+ }
7481+
7482 #define HANDLE_NUMERIC(key, length, func) { \
7483 register char *tmp=key; \
7484 \
7485@@ -175,6 +186,9 @@
7486 {
7487 uint i = 3;
7488 Bucket **tmp;
7489+#if HARDENING_PATCH_HASH_PROTECT
7490+ TSRMLS_FETCH();
7491+#endif
7492
7493 SET_INCONSISTENT(HT_OK);
7494
7495@@ -184,6 +198,13 @@
7496
7497 ht->nTableSize = 1 << i;
7498 ht->nTableMask = ht->nTableSize - 1;
7499+#if HARDENING_PATCH_HASH_PROTECT
7500+ if (zend_hash_canary_inited==0) {
7501+ zend_hash_canary = zend_canary();
7502+ zend_hash_canary_inited = 1;
7503+ }
7504+ ht->canary = zend_hash_canary;
7505+#endif
7506 ht->pDestructor = pDestructor;
7507 ht->pListHead = NULL;
7508 ht->pListTail = NULL;
7509@@ -259,6 +280,9 @@
7510 }
7511 #endif
7512 if (ht->pDestructor) {
7513+#if HARDENING_PATCH_HASH_PROTECT
7514+ CHECK_HASH_CANARY(ht);
7515+#endif
7516 ht->pDestructor(p->pData);
7517 }
7518 UPDATE_DATA(ht, p, pData, nDataSize);
7519@@ -327,6 +351,9 @@
7520 }
7521 #endif
7522 if (ht->pDestructor) {
7523+#if HARDENING_PATCH_HASH_PROTECT
7524+ CHECK_HASH_CANARY(ht);
7525+#endif
7526 ht->pDestructor(p->pData);
7527 }
7528 UPDATE_DATA(ht, p, pData, nDataSize);
7529@@ -402,6 +429,9 @@
7530 }
7531 #endif
7532 if (ht->pDestructor) {
7533+#if HARDENING_PATCH_HASH_PROTECT
7534+ CHECK_HASH_CANARY(ht);
7535+#endif
7536 ht->pDestructor(p->pData);
7537 }
7538 UPDATE_DATA(ht, p, pData, nDataSize);
7539@@ -450,7 +480,7 @@
7540 IS_CONSISTENT(ht);
7541
7542 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7543- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7544+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7545 if (t) {
7546 HANDLE_BLOCK_INTERRUPTIONS();
7547 ht->arBuckets = t;
7548@@ -460,6 +490,7 @@
7549 HANDLE_UNBLOCK_INTERRUPTIONS();
7550 return SUCCESS;
7551 }
7552+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7553 return FAILURE;
7554 }
7555 return SUCCESS;
7556@@ -524,6 +555,9 @@
7557 ht->pInternalPointer = p->pListNext;
7558 }
7559 if (ht->pDestructor) {
7560+#if HARDENING_PATCH_HASH_PROTECT
7561+ CHECK_HASH_CANARY(ht);
7562+#endif
7563 ht->pDestructor(p->pData);
7564 }
7565 if (!p->pDataPtr) {
7566@@ -553,6 +587,9 @@
7567 q = p;
7568 p = p->pListNext;
7569 if (ht->pDestructor) {
7570+#if HARDENING_PATCH_HASH_PROTECT
7571+ CHECK_HASH_CANARY(ht);
7572+#endif
7573 ht->pDestructor(q->pData);
7574 }
7575 if (!q->pDataPtr && q->pData) {
7576@@ -579,6 +616,9 @@
7577 q = p;
7578 p = p->pListNext;
7579 if (ht->pDestructor) {
7580+#if HARDENING_PATCH_HASH_PROTECT
7581+ CHECK_HASH_CANARY(ht);
7582+#endif
7583 ht->pDestructor(q->pData);
7584 }
7585 if (!q->pDataPtr && q->pData) {
7586@@ -608,6 +648,9 @@
7587 HANDLE_BLOCK_INTERRUPTIONS();
7588
7589 if (ht->pDestructor) {
7590+#if HARDENING_PATCH_HASH_PROTECT
7591+ CHECK_HASH_CANARY(ht);
7592+#endif
7593 ht->pDestructor(p->pData);
7594 }
7595 if (!p->pDataPtr) {
7596diff -Nura php-4.4.2/Zend/zend_hash.h hardening-patch-4.4.2-0.4.8/Zend/zend_hash.h
7597--- php-4.4.2/Zend/zend_hash.h 2006-01-01 14:46:49.000000000 +0100
7598+++ hardening-patch-4.4.2-0.4.8/Zend/zend_hash.h 2006-01-18 12:43:26.944203072 +0100
7599@@ -54,6 +54,9 @@
7600 } Bucket;
7601
7602 typedef struct _hashtable {
7603+#if HARDENING_PATCH_HASH_PROTECT
7604+ unsigned int canary;
7605+#endif
7606 uint nTableSize;
7607 uint nTableMask;
7608 uint nNumOfElements;
7609diff -Nura php-4.4.2/Zend/zend_ini.h hardening-patch-4.4.2-0.4.8/Zend/zend_ini.h
7610--- php-4.4.2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7611+++ hardening-patch-4.4.2-0.4.8/Zend/zend_ini.h 2006-01-18 12:43:26.945202920 +0100
7612@@ -174,6 +174,7 @@
7613 /* Standard message handlers */
7614 BEGIN_EXTERN_C()
7615 ZEND_API ZEND_INI_MH(OnUpdateBool);
7616+#define OnUpdateLong OnUpdateInt
7617 ZEND_API ZEND_INI_MH(OnUpdateInt);
7618 ZEND_API ZEND_INI_MH(OnUpdateReal);
7619 ZEND_API ZEND_INI_MH(OnUpdateString);
7620diff -Nura php-4.4.2/Zend/zend_language_scanner.l hardening-patch-4.4.2-0.4.8/Zend/zend_language_scanner.l
7621--- php-4.4.2/Zend/zend_language_scanner.l 2006-01-01 14:46:49.000000000 +0100
7622+++ hardening-patch-4.4.2-0.4.8/Zend/zend_language_scanner.l 2006-01-18 12:43:26.946202768 +0100
7623@@ -393,6 +393,13 @@
7624 compilation_successful=0;
7625 } else {
7626 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7627+#if HARDENING_PATCH
7628+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7629+ op_array->created_by_eval = 1;
7630+ } else {
7631+ op_array->created_by_eval = 0;
7632+ }
7633+#endif
7634 CG(in_compilation) = 1;
7635 CG(active_op_array) = op_array;
7636 compiler_result = zendparse(TSRMLS_C);
7637diff -Nura php-4.4.2/Zend/zend_language_scanner.c hardening-patch-4.4.2-0.4.8/Zend/zend_language_scanner.c
7638--- php-4.4.2/Zend/zend_language_scanner.c 2006-01-12 19:24:28.000000000 +0100
7639+++ hardening-patch-4.4.2-0.4.8/Zend/zend_language_scanner.c 2006-01-18 12:43:26.949202312 +0100
7640@@ -3036,6 +3036,13 @@
7641 compilation_successful=0;
7642 } else {
7643 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7644+#if HARDENING_PATCH
7645+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7646+ op_array->created_by_eval = 1;
7647+ } else {
7648+ op_array->created_by_eval = 0;
7649+ }
7650+#endif
7651 CG(in_compilation) = 1;
7652 CG(active_op_array) = op_array;
7653 compiler_result = zendparse(TSRMLS_C);
7654diff -Nura php-4.4.2/Zend/zend_llist.c hardening-patch-4.4.2-0.4.8/Zend/zend_llist.c
7655--- php-4.4.2/Zend/zend_llist.c 2006-01-01 14:46:49.000000000 +0100
7656+++ hardening-patch-4.4.2-0.4.8/Zend/zend_llist.c 2006-01-18 12:43:26.950202160 +0100
7657@@ -21,9 +21,49 @@
7658 #include "zend.h"
7659 #include "zend_llist.h"
7660 #include "zend_qsort.h"
7661+#include "zend_globals.h"
7662+
7663+#if HARDENING_PATCH_LL_PROTECT
7664+ unsigned int zend_llist_canary_1 = 0x1234567;
7665+ unsigned int zend_llist_canary_2 = 0x1553425;
7666+ zend_bool zend_llist_canary_inited = 0;
7667+#endif
7668+
7669+#define CHECK_LIST_CANARY(list) \
7670+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7671+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7672+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7673+ exit(1); \
7674+ }
7675+
7676+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7677+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7678+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7679+ exit(1); \
7680+ }
7681+
7682
7683 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7684 {
7685+#if HARDENING_PATCH_LL_PROTECT
7686+ TSRMLS_FETCH();
7687+
7688+ if (persistent) {
7689+ if (!zend_llist_canary_inited) {
7690+ /* do not change order to ensure thread safety */
7691+ zend_llist_canary_1 = zend_canary();
7692+ zend_llist_canary_2 = zend_canary();
7693+ zend_llist_canary_inited = 1;
7694+ }
7695+ } else
7696+ if (!HG(ll_canary_inited)) {
7697+ HG(canary_3) = zend_canary();
7698+ HG(canary_4) = zend_canary();
7699+ HG(ll_canary_inited) = 1;
7700+ }
7701+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7702+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7703+#endif
7704 l->head = NULL;
7705 l->tail = NULL;
7706 l->count = 0;
7707@@ -37,6 +77,11 @@
7708 {
7709 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7710
7711+#if HARDENING_PATCH_LL_PROTECT
7712+ TSRMLS_FETCH();
7713+ CHECK_LIST_CANARY(l)
7714+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7715+#endif
7716 tmp->prev = l->tail;
7717 tmp->next = NULL;
7718 if (l->tail) {
7719@@ -55,6 +100,11 @@
7720 {
7721 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7722
7723+#if HARDENING_PATCH_LL_PROTECT
7724+ TSRMLS_FETCH();
7725+ CHECK_LIST_CANARY(l)
7726+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7727+#endif
7728 tmp->next = l->head;
7729 tmp->prev = NULL;
7730 if (l->head) {
7731@@ -91,10 +141,20 @@
7732 zend_llist_element *current=l->head;
7733 zend_llist_element *next;
7734
7735+#if HARDENING_PATCH_LL_PROTECT
7736+ TSRMLS_FETCH();
7737+ CHECK_LIST_CANARY(l)
7738+#endif
7739 while (current) {
7740+#if HARDENING_PATCH_LL_PROTECT
7741+ CHECK_LISTELEMENT_CANARY(current, l)
7742+#endif
7743 next = current->next;
7744 if (compare(current->data, element)) {
7745 DEL_LLIST_ELEMENT(current, l);
7746+#if HARDENING_PATCH_LL_PROTECT
7747+ current->canary = 0;
7748+#endif
7749 break;
7750 }
7751 current = next;
7752@@ -106,7 +166,14 @@
7753 {
7754 zend_llist_element *current=l->head, *next;
7755
7756+#if HARDENING_PATCH_LL_PROTECT
7757+ TSRMLS_FETCH();
7758+ CHECK_LIST_CANARY(l)
7759+#endif
7760 while (current) {
7761+#if HARDENING_PATCH_LL_PROTECT
7762+ CHECK_LISTELEMENT_CANARY(current, l)
7763+#endif
7764 next = current->next;
7765 if (l->dtor) {
7766 l->dtor(current->data);
7767@@ -131,7 +198,14 @@
7768 zend_llist_element *old_tail;
7769 void *data;
7770
7771+#if HARDENING_PATCH_LL_PROTECT
7772+ TSRMLS_FETCH();
7773+ CHECK_LIST_CANARY(l)
7774+#endif
7775 if ((old_tail = l->tail)) {
7776+#if HARDENING_PATCH_LL_PROTECT
7777+ CHECK_LISTELEMENT_CANARY(old_tail, l)
7778+#endif
7779 if (l->tail->prev) {
7780 l->tail->prev->next = NULL;
7781 }
7782@@ -157,9 +231,16 @@
7783 {
7784 zend_llist_element *ptr;
7785
7786+#if HARDENING_PATCH_LL_PROTECT
7787+ TSRMLS_FETCH();
7788+ CHECK_LIST_CANARY(src)
7789+#endif
7790 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7791 ptr = src->head;
7792 while (ptr) {
7793+#if HARDENING_PATCH_LL_PROTECT
7794+ CHECK_LISTELEMENT_CANARY(ptr, src)
7795+#endif
7796 zend_llist_add_element(dst, ptr->data);
7797 ptr = ptr->next;
7798 }
7799@@ -170,11 +251,21 @@
7800 {
7801 zend_llist_element *element, *next;
7802
7803+#if HARDENING_PATCH_LL_PROTECT
7804+ TSRMLS_FETCH();
7805+ CHECK_LIST_CANARY(l)
7806+#endif
7807 element=l->head;
7808 while (element) {
7809+#if HARDENING_PATCH_LL_PROTECT
7810+ CHECK_LISTELEMENT_CANARY(element, l)
7811+#endif
7812 next = element->next;
7813 if (func(element->data)) {
7814 DEL_LLIST_ELEMENT(element, l);
7815+#if HARDENING_PATCH_LL_PROTECT
7816+ element->canary = 0;
7817+#endif
7818 }
7819 element = next;
7820 }
7821@@ -185,7 +276,13 @@
7822 {
7823 zend_llist_element *element;
7824
7825+#if HARDENING_PATCH_LL_PROTECT
7826+ CHECK_LIST_CANARY(l)
7827+#endif
7828 for (element=l->head; element; element=element->next) {
7829+#if HARDENING_PATCH_LL_PROTECT
7830+ CHECK_LISTELEMENT_CANARY(element, l)
7831+#endif
7832 func(element->data TSRMLS_CC);
7833 }
7834 }
7835@@ -197,6 +294,9 @@
7836 zend_llist_element **elements;
7837 zend_llist_element *element, **ptr;
7838
7839+#if HARDENING_PATCH_LL_PROTECT
7840+ CHECK_LIST_CANARY(l)
7841+#endif
7842 if (l->count <= 0) {
7843 return;
7844 }
7845@@ -206,6 +306,9 @@
7846 ptr = &elements[0];
7847
7848 for (element=l->head; element; element=element->next) {
7849+#if HARDENING_PATCH_LL_PROTECT
7850+ CHECK_LISTELEMENT_CANARY(element, l)
7851+#endif
7852 *ptr++ = element;
7853 }
7854
7855@@ -228,7 +331,13 @@
7856 {
7857 zend_llist_element *element;
7858
7859+#if HARDENING_PATCH_LL_PROTECT
7860+ CHECK_LIST_CANARY(l)
7861+#endif
7862 for (element=l->head; element; element=element->next) {
7863+#if HARDENING_PATCH_LL_PROTECT
7864+ CHECK_LISTELEMENT_CANARY(element, l)
7865+#endif
7866 func(element->data, arg TSRMLS_CC);
7867 }
7868 }
7869@@ -239,8 +348,14 @@
7870 zend_llist_element *element;
7871 va_list args;
7872
7873+#if HARDENING_PATCH_LL_PROTECT
7874+ CHECK_LIST_CANARY(l)
7875+#endif
7876 va_start(args, num_args);
7877 for (element=l->head; element; element=element->next) {
7878+#if HARDENING_PATCH_LL_PROTECT
7879+ CHECK_LISTELEMENT_CANARY(element, l)
7880+#endif
7881 func(element->data, num_args, args TSRMLS_CC);
7882 }
7883 va_end(args);
7884@@ -249,6 +364,10 @@
7885
7886 ZEND_API int zend_llist_count(zend_llist *l)
7887 {
7888+#if HARDENING_PATCH_LL_PROTECT
7889+ TSRMLS_FETCH();
7890+ CHECK_LIST_CANARY(l)
7891+#endif
7892 return l->count;
7893 }
7894
7895@@ -256,8 +375,15 @@
7896 {
7897 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7898
7899+#if HARDENING_PATCH_LL_PROTECT
7900+ TSRMLS_FETCH();
7901+ CHECK_LIST_CANARY(l)
7902+#endif
7903 *current = l->head;
7904 if (*current) {
7905+#if HARDENING_PATCH_LL_PROTECT
7906+ CHECK_LISTELEMENT_CANARY(*current, l)
7907+#endif
7908 return (*current)->data;
7909 } else {
7910 return NULL;
7911@@ -269,8 +395,15 @@
7912 {
7913 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7914
7915+#if HARDENING_PATCH_LL_PROTECT
7916+ TSRMLS_FETCH();
7917+ CHECK_LIST_CANARY(l)
7918+#endif
7919 *current = l->tail;
7920 if (*current) {
7921+#if HARDENING_PATCH_LL_PROTECT
7922+ CHECK_LISTELEMENT_CANARY(*current, l)
7923+#endif
7924 return (*current)->data;
7925 } else {
7926 return NULL;
7927@@ -282,9 +415,19 @@
7928 {
7929 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7930
7931+#if HARDENING_PATCH_LL_PROTECT
7932+ TSRMLS_FETCH();
7933+ CHECK_LIST_CANARY(l)
7934+#endif
7935 if (*current) {
7936+#if HARDENING_PATCH_LL_PROTECT
7937+ CHECK_LISTELEMENT_CANARY(*current, l)
7938+#endif
7939 *current = (*current)->next;
7940 if (*current) {
7941+#if HARDENING_PATCH_LL_PROTECT
7942+ CHECK_LISTELEMENT_CANARY(*current, l)
7943+#endif
7944 return (*current)->data;
7945 }
7946 }
7947@@ -296,9 +439,19 @@
7948 {
7949 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7950
7951+#if HARDENING_PATCH_LL_PROTECT
7952+ TSRMLS_FETCH();
7953+ CHECK_LIST_CANARY(l)
7954+#endif
7955 if (*current) {
7956+#if HARDENING_PATCH_LL_PROTECT
7957+ CHECK_LISTELEMENT_CANARY(*current, l)
7958+#endif
7959 *current = (*current)->prev;
7960 if (*current) {
7961+#if HARDENING_PATCH_LL_PROTECT
7962+ CHECK_LISTELEMENT_CANARY(*current, l)
7963+#endif
7964 return (*current)->data;
7965 }
7966 }
7967diff -Nura php-4.4.2/Zend/zend_llist.h hardening-patch-4.4.2-0.4.8/Zend/zend_llist.h
7968--- php-4.4.2/Zend/zend_llist.h 2006-01-01 14:46:49.000000000 +0100
7969+++ hardening-patch-4.4.2-0.4.8/Zend/zend_llist.h 2006-01-18 12:43:26.951202008 +0100
7970@@ -24,6 +24,9 @@
7971 #include <stdlib.h>
7972
7973 typedef struct _zend_llist_element {
7974+#if HARDENING_PATCH_LL_PROTECT
7975+ unsigned int canary, padding;
7976+#endif
7977 struct _zend_llist_element *next;
7978 struct _zend_llist_element *prev;
7979 char data[1]; /* Needs to always be last in the struct */
7980@@ -36,6 +39,9 @@
7981 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7982
7983 typedef struct _zend_llist {
7984+#if HARDENING_PATCH_LL_PROTECT
7985+ unsigned int canary_h; /* head */
7986+#endif
7987 zend_llist_element *head;
7988 zend_llist_element *tail;
7989 size_t size;
7990@@ -43,6 +49,9 @@
7991 llist_dtor_func_t dtor;
7992 unsigned char persistent;
7993 zend_llist_element *traverse_ptr;
7994+#if HARDENING_PATCH_LL_PROTECT
7995+ unsigned int canary_t; /* tail */
7996+#endif
7997 } zend_llist;
7998
7999 typedef zend_llist_element* zend_llist_position;
8000diff -Nura php-4.4.2/Zend/zend_modules.h hardening-patch-4.4.2-0.4.8/Zend/zend_modules.h
8001--- php-4.4.2/Zend/zend_modules.h 2006-01-01 14:46:49.000000000 +0100
8002+++ hardening-patch-4.4.2-0.4.8/Zend/zend_modules.h 2006-01-18 12:43:26.951202008 +0100
8003@@ -34,6 +34,7 @@
8004 ZEND_API extern unsigned char second_arg_force_ref[];
8005 ZEND_API extern unsigned char third_arg_force_ref[];
8006
8007+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001051112
8008 #define ZEND_MODULE_API_NO 20020429
8009 #ifdef ZTS
8010 #define USING_ZTS 1
8011@@ -41,9 +42,9 @@
8012 #define USING_ZTS 0
8013 #endif
8014
8015-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8016+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
8017
8018-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
8019+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
8020
8021 #define STANDARD_MODULE_PROPERTIES \
8022 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
8023@@ -75,6 +76,7 @@
8024 unsigned char type;
8025 void *handle;
8026 int module_number;
8027+ unsigned int real_zend_api;
8028 };
8029
8030
8031diff -Nura php-4.4.2/Zend/zend_opcode.c hardening-patch-4.4.2-0.4.8/Zend/zend_opcode.c
8032--- php-4.4.2/Zend/zend_opcode.c 2006-01-01 14:46:49.000000000 +0100
8033+++ hardening-patch-4.4.2-0.4.8/Zend/zend_opcode.c 2006-01-18 12:43:26.951202008 +0100
8034@@ -88,6 +88,9 @@
8035 op_array->done_pass_two = 0;
8036
8037 op_array->start_op = NULL;
8038+#if HARDENING_PATCH
8039+ op_array->created_by_eval = 0;
8040+#endif
8041
8042 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
8043 }
8044diff -Nura php-4.4.2/Zend/zend_operators.c hardening-patch-4.4.2-0.4.8/Zend/zend_operators.c
8045--- php-4.4.2/Zend/zend_operators.c 2006-01-01 14:46:49.000000000 +0100
8046+++ hardening-patch-4.4.2-0.4.8/Zend/zend_operators.c 2006-01-18 12:43:26.952201856 +0100
8047@@ -1604,6 +1604,20 @@
8048 return (op->value.lval ? 1 : 0);
8049 }
8050
8051+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
8052+{
8053+ register unsigned char *str = (unsigned char*)source;
8054+ register unsigned char *result = (unsigned char*)dest;
8055+ register unsigned char *end = str + length;
8056+
8057+ while (str < end) {
8058+ *result++ = tolower((int)*str++);
8059+ }
8060+ *result = *end;
8061+
8062+ return dest;
8063+}
8064+
8065 ZEND_API void zend_str_tolower(char *str, unsigned int length)
8066 {
8067 register char *p=str, *end=p+length;
8068diff -Nura php-4.4.2/Zend/zend_operators.h hardening-patch-4.4.2-0.4.8/Zend/zend_operators.h
8069--- php-4.4.2/Zend/zend_operators.h 2006-01-01 14:46:49.000000000 +0100
8070+++ hardening-patch-4.4.2-0.4.8/Zend/zend_operators.h 2006-01-18 12:43:26.953201704 +0100
8071@@ -174,6 +174,14 @@
8072 #endif
8073
8074 ZEND_API void zend_str_tolower(char *str, unsigned int length);
8075+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
8076+
8077+static inline char *
8078+zend_str_tolower_dup(const char *source, unsigned int length)
8079+{
8080+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
8081+}
8082+
8083 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
8084 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
8085 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
diff --git a/0.4.8/hardening-patch-5.1.2-0.4.8.patch b/0.4.8/hardening-patch-5.1.2-0.4.8.patch
new file mode 100644
index 0000000..fab5819
--- /dev/null
+++ b/0.4.8/hardening-patch-5.1.2-0.4.8.patch
@@ -0,0 +1,8108 @@
1diff -Nura php-5.1.2/configure hardening-patch-5.1.2-0.4.8/configure
2--- php-5.1.2/configure 2006-01-11 15:25:39.000000000 +0100
3+++ hardening-patch-5.1.2-0.4.8/configure 2006-01-12 19:58:15.570988520 +0100
4@@ -942,6 +942,16 @@
5 ac_help="$ac_help
6 --with-libdir=NAME Look for libraries in .../NAME rather than .../lib"
7 ac_help="$ac_help
8+ --disable-hardening-patch-mm-protect Disable the Memory Manager protection."
9+ac_help="$ac_help
10+ --disable-hardening-patch-ll-protect Disable the Linked List protection."
11+ac_help="$ac_help
12+ --disable-hardening-patch-inc-protect Disable include/require protection."
13+ac_help="$ac_help
14+ --disable-hardening-patch-fmt-protect Disable format string protection."
15+ac_help="$ac_help
16+ --disable-hardening-patch-hash-protect Disable Zend HashTable DTOR protection."
17+ac_help="$ac_help
18
19 SAPI modules:
20 "
21@@ -1410,6 +1420,8 @@
22 ac_help="$ac_help
23 --enable-wddx Enable WDDX support"
24 ac_help="$ac_help
25+ --disable-varfilter Disable Hardening-Patch's variable filter"
26+ac_help="$ac_help
27 --disable-xml Disable XML support"
28 ac_help="$ac_help
29 --with-libxml-dir=DIR XML: libxml2 install prefix"
30@@ -3618,6 +3630,157 @@
31
32
33
34+# Check whether --enable-hardening-patch-mm-protect or --disable-hardening-patch-mm-protect was given.
35+if test "${enable_hardening_patch_mm_protect+set}" = set; then
36+ enableval="$enable_hardening_patch_mm_protect"
37+
38+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
39+
40+else
41+
42+ DO_HARDENING_PATCH_MM_PROTECT=yes
43+
44+fi
45+
46+
47+# Check whether --enable-hardening-patch-ll-protect or --disable-hardening-patch-ll-protect was given.
48+if test "${enable_hardening_patch_ll_protect+set}" = set; then
49+ enableval="$enable_hardening_patch_ll_protect"
50+
51+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
52+
53+else
54+
55+ DO_HARDENING_PATCH_LL_PROTECT=yes
56+
57+fi
58+
59+
60+# Check whether --enable-hardening-patch-inc-protect or --disable-hardening-patch-inc-protect was given.
61+if test "${enable_hardening_patch_inc_protect+set}" = set; then
62+ enableval="$enable_hardening_patch_inc_protect"
63+
64+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
65+
66+else
67+
68+ DO_HARDENING_PATCH_INC_PROTECT=yes
69+
70+fi
71+
72+
73+# Check whether --enable-hardening-patch-fmt-protect or --disable-hardening-patch-fmt-protect was given.
74+if test "${enable_hardening_patch_fmt_protect+set}" = set; then
75+ enableval="$enable_hardening_patch_fmt_protect"
76+
77+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
78+
79+else
80+
81+ DO_HARDENING_PATCH_FMT_PROTECT=yes
82+
83+fi
84+
85+
86+# Check whether --enable-hardening-patch-hash-protect or --disable-hardening-patch-hash-protect was given.
87+if test "${enable_hardening_patch_hash_protect+set}" = set; then
88+ enableval="$enable_hardening_patch_hash_protect"
89+
90+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
91+
92+else
93+
94+ DO_HARDENING_PATCH_HASH_PROTECT=yes
95+
96+fi
97+
98+
99+echo $ac_n "checking whether to protect the Zend Memory Manager""... $ac_c" 1>&6
100+echo "configure:2725: checking whether to protect the Zend Memory Manager" >&5
101+echo "$ac_t""$DO_HARDENING_PATCH_MM_PROTECT" 1>&6
102+
103+echo $ac_n "checking whether to protect the Zend Linked Lists""... $ac_c" 1>&6
104+echo "configure:2729: checking whether to protect the Zend Linked Lists" >&5
105+echo "$ac_t""$DO_HARDENING_PATCH_LL_PROTECT" 1>&6
106+
107+echo $ac_n "checking whether to protect include/require statements""... $ac_c" 1>&6
108+echo "configure:2733: checking whether to protect include/require statements" >&5
109+echo "$ac_t""$DO_HARDENING_PATCH_INC_PROTECT" 1>&6
110+
111+echo $ac_n "checking whether to protect PHP Format String functions""... $ac_c" 1>&6
112+echo "configure:2737: checking whether to protect PHP Format String functions" >&5
113+echo "$ac_t""$DO_HARDENING_PATCH_FMT_PROTECT" 1>&6
114+
115+echo $ac_n "checking whether to protect the Zend HashTable Destructors""... $ac_c" 1>&6
116+echo "configure:2737: checking whether to protect the Zend HashTable Destructors" >&5
117+echo "$ac_t""$DO_HARDENING_PATCH_HASH_PROTECT" 1>&6
118+
119+
120+cat >> confdefs.h <<\EOF
121+#define HARDENING_PATCH 1
122+EOF
123+
124+
125+
126+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
127+ cat >> confdefs.h <<\EOF
128+#define HARDENING_PATCH_MM_PROTECT 1
129+EOF
130+
131+else
132+ cat >> confdefs.h <<\EOF
133+#define HARDENING_PATCH_MM_PROTECT 0
134+EOF
135+
136+fi
137+
138+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
139+ cat >> confdefs.h <<\EOF
140+#define HARDENING_PATCH_LL_PROTECT 1
141+EOF
142+
143+else
144+ cat >> confdefs.h <<\EOF
145+#define HARDENING_PATCH_LL_PROTECT 0
146+EOF
147+
148+fi
149+
150+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
151+ cat >> confdefs.h <<\EOF
152+#define HARDENING_PATCH_INC_PROTECT 1
153+EOF
154+
155+else
156+ cat >> confdefs.h <<\EOF
157+#define HARDENING_PATCH_INC_PROTECT 0
158+EOF
159+
160+fi
161+
162+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
163+ cat >> confdefs.h <<\EOF
164+#define HARDENING_PATCH_FMT_PROTECT 1
165+EOF
166+
167+else
168+ cat >> confdefs.h <<\EOF
169+#define HARDENING_PATCH_FMT_PROTECT 0
170+EOF
171+
172+fi
173+
174+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
175+ cat >> confdefs.h <<\EOF
176+#define HARDENING_PATCH_HASH_PROTECT 1
177+EOF
178+
179+else
180+ cat >> confdefs.h <<\EOF
181+#define HARDENING_PATCH_HASH_PROTECT 0
182+EOF
183+
184+fi
185
186
187
188@@ -18600,6 +18763,62 @@
189 fi
190
191
192+ echo $ac_n "checking whether realpath is broken""... $ac_c" 1>&6
193+echo "configure:14928: checking whether realpath is broken" >&5
194+if eval "test \"`echo '$''{'ac_cv_broken_realpath'+set}'`\" = set"; then
195+ echo $ac_n "(cached) $ac_c" 1>&6
196+else
197+
198+ if test "$cross_compiling" = yes; then
199+
200+ ac_cv_broken_realpath=no
201+
202+else
203+ cat > conftest.$ac_ext <<EOF
204+#line 14939 "configure"
205+#include "confdefs.h"
206+
207+main() {
208+ char buf[4096+1];
209+ buf[0] = 0;
210+ realpath("/etc/hosts/../passwd", buf);
211+ exit(strcmp(buf, "/etc/passwd")==0);
212+}
213+
214+EOF
215+if { (eval echo configure:14958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
216+then
217+
218+ ac_cv_broken_realpath=no
219+
220+else
221+ echo "configure: failed program was:" >&5
222+ cat conftest.$ac_ext >&5
223+ rm -fr conftest*
224+
225+ ac_cv_broken_realpath=yes
226+
227+fi
228+rm -fr conftest*
229+fi
230+
231+
232+fi
233+
234+echo "$ac_t""$ac_cv_broken_realpath" 1>&6
235+ if test "$ac_cv_broken_realpath" = "yes"; then
236+ cat >> confdefs.h <<\EOF
237+#define PHP_BROKEN_REALPATH 1
238+EOF
239+
240+ else
241+ cat >> confdefs.h <<\EOF
242+#define PHP_BROKEN_REALPATH 0
243+EOF
244+
245+ fi
246+
247+
248 echo $ac_n "checking for declared timezone""... $ac_c" 1>&6
249 echo "configure:18605: checking for declared timezone" >&5
250 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
251@@ -89833,7 +90052,7 @@
252 if test "$ac_cv_crypt_blowfish" = "yes"; then
253 ac_result=1
254 else
255- ac_result=0
256+ ac_result=1
257 fi
258 cat >> confdefs.h <<EOF
259 #define PHP_BLOWFISH_CRYPT $ac_result
260@@ -92433,7 +92652,7 @@
261 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
262 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
263 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
264- filters.c proc_open.c streamsfuncs.c http.c; do
265+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
266
267 IFS=.
268 set $ac_src
269@@ -92492,7 +92711,7 @@
270 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
271 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
272 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
273- filters.c proc_open.c streamsfuncs.c http.c; do
274+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
275
276 IFS=.
277 set $ac_src
278@@ -92622,7 +92841,7 @@
279 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
280 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
281 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
282- filters.c proc_open.c streamsfuncs.c http.c; do
283+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
284
285 IFS=.
286 set $ac_src
287@@ -92677,7 +92896,7 @@
288 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
289 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
290 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
291- filters.c proc_open.c streamsfuncs.c http.c; do
292+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
293
294 IFS=.
295 set $ac_src
296@@ -96512,6 +96731,265 @@
297 fi
298
299
300+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
301+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
302+# Check whether --enable-varfilter or --disable-varfilter was given.
303+if test "${enable_varfilter+set}" = set; then
304+ enableval="$enable_varfilter"
305+ PHP_VARFILTER=$enableval
306+else
307+
308+ PHP_VARFILTER=yes
309+
310+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
311+ PHP_VARFILTER=$PHP_ENABLE_ALL
312+ fi
313+
314+fi
315+
316+
317+
318+ext_output="yes, shared"
319+ext_shared=yes
320+case $PHP_VARFILTER in
321+shared,*)
322+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
323+ ;;
324+shared)
325+ PHP_VARFILTER=yes
326+ ;;
327+no)
328+ ext_output=no
329+ ext_shared=no
330+ ;;
331+*)
332+ ext_output=yes
333+ ext_shared=no
334+ ;;
335+esac
336+
337+
338+
339+echo "$ac_t""$ext_output" 1>&6
340+
341+
342+
343+
344+if test "$PHP_VARFILTER" != "no"; then
345+ cat >> confdefs.h <<\EOF
346+#define HAVE_VARFILTER 1
347+EOF
348+
349+
350+ ext_builddir=ext/varfilter
351+ ext_srcdir=$abs_srcdir/ext/varfilter
352+
353+ ac_extra=
354+
355+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
356+
357+
358+
359+ case ext/varfilter in
360+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
361+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
362+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
363+ esac
364+
365+
366+
367+ b_c_pre=$php_c_pre
368+ b_cxx_pre=$php_cxx_pre
369+ b_c_meta=$php_c_meta
370+ b_cxx_meta=$php_cxx_meta
371+ b_c_post=$php_c_post
372+ b_cxx_post=$php_cxx_post
373+ b_lo=$php_lo
374+
375+
376+ old_IFS=$IFS
377+ for ac_src in varfilter.c; do
378+
379+ IFS=.
380+ set $ac_src
381+ ac_obj=$1
382+ IFS=$old_IFS
383+
384+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
385+
386+ case $ac_src in
387+ *.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" ;;
388+ *.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" ;;
389+ esac
390+
391+ cat >>Makefile.objects<<EOF
392+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
393+ $ac_comp
394+EOF
395+ done
396+
397+
398+ EXT_STATIC="$EXT_STATIC varfilter"
399+ if test "$ext_shared" != "nocli"; then
400+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
401+ fi
402+ else
403+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
404+
405+ case ext/varfilter in
406+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
407+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
408+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
409+ esac
410+
411+
412+
413+ b_c_pre=$shared_c_pre
414+ b_cxx_pre=$shared_cxx_pre
415+ b_c_meta=$shared_c_meta
416+ b_cxx_meta=$shared_cxx_meta
417+ b_c_post=$shared_c_post
418+ b_cxx_post=$shared_cxx_post
419+ b_lo=$shared_lo
420+
421+
422+ old_IFS=$IFS
423+ for ac_src in varfilter.c; do
424+
425+ IFS=.
426+ set $ac_src
427+ ac_obj=$1
428+ IFS=$old_IFS
429+
430+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
431+
432+ case $ac_src in
433+ *.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" ;;
434+ *.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" ;;
435+ esac
436+
437+ cat >>Makefile.objects<<EOF
438+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
439+ $ac_comp
440+EOF
441+ done
442+
443+
444+ install_modules="install-modules"
445+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
446+
447+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
448+
449+ cat >>Makefile.objects<<EOF
450+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
451+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
452+
453+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
454+ \$(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)
455+
456+EOF
457+
458+ cat >> confdefs.h <<EOF
459+#define COMPILE_DL_VARFILTER 1
460+EOF
461+
462+ fi
463+ fi
464+
465+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
466+ if test "$PHP_SAPI" = "cgi"; then
467+
468+
469+ case ext/varfilter in
470+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
471+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
472+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
473+ esac
474+
475+
476+
477+ b_c_pre=$php_c_pre
478+ b_cxx_pre=$php_cxx_pre
479+ b_c_meta=$php_c_meta
480+ b_cxx_meta=$php_cxx_meta
481+ b_c_post=$php_c_post
482+ b_cxx_post=$php_cxx_post
483+ b_lo=$php_lo
484+
485+
486+ old_IFS=$IFS
487+ for ac_src in varfilter.c; do
488+
489+ IFS=.
490+ set $ac_src
491+ ac_obj=$1
492+ IFS=$old_IFS
493+
494+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
495+
496+ case $ac_src in
497+ *.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" ;;
498+ *.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" ;;
499+ esac
500+
501+ cat >>Makefile.objects<<EOF
502+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
503+ $ac_comp
504+EOF
505+ done
506+
507+
508+ EXT_STATIC="$EXT_STATIC varfilter"
509+ else
510+
511+
512+ case ext/varfilter in
513+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
514+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
515+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
516+ esac
517+
518+
519+
520+ b_c_pre=$php_c_pre
521+ b_cxx_pre=$php_cxx_pre
522+ b_c_meta=$php_c_meta
523+ b_cxx_meta=$php_cxx_meta
524+ b_c_post=$php_c_post
525+ b_cxx_post=$php_cxx_post
526+ b_lo=$php_lo
527+
528+
529+ old_IFS=$IFS
530+ for ac_src in varfilter.c; do
531+
532+ IFS=.
533+ set $ac_src
534+ ac_obj=$1
535+ IFS=$old_IFS
536+
537+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
538+
539+ case $ac_src in
540+ *.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" ;;
541+ *.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" ;;
542+ esac
543+
544+ cat >>Makefile.objects<<EOF
545+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
546+ $ac_comp
547+EOF
548+ done
549+
550+
551+ fi
552+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
553+ fi
554+
555+ BUILD_DIR="$BUILD_DIR $ext_builddir"
556+
557+
558+fi
559
560
561 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
562@@ -112764,7 +113242,7 @@
563 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
564 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
565 network.c php_open_temporary_file.c php_logos.c \
566- output.c ; do
567+ output.c hardening_patch.c ; do
568
569 IFS=.
570 set $ac_src
571@@ -113009,7 +113487,7 @@
572 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
573 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
574 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
575- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
576+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
577
578 IFS=.
579 set $ac_src
580diff -Nura php-5.1.2/configure.in hardening-patch-5.1.2-0.4.8/configure.in
581--- php-5.1.2/configure.in 2006-01-11 15:19:13.000000000 +0100
582+++ hardening-patch-5.1.2-0.4.8/configure.in 2006-01-12 19:50:03.164845632 +0100
583@@ -209,7 +209,7 @@
584
585 sinclude(Zend/Zend.m4)
586 sinclude(TSRM/tsrm.m4)
587-
588+sinclude(main/hardening_patch.m4)
589
590 divert(2)
591
592@@ -1274,7 +1274,7 @@
593 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
594 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
595 network.c php_open_temporary_file.c php_logos.c \
596- output.c )
597+ output.c hardening_patch.c )
598
599 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
600 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
601@@ -1301,7 +1301,7 @@
602 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
603 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
604 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
605- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
606+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
607
608 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
609 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
610diff -Nura php-5.1.2/ext/fbsql/php_fbsql.c hardening-patch-5.1.2-0.4.8/ext/fbsql/php_fbsql.c
611--- php-5.1.2/ext/fbsql/php_fbsql.c 2006-01-01 13:50:06.000000000 +0100
612+++ hardening-patch-5.1.2-0.4.8/ext/fbsql/php_fbsql.c 2006-01-12 19:50:03.166845328 +0100
613@@ -1925,8 +1925,24 @@
614 }
615 else if (fbcmdErrorsFound(md))
616 {
617+#if HARDENING_PATCH
618+ char* query_copy;
619+ int i;
620+#endif
621 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
622 char* emg = fbcemdAllErrorMessages(emd);
623+#if HARDENING_PATCH
624+ query_copy=estrdup(query_copy);
625+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
626+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
627+ efree(query_copy);
628+ if (HG(hphp_sql_bailout_on_error)) {
629+ free(emg);
630+ fbcemdRelease(emd);
631+ result = 0;
632+ zend_bailout();
633+ }
634+#endif
635 if (FB_SQL_G(generateWarnings))
636 {
637 if (emg)
638diff -Nura php-5.1.2/ext/mysql/php_mysql.c hardening-patch-5.1.2-0.4.8/ext/mysql/php_mysql.c
639--- php-5.1.2/ext/mysql/php_mysql.c 2006-01-01 13:50:09.000000000 +0100
640+++ hardening-patch-5.1.2-0.4.8/ext/mysql/php_mysql.c 2006-01-12 19:50:03.168845024 +0100
641@@ -1231,6 +1231,8 @@
642 {
643 php_mysql_conn *mysql;
644 MYSQL_RES *mysql_result;
645+ char *copy_query;
646+ int i;
647
648 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
649
650@@ -1281,6 +1283,13 @@
651 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
652 }
653 }
654+ copy_query = estrdup(Z_STRVAL_PP(query));
655+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
656+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
657+ efree(copy_query);
658+ if (HG(hphp_sql_bailout_on_error)) {
659+ zend_bailout();
660+ }
661 RETURN_FALSE;
662 }
663 #else
664@@ -1291,6 +1300,13 @@
665 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
666 }
667 }
668+ copy_query = estrdup(Z_STRVAL_PP(query));
669+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
670+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
671+ efree(copy_query);
672+ if (HG(hphp_sql_bailout_on_error)) {
673+ zend_bailout();
674+ }
675 RETURN_FALSE;
676 }
677 #endif
678diff -Nura php-5.1.2/ext/mysqli/mysqli_nonapi.c hardening-patch-5.1.2-0.4.8/ext/mysqli/mysqli_nonapi.c
679--- php-5.1.2/ext/mysqli/mysqli_nonapi.c 2006-01-01 13:50:09.000000000 +0100
680+++ hardening-patch-5.1.2-0.4.8/ext/mysqli/mysqli_nonapi.c 2006-01-12 19:50:03.168845024 +0100
681@@ -183,6 +183,17 @@
682 if (mysql_real_query(mysql->mysql, query, query_len)) {
683 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
684 unsigned int s_errno;
685+#if HARDENING_PATCH
686+ char *query_copy = estrdup(query);
687+ int i;
688+
689+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
690+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
691+ efree(query_copy);
692+ if (HG(hphp_sql_bailout_on_error)) {
693+ zend_bailout();
694+ }
695+#endif
696 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
697
698 /* we have to save error information, cause
699@@ -233,6 +244,17 @@
700 MYSQLI_DISABLE_MQ;
701
702 if (mysql_real_query(mysql->mysql, query, query_len)) {
703+#if HARDENING_PATCH
704+ char *query_copy = estrdup(query);
705+ int i;
706+
707+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
708+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
709+ efree(query_copy);
710+ if (HG(hphp_sql_bailout_on_error)) {
711+ zend_bailout();
712+ }
713+#endif
714 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
715 RETURN_FALSE;
716 }
717diff -Nura php-5.1.2/ext/pgsql/pgsql.c hardening-patch-5.1.2-0.4.8/ext/pgsql/pgsql.c
718--- php-5.1.2/ext/pgsql/pgsql.c 2006-01-01 13:50:12.000000000 +0100
719+++ hardening-patch-5.1.2-0.4.8/ext/pgsql/pgsql.c 2006-01-12 19:50:03.171844568 +0100
720@@ -1152,10 +1152,28 @@
721 case PGRES_EMPTY_QUERY:
722 case PGRES_BAD_RESPONSE:
723 case PGRES_NONFATAL_ERROR:
724- case PGRES_FATAL_ERROR:
725- PHP_PQ_ERROR("Query failed: %s", pgsql);
726- PQclear(pgsql_result);
727- RETURN_FALSE;
728+ case PGRES_FATAL_ERROR:
729+ {
730+#if HARDENING_PATCH
731+ int i;
732+ char *query_copy;
733+#endif
734+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
735+ PQclear(pgsql_result);
736+#if HARDENING_PATCH
737+ query_copy = estrdup(Z_STRVAL_PP(query));
738+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
739+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
740+ efree(query_copy);
741+ if (HG(hphp_sql_bailout_on_error)) {
742+ efree(msgbuf);
743+ zend_bailout();
744+ }
745+#endif
746+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
747+ efree(msgbuf);
748+ RETURN_FALSE;
749+ }
750 break;
751 case PGRES_COMMAND_OK: /* successful command that did not return rows */
752 default:
753diff -Nura php-5.1.2/ext/session/mod_files.c hardening-patch-5.1.2-0.4.8/ext/session/mod_files.c
754--- php-5.1.2/ext/session/mod_files.c 2006-01-01 13:50:12.000000000 +0100
755+++ hardening-patch-5.1.2-0.4.8/ext/session/mod_files.c 2006-01-12 19:50:03.172844416 +0100
756@@ -420,6 +420,35 @@
757 return SUCCESS;
758 }
759
760+PS_VALIDATE_SID_FUNC(files)
761+{
762+ char buf[MAXPATHLEN];
763+ int fd;
764+ PS_FILES_DATA;
765+
766+ if (!ps_files_valid_key(key)) {
767+ return FAILURE;
768+ }
769+
770+ if (!PS(use_strict_mode)) {
771+ return SUCCESS;
772+ }
773+
774+ if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
775+ return FAILURE;
776+ }
777+
778+ fd = VCWD_OPEN_MODE(buf, O_RDWR | O_BINARY,
779+ data->filemode);
780+
781+ if (fd != -1) {
782+ close(fd);
783+ return SUCCESS;
784+ }
785+
786+ return FAILURE;
787+}
788+
789 /*
790 * Local variables:
791 * tab-width: 4
792diff -Nura php-5.1.2/ext/session/mod_mm.c hardening-patch-5.1.2-0.4.8/ext/session/mod_mm.c
793--- php-5.1.2/ext/session/mod_mm.c 2006-01-01 13:50:12.000000000 +0100
794+++ hardening-patch-5.1.2-0.4.8/ext/session/mod_mm.c 2006-01-12 19:50:03.172844416 +0100
795@@ -425,6 +425,42 @@
796 return SUCCESS;
797 }
798
799+PS_VALIDATE_SID_FUNC(mm)
800+{
801+ PS_MM_DATA;
802+ ps_sd *sd;
803+ const char *p;
804+ char c;
805+ int ret = SUCCESS;
806+
807+ for (p = key; (c = *p); p++) {
808+ /* valid characters are a..z,A..Z,0..9 */
809+ if (!((c >= 'a' && c <= 'z')
810+ || (c >= 'A' && c <= 'Z')
811+ || (c >= '0' && c <= '9')
812+ || c == ','
813+ || c == '-')) {
814+ return FAILURE;
815+ }
816+ }
817+
818+ if (!PS(use_strict_mode)) {
819+ return SUCCESS;
820+ }
821+
822+ mm_lock(data->mm, MM_LOCK_RD);
823+
824+ sd = ps_sd_lookup(data, key, 0);
825+ if (sd) {
826+ mm_unlock(data->mm);
827+ return SUCCESS;
828+ }
829+
830+ mm_unlock(data->mm);
831+
832+ return FAILURE;
833+}
834+
835 #endif
836
837 /*
838diff -Nura php-5.1.2/ext/session/mod_user.c hardening-patch-5.1.2-0.4.8/ext/session/mod_user.c
839--- php-5.1.2/ext/session/mod_user.c 2006-01-01 13:50:12.000000000 +0100
840+++ hardening-patch-5.1.2-0.4.8/ext/session/mod_user.c 2006-01-12 19:50:03.173844264 +0100
841@@ -23,7 +23,7 @@
842 #include "mod_user.h"
843
844 ps_module ps_mod_user = {
845- PS_MOD(user)
846+ PS_MOD_SID(user)
847 };
848
849 #define SESS_ZVAL_LONG(val, a) \
850@@ -174,6 +174,83 @@
851 FINISH;
852 }
853
854+PS_CREATE_SID_FUNC(user)
855+{
856+ int i;
857+ char *val = NULL;
858+ zval *retval;
859+ ps_user *mdata = PS_GET_MOD_DATA();
860+
861+ if (!mdata)
862+ return estrndup("", 0);
863+
864+ if (PSF(create) == NULL || ZVAL_IS_NULL(PSF(create))) {
865+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
866+ }
867+ retval = ps_call_handler(PSF(create), 0, NULL TSRMLS_CC);
868+
869+ if (retval) {
870+ if (Z_TYPE_P(retval) == IS_STRING) {
871+ val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
872+ } else {
873+ val = estrndup("", 0);
874+ }
875+ zval_ptr_dtor(&retval);
876+ } else {
877+ val = estrndup("", 0);
878+ }
879+
880+ return val;
881+}
882+
883+static int ps_user_valid_key(const char *key TSRMLS_DC)
884+{
885+ size_t len;
886+ const char *p;
887+ char c;
888+ int ret = SUCCESS;
889+
890+ for (p = key; (c = *p); p++) {
891+ /* valid characters are a..z,A..Z,0..9 */
892+ if (!((c >= 'a' && c <= 'z')
893+ || (c >= 'A' && c <= 'Z')
894+ || (c >= '0' && c <= '9')
895+ || c == ','
896+ || c == '-')) {
897+ ret = FAILURE;
898+ break;
899+ }
900+ }
901+
902+ len = p - key;
903+
904+ if (len == 0)
905+ ret = FAILURE;
906+
907+ return ret;
908+}
909+
910+PS_VALIDATE_SID_FUNC(user)
911+{
912+ zval *args[1];
913+ STDVARS;
914+
915+ if (PSF(validate) == NULL || ZVAL_IS_NULL(PSF(validate))) {
916+ return ps_user_valid_key(key TSRMLS_CC);
917+ }
918+ SESS_ZVAL_STRING(key, args[0]);
919+
920+ retval = ps_call_handler(PSF(validate), 1, args TSRMLS_CC);
921+
922+ if (retval) {
923+ convert_to_long(retval);
924+ ret = Z_LVAL_P(retval) ? SUCCESS : FAILURE;
925+ zval_ptr_dtor(&retval);
926+ }
927+
928+ return ret;
929+}
930+
931 /*
932 * Local variables:
933 * tab-width: 4
934diff -Nura php-5.1.2/ext/session/mod_user.h hardening-patch-5.1.2-0.4.8/ext/session/mod_user.h
935--- php-5.1.2/ext/session/mod_user.h 2006-01-01 13:50:12.000000000 +0100
936+++ hardening-patch-5.1.2-0.4.8/ext/session/mod_user.h 2006-01-12 19:50:03.173844264 +0100
937@@ -22,7 +22,7 @@
938 #define MOD_USER_H
939
940 typedef union {
941- zval *names[6];
942+ zval *names[8];
943 struct {
944 zval *ps_open;
945 zval *ps_close;
946@@ -30,6 +30,8 @@
947 zval *ps_write;
948 zval *ps_destroy;
949 zval *ps_gc;
950+ zval *ps_create;
951+ zval *ps_validate;
952 } name;
953 } ps_user;
954
955diff -Nura php-5.1.2/ext/session/php_session.h hardening-patch-5.1.2-0.4.8/ext/session/php_session.h
956--- php-5.1.2/ext/session/php_session.h 2006-01-01 13:50:12.000000000 +0100
957+++ hardening-patch-5.1.2-0.4.8/ext/session/php_session.h 2006-01-12 19:50:03.173844264 +0100
958@@ -23,7 +23,7 @@
959
960 #include "ext/standard/php_var.h"
961
962-#define PHP_SESSION_API 20020330
963+#define PHP_SESSION_API 20051121
964
965 #define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
966 #define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
967@@ -32,6 +32,7 @@
968 #define PS_DESTROY_ARGS void **mod_data, const char *key TSRMLS_DC
969 #define PS_GC_ARGS void **mod_data, int maxlifetime, int *nrdels TSRMLS_DC
970 #define PS_CREATE_SID_ARGS void **mod_data, int *newlen TSRMLS_DC
971+#define PS_VALIDATE_SID_ARGS void **mod_data, const char *key TSRMLS_DC
972
973 /* default create id function */
974 PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS);
975@@ -45,6 +46,7 @@
976 int (*s_destroy)(PS_DESTROY_ARGS);
977 int (*s_gc)(PS_GC_ARGS);
978 char *(*s_create_sid)(PS_CREATE_SID_ARGS);
979+ int (*s_validate_sid)(PS_VALIDATE_SID_ARGS);
980 } ps_module;
981
982 #define PS_GET_MOD_DATA() *mod_data
983@@ -57,6 +59,7 @@
984 #define PS_DESTROY_FUNC(x) int ps_delete_##x(PS_DESTROY_ARGS)
985 #define PS_GC_FUNC(x) int ps_gc_##x(PS_GC_ARGS)
986 #define PS_CREATE_SID_FUNC(x) char *ps_create_sid_##x(PS_CREATE_SID_ARGS)
987+#define PS_VALIDATE_SID_FUNC(x) int ps_validate_sid_##x(PS_VALIDATE_SID_ARGS)
988
989 #define PS_FUNCS(x) \
990 PS_OPEN_FUNC(x); \
991@@ -65,11 +68,12 @@
992 PS_WRITE_FUNC(x); \
993 PS_DESTROY_FUNC(x); \
994 PS_GC_FUNC(x); \
995- PS_CREATE_SID_FUNC(x)
996+ PS_CREATE_SID_FUNC(x); \
997+ PS_VALIDATE_SID_FUNC(x)
998
999 #define PS_MOD(x) \
1000 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1001- ps_delete_##x, ps_gc_##x, php_session_create_id
1002+ ps_delete_##x, ps_gc_##x, php_session_create_id, ps_validate_sid_##x
1003
1004 /* SID enabled module handler definitions */
1005 #define PS_FUNCS_SID(x) \
1006@@ -79,11 +83,12 @@
1007 PS_WRITE_FUNC(x); \
1008 PS_DESTROY_FUNC(x); \
1009 PS_GC_FUNC(x); \
1010- PS_CREATE_SID_FUNC(x)
1011+ PS_CREATE_SID_FUNC(x); \
1012+ PS_VALIDATE_SID(x)
1013
1014 #define PS_MOD_SID(x) \
1015 #x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
1016- ps_delete_##x, ps_gc_##x, ps_create_sid_##x
1017+ ps_delete_##x, ps_gc_##x, ps_create_sid_##x, ps_validate_sid_##x
1018
1019 typedef enum {
1020 php_session_disabled,
1021@@ -120,6 +125,7 @@
1022 zend_bool use_only_cookies;
1023 zend_bool use_trans_sid; /* contains the INI value of whether to use trans-sid */
1024 zend_bool apply_trans_sid; /* whether or not to enable trans-sid for the current request */
1025+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
1026
1027 long hash_func;
1028 long hash_bits_per_character;
1029diff -Nura php-5.1.2/ext/session/session.c hardening-patch-5.1.2-0.4.8/ext/session/session.c
1030--- php-5.1.2/ext/session/session.c 2006-01-01 13:50:12.000000000 +0100
1031+++ hardening-patch-5.1.2-0.4.8/ext/session/session.c 2006-01-12 19:50:03.175843960 +0100
1032@@ -166,6 +166,7 @@
1033 STD_PHP_INI_BOOLEAN("session.cookie_secure", "", PHP_INI_ALL, OnUpdateBool, cookie_secure, php_ps_globals, ps_globals)
1034 STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
1035 STD_PHP_INI_BOOLEAN("session.use_only_cookies", "0", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
1036+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "1", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
1037 STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
1038 STD_PHP_INI_ENTRY("session.entropy_file", "", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
1039 STD_PHP_INI_ENTRY("session.entropy_length", "0", PHP_INI_ALL, OnUpdateLong, entropy_length, php_ps_globals, ps_globals)
1040@@ -752,6 +753,15 @@
1041 return;
1042 }
1043
1044+ /* If there is an ID, use session module to verify it */
1045+ if (PS(id)) {
1046+ if (PS(mod)->s_validate_sid(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
1047+ efree(PS(id));
1048+ PS(id) = NULL;
1049+ PS(send_cookie) = 1;
1050+ }
1051+ }
1052+
1053 /* If there is no ID, use session module to create one */
1054 if (!PS(id))
1055 PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
1056@@ -1370,22 +1380,29 @@
1057 }
1058 /* }}} */
1059
1060-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
1061+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc[, string create, string validate])
1062 Sets user-level functions */
1063 PHP_FUNCTION(session_set_save_handler)
1064 {
1065- zval **args[6];
1066- int i;
1067+ zval **args[8];
1068+ int i, numargs;
1069 ps_user *mdata;
1070 char *name;
1071
1072- if (ZEND_NUM_ARGS() != 6 || zend_get_parameters_array_ex(6, args) == FAILURE)
1073+ numargs = ZEND_NUM_ARGS();
1074+ args[6] = NULL;
1075+ args[7] = NULL;
1076+
1077+ if (numargs < 6 || numargs > 8 || zend_get_parameters_array_ex(numargs, args) == FAILURE)
1078 WRONG_PARAM_COUNT;
1079
1080 if (PS(session_status) != php_session_none)
1081 RETURN_FALSE;
1082
1083- for (i = 0; i < 6; i++) {
1084+ for (i = 0; i < 8; i++) {
1085+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1086+ continue;
1087+ }
1088 if (!zend_is_callable(*args[i], 0, &name)) {
1089 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
1090 efree(name);
1091@@ -1398,7 +1415,11 @@
1092
1093 mdata = emalloc(sizeof(*mdata));
1094
1095- for (i = 0; i < 6; i++) {
1096+ for (i = 0; i < 8; i++) {
1097+ if (i >= 6 && (args[i] == NULL || ZVAL_IS_NULL(*args[i]))) {
1098+ mdata->names[i] = NULL;
1099+ continue;
1100+ }
1101 ZVAL_ADDREF(*args[i]);
1102 mdata->names[i] = *args[i];
1103 }
1104diff -Nura php-5.1.2/ext/session/tests/014.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/014.phpt
1105--- php-5.1.2/ext/session/tests/014.phpt 2005-07-04 15:09:14.000000000 +0200
1106+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/014.phpt 2006-01-12 19:50:03.175843960 +0100
1107@@ -5,6 +5,7 @@
1108 --INI--
1109 session.use_trans_sid=1
1110 session.use_cookies=0
1111+session.use_strict_mode=0
1112 session.cache_limiter=
1113 register_globals=1
1114 session.bug_compat_42=1
1115diff -Nura php-5.1.2/ext/session/tests/015.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/015.phpt
1116--- php-5.1.2/ext/session/tests/015.phpt 2005-07-04 15:09:14.000000000 +0200
1117+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/015.phpt 2006-01-12 19:50:03.175843960 +0100
1118@@ -5,6 +5,7 @@
1119 --INI--
1120 session.use_trans_sid=1
1121 session.use_cookies=0
1122+session.use_strict_mode=0
1123 session.cache_limiter=
1124 arg_separator.output=&
1125 session.name=PHPSESSID
1126diff -Nura php-5.1.2/ext/session/tests/018.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/018.phpt
1127--- php-5.1.2/ext/session/tests/018.phpt 2005-07-04 15:09:14.000000000 +0200
1128+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/018.phpt 2006-01-12 19:50:03.176843808 +0100
1129@@ -4,6 +4,7 @@
1130 <?php include('skipif.inc'); ?>
1131 --INI--
1132 session.use_cookies=0
1133+session.use_strict_mode=0
1134 session.cache_limiter=
1135 session.use_trans_sid=1
1136 session.name=PHPSESSID
1137diff -Nura php-5.1.2/ext/session/tests/019.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/019.phpt
1138--- php-5.1.2/ext/session/tests/019.phpt 2005-07-04 15:09:14.000000000 +0200
1139+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/019.phpt 2006-01-12 19:50:03.176843808 +0100
1140@@ -4,6 +4,7 @@
1141 <?php include('skipif.inc'); ?>
1142 --INI--
1143 session.use_cookies=0
1144+session.use_strict_mode=0
1145 session.cache_limiter=
1146 register_globals=1
1147 session.serialize_handler=php
1148diff -Nura php-5.1.2/ext/session/tests/020.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/020.phpt
1149--- php-5.1.2/ext/session/tests/020.phpt 2005-07-04 15:09:14.000000000 +0200
1150+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/020.phpt 2006-01-12 19:50:03.176843808 +0100
1151@@ -4,6 +4,7 @@
1152 <?php include('skipif.inc'); ?>
1153 --INI--
1154 session.use_cookies=0
1155+session.use_strict_mode=0
1156 session.cache_limiter=
1157 session.use_trans_sid=1
1158 arg_separator.output=&amp;
1159diff -Nura php-5.1.2/ext/session/tests/021.phpt hardening-patch-5.1.2-0.4.8/ext/session/tests/021.phpt
1160--- php-5.1.2/ext/session/tests/021.phpt 2005-07-04 15:09:14.000000000 +0200
1161+++ hardening-patch-5.1.2-0.4.8/ext/session/tests/021.phpt 2006-01-12 19:50:03.176843808 +0100
1162@@ -4,6 +4,7 @@
1163 <?php include('skipif.inc'); ?>
1164 --INI--
1165 session.use_cookies=0
1166+session.use_strict_mode=0
1167 session.cache_limiter=
1168 session.use_trans_sid=1
1169 url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
1170diff -Nura php-5.1.2/ext/sqlite/sess_sqlite.c hardening-patch-5.1.2-0.4.8/ext/sqlite/sess_sqlite.c
1171--- php-5.1.2/ext/sqlite/sess_sqlite.c 2006-01-01 13:50:14.000000000 +0100
1172+++ hardening-patch-5.1.2-0.4.8/ext/sqlite/sess_sqlite.c 2006-01-12 19:50:03.177843656 +0100
1173@@ -185,6 +185,76 @@
1174 return SQLITE_RETVAL(rv);
1175 }
1176
1177+PS_VALIDATE_SID_FUNC(sqlite)
1178+{
1179+ PS_SQLITE_DATA;
1180+ char *query;
1181+ const char *tail;
1182+ sqlite_vm *vm;
1183+ int colcount, result;
1184+ const char **rowdata, **colnames;
1185+ char *error;
1186+ size_t len;
1187+ const char *p;
1188+ char c;
1189+ int ret = FAILURE;
1190+
1191+ for (p = key; (c = *p); p++) {
1192+ /* valid characters are a..z,A..Z,0..9 */
1193+ if (!((c >= 'a' && c <= 'z')
1194+ || (c >= 'A' && c <= 'Z')
1195+ || (c >= '0' && c <= '9')
1196+ || c == ','
1197+ || c == '-')) {
1198+ return FAILURE;
1199+ break;
1200+ }
1201+ }
1202+
1203+ len = p - key;
1204+
1205+ if (len == 0)
1206+ return FAILURE;
1207+
1208+ if (!PS(use_strict_mode)) {
1209+ return SUCCESS;
1210+ }
1211+
1212+ query = sqlite_mprintf("SELECT value FROM session_data WHERE sess_id='%q' LIMIT 1", key);
1213+ if (query == NULL) {
1214+ /* no memory */
1215+ return FAILURE;
1216+ }
1217+
1218+ if (sqlite_compile(db, query, &tail, &vm, &error) != SQLITE_OK) {
1219+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: Could not compile session validate sid query: %s", error);
1220+ sqlite_freemem(error);
1221+ sqlite_freemem(query);
1222+ return FAILURE;
1223+ }
1224+
1225+ switch ((result = sqlite_step(vm, &colcount, &rowdata, &colnames))) {
1226+ case SQLITE_ROW:
1227+ if (rowdata[0] != NULL) {
1228+ ret = SUCCESS;
1229+ }
1230+ break;
1231+ default:
1232+ sqlite_freemem(error);
1233+ error = NULL;
1234+ }
1235+
1236+ if (SQLITE_OK != sqlite_finalize(vm, &error)) {
1237+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SQLite: session validate sid: error %s", error);
1238+ sqlite_freemem(error);
1239+ error = NULL;
1240+ }
1241+
1242+ sqlite_freemem(query);
1243+
1244+ return ret;
1245+}
1246+
1247 #endif /* HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) */
1248
1249 /*
1250diff -Nura php-5.1.2/ext/sqlite/sqlite.c hardening-patch-5.1.2-0.4.8/ext/sqlite/sqlite.c
1251--- php-5.1.2/ext/sqlite/sqlite.c 2006-01-01 13:50:14.000000000 +0100
1252+++ hardening-patch-5.1.2-0.4.8/ext/sqlite/sqlite.c 2006-01-12 19:50:03.179843352 +0100
1253@@ -1533,6 +1533,19 @@
1254 db->last_err_code = ret;
1255
1256 if (ret != SQLITE_OK) {
1257+#if HARDENING_PATCH
1258+ char *query_copy;
1259+ int i;
1260+
1261+ query_copy = estrdup(sql);
1262+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
1263+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
1264+ efree(query_copy);
1265+ if (HG(hphp_sql_bailout_on_error)) {
1266+ sqlite_freemem(errtext);
1267+ zend_bailout();
1268+ }
1269+#endif
1270 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
1271 if (errmsg) {
1272 ZVAL_STRING(errmsg, errtext, 1);
1273diff -Nura php-5.1.2/ext/standard/array.c hardening-patch-5.1.2-0.4.8/ext/standard/array.c
1274--- php-5.1.2/ext/standard/array.c 2006-01-01 13:50:14.000000000 +0100
1275+++ hardening-patch-5.1.2-0.4.8/ext/standard/array.c 2006-01-12 19:50:03.181843048 +0100
1276@@ -1305,6 +1305,32 @@
1277 }
1278 }
1279 }
1280+
1281+ if (var_name[0] == 'H') {
1282+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
1283+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
1284+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
1285+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
1286+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
1287+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
1288+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
1289+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
1290+ return 0;
1291+ }
1292+ } else if (var_name[0] == '_') {
1293+ if ((strcmp(var_name, "_COOKIE")==0)||
1294+ (strcmp(var_name, "_ENV")==0)||
1295+ (strcmp(var_name, "_FILES")==0)||
1296+ (strcmp(var_name, "_GET")==0)||
1297+ (strcmp(var_name, "_POST")==0)||
1298+ (strcmp(var_name, "_REQUEST")==0)||
1299+ (strcmp(var_name, "_SESSION")==0)||
1300+ (strcmp(var_name, "_SERVER")==0)) {
1301+ return 0;
1302+ }
1303+ } else if (strcmp(var_name, "GLOBALS")==0) {
1304+ return 0;
1305+ }
1306
1307 return 1;
1308 }
1309diff -Nura php-5.1.2/ext/standard/basic_functions.c hardening-patch-5.1.2-0.4.8/ext/standard/basic_functions.c
1310--- php-5.1.2/ext/standard/basic_functions.c 2006-01-04 22:31:29.000000000 +0100
1311+++ hardening-patch-5.1.2-0.4.8/ext/standard/basic_functions.c 2006-01-12 19:50:03.184842592 +0100
1312@@ -151,12 +151,14 @@
1313 typedef struct _php_shutdown_function_entry {
1314 zval **arguments;
1315 int arg_count;
1316+ zend_bool created_by_eval;
1317 } php_shutdown_function_entry;
1318
1319 typedef struct _user_tick_function_entry {
1320 zval **arguments;
1321 int arg_count;
1322 int calling;
1323+ zend_bool created_by_eval;
1324 } user_tick_function_entry;
1325
1326 /* some prototypes for local functions */
1327@@ -188,6 +190,8 @@
1328 PHP_FE(get_html_translation_table, NULL)
1329 PHP_FE(sha1, NULL)
1330 PHP_FE(sha1_file, NULL)
1331+ PHP_FE(sha256, NULL)
1332+ PHP_FE(sha256_file, NULL)
1333 PHP_NAMED_FE(md5,php_if_md5, NULL)
1334 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
1335 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
1336@@ -628,7 +632,7 @@
1337 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
1338
1339 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1340- PHP_FE(realpath, NULL)
1341+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
1342 #endif
1343
1344 #ifdef HAVE_FNMATCH
1345@@ -2269,6 +2273,13 @@
1346 {
1347 zval retval;
1348 char *function_name = NULL;
1349+#if HARDENING_PATCH
1350+ zend_uint orig_code_type = EG(in_code_type);
1351+
1352+ if (shutdown_function_entry->created_by_eval) {
1353+ EG(in_code_type) = ZEND_EVAL_CODE;
1354+ }
1355+#endif
1356
1357 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
1358 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
1359@@ -2284,6 +2295,9 @@
1360 if (function_name) {
1361 efree(function_name);
1362 }
1363+#if HARDENING_PATCH
1364+ EG(in_code_type) = orig_code_type;
1365+#endif
1366 return 0;
1367 }
1368
1369@@ -2291,6 +2305,13 @@
1370 {
1371 zval retval;
1372 zval *function = tick_fe->arguments[0];
1373+#if HARDENING_PATCH
1374+ zend_uint orig_code_type = EG(in_code_type);
1375+
1376+ if (tick_fe->created_by_eval) {
1377+ EG(in_code_type) = ZEND_EVAL_CODE;
1378+ }
1379+#endif
1380
1381 /* Prevent reentrant calls to the same user ticks function */
1382 if (! tick_fe->calling) {
1383@@ -2322,6 +2343,9 @@
1384
1385 tick_fe->calling = 0;
1386 }
1387+#if HARDENING_PATCH
1388+ EG(in_code_type) = orig_code_type;
1389+#endif
1390 }
1391
1392 static void run_user_tick_functions(int tick_count)
1393@@ -2385,6 +2409,13 @@
1394 }
1395
1396 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
1397+#if HARDENING_PATCH
1398+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1399+ shutdown_function_entry.created_by_eval = 1;
1400+ } else {
1401+ shutdown_function_entry.created_by_eval = 0;
1402+ }
1403+#endif
1404
1405 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1406 RETURN_FALSE;
1407@@ -2968,6 +2999,13 @@
1408 }
1409
1410 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1411+#if HARDENING_PATCH
1412+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1413+ tick_fe.created_by_eval = 1;
1414+ } else {
1415+ tick_fe.created_by_eval = 0;
1416+ }
1417+#endif
1418
1419 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1420 RETURN_FALSE;
1421@@ -3270,6 +3308,35 @@
1422 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
1423 }
1424
1425+ if (new_key[0] == 'H') {
1426+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1427+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1428+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1429+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1430+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1431+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1432+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1433+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1434+ efree(new_key);
1435+ return 0;
1436+ }
1437+ } else if (new_key[0] == '_') {
1438+ if ((strcmp(new_key, "_COOKIE")==0)||
1439+ (strcmp(new_key, "_ENV")==0)||
1440+ (strcmp(new_key, "_FILES")==0)||
1441+ (strcmp(new_key, "_GET")==0)||
1442+ (strcmp(new_key, "_POST")==0)||
1443+ (strcmp(new_key, "_REQUEST")==0)||
1444+ (strcmp(new_key, "_SESSION")==0)||
1445+ (strcmp(new_key, "_SERVER")==0)) {
1446+ efree(new_key);
1447+ return 0;
1448+ }
1449+ } else if (strcmp(new_key, "GLOBALS")==0) {
1450+ efree(new_key);
1451+ return 0;
1452+ }
1453+
1454 zend_delete_global_variable(new_key, new_key_len-1 TSRMLS_CC);
1455 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1456
1457diff -Nura php-5.1.2/ext/standard/config.m4 hardening-patch-5.1.2-0.4.8/ext/standard/config.m4
1458--- php-5.1.2/ext/standard/config.m4 2006-01-04 22:31:29.000000000 +0100
1459+++ hardening-patch-5.1.2-0.4.8/ext/standard/config.m4 2006-01-12 19:56:13.030617488 +0100
1460@@ -203,7 +203,7 @@
1461 if test "$ac_cv_crypt_blowfish" = "yes"; then
1462 ac_result=1
1463 else
1464- ac_result=0
1465+ ac_result=1
1466 fi
1467 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1468 ])
1469@@ -489,7 +489,7 @@
1470 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1471 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1472 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
1473- filters.c proc_open.c streamsfuncs.c http.c)
1474+ filters.c proc_open.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
1475
1476 PHP_ADD_MAKEFILE_FRAGMENT
1477
1478diff -Nura php-5.1.2/ext/standard/config.w32 hardening-patch-5.1.2-0.4.8/ext/standard/config.w32
1479--- php-5.1.2/ext/standard/config.w32 2006-01-04 22:31:29.000000000 +0100
1480+++ hardening-patch-5.1.2-0.4.8/ext/standard/config.w32 2006-01-12 19:56:43.252023136 +0100
1481@@ -16,5 +16,5 @@
1482 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
1483 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
1484 user_filters.c uuencode.c filters.c proc_open.c \
1485- streamsfuncs.c http.c", false /* never shared */);
1486+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
1487
1488diff -Nura php-5.1.2/ext/standard/crypt_blowfish.c hardening-patch-5.1.2-0.4.8/ext/standard/crypt_blowfish.c
1489--- php-5.1.2/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1490+++ hardening-patch-5.1.2-0.4.8/ext/standard/crypt_blowfish.c 2006-01-12 19:50:03.187842136 +0100
1491@@ -0,0 +1,748 @@
1492+/*
1493+ * This code comes from John the Ripper password cracker, with reentrant
1494+ * and crypt(3) interfaces added, but optimizations specific to password
1495+ * cracking removed.
1496+ *
1497+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1498+ * placed in the public domain.
1499+ *
1500+ * There's absolutely no warranty.
1501+ *
1502+ * It is my intent that you should be able to use this on your system,
1503+ * as a part of a software package, or anywhere else to improve security,
1504+ * ensure compatibility, or for any other purpose. I would appreciate
1505+ * it if you give credit where it is due and keep your modifications in
1506+ * the public domain as well, but I don't require that in order to let
1507+ * you place this code and any modifications you make under a license
1508+ * of your choice.
1509+ *
1510+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1511+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1512+ * ideas. The password hashing algorithm was designed by David Mazieres
1513+ * <dm at lcs.mit.edu>.
1514+ *
1515+ * There's a paper on the algorithm that explains its design decisions:
1516+ *
1517+ * http://www.usenix.org/events/usenix99/provos.html
1518+ *
1519+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1520+ * Blowfish library (I can't be sure if I would think of something if I
1521+ * hadn't seen his code).
1522+ */
1523+
1524+#include <string.h>
1525+
1526+#include <errno.h>
1527+#ifndef __set_errno
1528+#define __set_errno(val) errno = (val)
1529+#endif
1530+
1531+#undef __CONST
1532+#ifdef __GNUC__
1533+#define __CONST __const
1534+#else
1535+#define __CONST
1536+#endif
1537+
1538+#ifdef __i386__
1539+#define BF_ASM 0
1540+#define BF_SCALE 1
1541+#elif defined(__alpha__) || defined(__hppa__)
1542+#define BF_ASM 0
1543+#define BF_SCALE 1
1544+#else
1545+#define BF_ASM 0
1546+#define BF_SCALE 0
1547+#endif
1548+
1549+typedef unsigned int BF_word;
1550+
1551+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1552+#define BF_N 16
1553+
1554+typedef BF_word BF_key[BF_N + 2];
1555+
1556+typedef struct {
1557+ BF_word S[4][0x100];
1558+ BF_key P;
1559+} BF_ctx;
1560+
1561+/*
1562+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1563+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1564+ */
1565+static BF_word BF_magic_w[6] = {
1566+ 0x4F727068, 0x65616E42, 0x65686F6C,
1567+ 0x64657253, 0x63727944, 0x6F756274
1568+};
1569+
1570+/*
1571+ * P-box and S-box tables initialized with digits of Pi.
1572+ */
1573+static BF_ctx BF_init_state = {
1574+ {
1575+ {
1576+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1577+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1578+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1579+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1580+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1581+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1582+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1583+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1584+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1585+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1586+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1587+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1588+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1589+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1590+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1591+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1592+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1593+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1594+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1595+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1596+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1597+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1598+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1599+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1600+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1601+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1602+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1603+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1604+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1605+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1606+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1607+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1608+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1609+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1610+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1611+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1612+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1613+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1614+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1615+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1616+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1617+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1618+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1619+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1620+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1621+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1622+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1623+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1624+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1625+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1626+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1627+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1628+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1629+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1630+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1631+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1632+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1633+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1634+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1635+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1636+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1637+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1638+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1639+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1640+ }, {
1641+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1642+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1643+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1644+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1645+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1646+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1647+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1648+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1649+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1650+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1651+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1652+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1653+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1654+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1655+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1656+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1657+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1658+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1659+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1660+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1661+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1662+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1663+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1664+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1665+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1666+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1667+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1668+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1669+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1670+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1671+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1672+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1673+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1674+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1675+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1676+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1677+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1678+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1679+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1680+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1681+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1682+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1683+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1684+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1685+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1686+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1687+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1688+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1689+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1690+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1691+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1692+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1693+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1694+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1695+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1696+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1697+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1698+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1699+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1700+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1701+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1702+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1703+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1704+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1705+ }, {
1706+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1707+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1708+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1709+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1710+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1711+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1712+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1713+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1714+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1715+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1716+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1717+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1718+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1719+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1720+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1721+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1722+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1723+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1724+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1725+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1726+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1727+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1728+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1729+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1730+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1731+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1732+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1733+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1734+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1735+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1736+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1737+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1738+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1739+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1740+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1741+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1742+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1743+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1744+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1745+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1746+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1747+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1748+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1749+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1750+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1751+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1752+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1753+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1754+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1755+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1756+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1757+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1758+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1759+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1760+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1761+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1762+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1763+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1764+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1765+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1766+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1767+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1768+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1769+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1770+ }, {
1771+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1772+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1773+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1774+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1775+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1776+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1777+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1778+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1779+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1780+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1781+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1782+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1783+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1784+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1785+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1786+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1787+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1788+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1789+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1790+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1791+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1792+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1793+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1794+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1795+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1796+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1797+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1798+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1799+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1800+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1801+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1802+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1803+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1804+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1805+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1806+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1807+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1808+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1809+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1810+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1811+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1812+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1813+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1814+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1815+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1816+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1817+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1818+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1819+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1820+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1821+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1822+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1823+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1824+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1825+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1826+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1827+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1828+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1829+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1830+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1831+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1832+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1833+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1834+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1835+ }
1836+ }, {
1837+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1838+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1839+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1840+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1841+ 0x9216d5d9, 0x8979fb1b
1842+ }
1843+};
1844+
1845+static unsigned char BF_itoa64[64 + 1] =
1846+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1847+
1848+static unsigned char BF_atoi64[0x60] = {
1849+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1850+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1851+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1852+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1853+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1854+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1855+};
1856+
1857+/*
1858+ * This may be optimized out if built with function inlining and no BF_ASM.
1859+ */
1860+static void clean(void *data, int size)
1861+{
1862+#if BF_ASM
1863+ extern void _BF_clean(void *data);
1864+#endif
1865+ memset(data, 0, size);
1866+#if BF_ASM
1867+ _BF_clean(data);
1868+#endif
1869+}
1870+
1871+#define BF_safe_atoi64(dst, src) \
1872+{ \
1873+ tmp = (unsigned char)(src); \
1874+ if (tmp == '$') break; \
1875+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1876+ tmp = BF_atoi64[tmp]; \
1877+ if (tmp > 63) return -1; \
1878+ (dst) = tmp; \
1879+}
1880+
1881+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1882+{
1883+ unsigned char *dptr = (unsigned char *)dst;
1884+ unsigned char *end = dptr + size;
1885+ unsigned char *sptr = (unsigned char *)src;
1886+ unsigned int tmp, c1, c2, c3, c4;
1887+
1888+ do {
1889+ BF_safe_atoi64(c1, *sptr++);
1890+ BF_safe_atoi64(c2, *sptr++);
1891+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1892+ if (dptr >= end) break;
1893+
1894+ BF_safe_atoi64(c3, *sptr++);
1895+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1896+ if (dptr >= end) break;
1897+
1898+ BF_safe_atoi64(c4, *sptr++);
1899+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1900+ } while (dptr < end);
1901+
1902+ while (dptr < end)
1903+ *dptr++ = 0;
1904+
1905+ return 0;
1906+}
1907+
1908+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1909+{
1910+ unsigned char *sptr = (unsigned char *)src;
1911+ unsigned char *end = sptr + size;
1912+ unsigned char *dptr = (unsigned char *)dst;
1913+ unsigned int c1, c2;
1914+
1915+ do {
1916+ c1 = *sptr++;
1917+ *dptr++ = BF_itoa64[c1 >> 2];
1918+ c1 = (c1 & 0x03) << 4;
1919+ if (sptr >= end) {
1920+ *dptr++ = BF_itoa64[c1];
1921+ break;
1922+ }
1923+
1924+ c2 = *sptr++;
1925+ c1 |= c2 >> 4;
1926+ *dptr++ = BF_itoa64[c1];
1927+ c1 = (c2 & 0x0f) << 2;
1928+ if (sptr >= end) {
1929+ *dptr++ = BF_itoa64[c1];
1930+ break;
1931+ }
1932+
1933+ c2 = *sptr++;
1934+ c1 |= c2 >> 6;
1935+ *dptr++ = BF_itoa64[c1];
1936+ *dptr++ = BF_itoa64[c2 & 0x3f];
1937+ } while (sptr < end);
1938+}
1939+
1940+static void BF_swap(BF_word *x, int count)
1941+{
1942+ static int endianness_check = 1;
1943+ char *is_little_endian = (char *)&endianness_check;
1944+ BF_word tmp;
1945+
1946+ if (*is_little_endian)
1947+ do {
1948+ tmp = *x;
1949+ tmp = (tmp << 16) | (tmp >> 16);
1950+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1951+ } while (--count);
1952+}
1953+
1954+#if BF_SCALE
1955+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1956+#define BF_ROUND(L, R, N) \
1957+ tmp1 = L & 0xFF; \
1958+ tmp2 = L >> 8; \
1959+ tmp2 &= 0xFF; \
1960+ tmp3 = L >> 16; \
1961+ tmp3 &= 0xFF; \
1962+ tmp4 = L >> 24; \
1963+ tmp1 = data.ctx.S[3][tmp1]; \
1964+ tmp2 = data.ctx.S[2][tmp2]; \
1965+ tmp3 = data.ctx.S[1][tmp3]; \
1966+ tmp3 += data.ctx.S[0][tmp4]; \
1967+ tmp3 ^= tmp2; \
1968+ R ^= data.ctx.P[N + 1]; \
1969+ tmp3 += tmp1; \
1970+ R ^= tmp3;
1971+#else
1972+/* Architectures with no complicated addressing modes supported */
1973+#define BF_INDEX(S, i) \
1974+ (*((BF_word *)(((unsigned char *)S) + (i))))
1975+#define BF_ROUND(L, R, N) \
1976+ tmp1 = L & 0xFF; \
1977+ tmp1 <<= 2; \
1978+ tmp2 = L >> 6; \
1979+ tmp2 &= 0x3FC; \
1980+ tmp3 = L >> 14; \
1981+ tmp3 &= 0x3FC; \
1982+ tmp4 = L >> 22; \
1983+ tmp4 &= 0x3FC; \
1984+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1985+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1986+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1987+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1988+ tmp3 ^= tmp2; \
1989+ R ^= data.ctx.P[N + 1]; \
1990+ tmp3 += tmp1; \
1991+ R ^= tmp3;
1992+#endif
1993+
1994+/*
1995+ * Encrypt one block, BF_N is hardcoded here.
1996+ */
1997+#define BF_ENCRYPT \
1998+ L ^= data.ctx.P[0]; \
1999+ BF_ROUND(L, R, 0); \
2000+ BF_ROUND(R, L, 1); \
2001+ BF_ROUND(L, R, 2); \
2002+ BF_ROUND(R, L, 3); \
2003+ BF_ROUND(L, R, 4); \
2004+ BF_ROUND(R, L, 5); \
2005+ BF_ROUND(L, R, 6); \
2006+ BF_ROUND(R, L, 7); \
2007+ BF_ROUND(L, R, 8); \
2008+ BF_ROUND(R, L, 9); \
2009+ BF_ROUND(L, R, 10); \
2010+ BF_ROUND(R, L, 11); \
2011+ BF_ROUND(L, R, 12); \
2012+ BF_ROUND(R, L, 13); \
2013+ BF_ROUND(L, R, 14); \
2014+ BF_ROUND(R, L, 15); \
2015+ tmp4 = R; \
2016+ R = L; \
2017+ L = tmp4 ^ data.ctx.P[BF_N + 1];
2018+
2019+#if BF_ASM
2020+#define BF_body() \
2021+ _BF_body_r(&data.ctx);
2022+#else
2023+#define BF_body() \
2024+ L = R = 0; \
2025+ ptr = data.ctx.P; \
2026+ do { \
2027+ ptr += 2; \
2028+ BF_ENCRYPT; \
2029+ *(ptr - 2) = L; \
2030+ *(ptr - 1) = R; \
2031+ } while (ptr < &data.ctx.P[BF_N + 2]); \
2032+\
2033+ ptr = data.ctx.S[0]; \
2034+ do { \
2035+ ptr += 2; \
2036+ BF_ENCRYPT; \
2037+ *(ptr - 2) = L; \
2038+ *(ptr - 1) = R; \
2039+ } while (ptr < &data.ctx.S[3][0xFF]);
2040+#endif
2041+
2042+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
2043+{
2044+ __CONST char *ptr = key;
2045+ int i, j;
2046+ BF_word tmp;
2047+
2048+ for (i = 0; i < BF_N + 2; i++) {
2049+ tmp = 0;
2050+ for (j = 0; j < 4; j++) {
2051+ tmp <<= 8;
2052+ tmp |= *ptr;
2053+
2054+ if (!*ptr) ptr = key; else ptr++;
2055+ }
2056+
2057+ expanded[i] = tmp;
2058+ initial[i] = BF_init_state.P[i] ^ tmp;
2059+ }
2060+}
2061+
2062+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
2063+ char *output, int size)
2064+{
2065+#if BF_ASM
2066+ extern void _BF_body_r(BF_ctx *ctx);
2067+#endif
2068+ struct {
2069+ BF_ctx ctx;
2070+ BF_key expanded_key;
2071+ union {
2072+ BF_word salt[4];
2073+ BF_word output[6];
2074+ } binary;
2075+ } data;
2076+ BF_word L, R;
2077+ BF_word tmp1, tmp2, tmp3, tmp4;
2078+ BF_word *ptr;
2079+ BF_word count;
2080+ int i;
2081+
2082+ if (size < 7 + 22 + 31 + 1) {
2083+ __set_errno(ERANGE);
2084+ return NULL;
2085+ }
2086+
2087+ if (setting[0] != '$' ||
2088+ setting[1] != '2' ||
2089+ setting[2] != 'a' ||
2090+ setting[3] != '$' ||
2091+ setting[4] < '0' || setting[4] > '3' ||
2092+ setting[5] < '0' || setting[5] > '9' ||
2093+ setting[6] != '$') {
2094+ __set_errno(EINVAL);
2095+ return NULL;
2096+ }
2097+
2098+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
2099+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
2100+ clean(data.binary.salt, sizeof(data.binary.salt));
2101+ __set_errno(EINVAL);
2102+ return NULL;
2103+ }
2104+
2105+ BF_swap(data.binary.salt, 4);
2106+
2107+ BF_set_key(key, data.expanded_key, data.ctx.P);
2108+
2109+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
2110+
2111+ L = R = 0;
2112+ for (i = 0; i < BF_N + 2; i += 2) {
2113+ L ^= data.binary.salt[i & 2];
2114+ R ^= data.binary.salt[(i & 2) + 1];
2115+ BF_ENCRYPT;
2116+ data.ctx.P[i] = L;
2117+ data.ctx.P[i + 1] = R;
2118+ }
2119+
2120+ ptr = data.ctx.S[0];
2121+ do {
2122+ ptr += 4;
2123+ L ^= data.binary.salt[(BF_N + 2) & 3];
2124+ R ^= data.binary.salt[(BF_N + 3) & 3];
2125+ BF_ENCRYPT;
2126+ *(ptr - 4) = L;
2127+ *(ptr - 3) = R;
2128+
2129+ L ^= data.binary.salt[(BF_N + 4) & 3];
2130+ R ^= data.binary.salt[(BF_N + 5) & 3];
2131+ BF_ENCRYPT;
2132+ *(ptr - 2) = L;
2133+ *(ptr - 1) = R;
2134+ } while (ptr < &data.ctx.S[3][0xFF]);
2135+
2136+ do {
2137+ data.ctx.P[0] ^= data.expanded_key[0];
2138+ data.ctx.P[1] ^= data.expanded_key[1];
2139+ data.ctx.P[2] ^= data.expanded_key[2];
2140+ data.ctx.P[3] ^= data.expanded_key[3];
2141+ data.ctx.P[4] ^= data.expanded_key[4];
2142+ data.ctx.P[5] ^= data.expanded_key[5];
2143+ data.ctx.P[6] ^= data.expanded_key[6];
2144+ data.ctx.P[7] ^= data.expanded_key[7];
2145+ data.ctx.P[8] ^= data.expanded_key[8];
2146+ data.ctx.P[9] ^= data.expanded_key[9];
2147+ data.ctx.P[10] ^= data.expanded_key[10];
2148+ data.ctx.P[11] ^= data.expanded_key[11];
2149+ data.ctx.P[12] ^= data.expanded_key[12];
2150+ data.ctx.P[13] ^= data.expanded_key[13];
2151+ data.ctx.P[14] ^= data.expanded_key[14];
2152+ data.ctx.P[15] ^= data.expanded_key[15];
2153+ data.ctx.P[16] ^= data.expanded_key[16];
2154+ data.ctx.P[17] ^= data.expanded_key[17];
2155+
2156+ BF_body();
2157+
2158+ tmp1 = data.binary.salt[0];
2159+ tmp2 = data.binary.salt[1];
2160+ tmp3 = data.binary.salt[2];
2161+ tmp4 = data.binary.salt[3];
2162+ data.ctx.P[0] ^= tmp1;
2163+ data.ctx.P[1] ^= tmp2;
2164+ data.ctx.P[2] ^= tmp3;
2165+ data.ctx.P[3] ^= tmp4;
2166+ data.ctx.P[4] ^= tmp1;
2167+ data.ctx.P[5] ^= tmp2;
2168+ data.ctx.P[6] ^= tmp3;
2169+ data.ctx.P[7] ^= tmp4;
2170+ data.ctx.P[8] ^= tmp1;
2171+ data.ctx.P[9] ^= tmp2;
2172+ data.ctx.P[10] ^= tmp3;
2173+ data.ctx.P[11] ^= tmp4;
2174+ data.ctx.P[12] ^= tmp1;
2175+ data.ctx.P[13] ^= tmp2;
2176+ data.ctx.P[14] ^= tmp3;
2177+ data.ctx.P[15] ^= tmp4;
2178+ data.ctx.P[16] ^= tmp1;
2179+ data.ctx.P[17] ^= tmp2;
2180+
2181+ BF_body();
2182+ } while (--count);
2183+
2184+ for (i = 0; i < 6; i += 2) {
2185+ L = BF_magic_w[i];
2186+ R = BF_magic_w[i + 1];
2187+
2188+ count = 64;
2189+ do {
2190+ BF_ENCRYPT;
2191+ } while (--count);
2192+
2193+ data.binary.output[i] = L;
2194+ data.binary.output[i + 1] = R;
2195+ }
2196+
2197+ memcpy(output, setting, 7 + 22 - 1);
2198+ output[7 + 22 - 1] = BF_itoa64[(int)
2199+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
2200+
2201+/* This has to be bug-compatible with the original implementation, so
2202+ * only encode 23 of the 24 bytes. :-) */
2203+ BF_swap(data.binary.output, 6);
2204+ BF_encode(&output[7 + 22], data.binary.output, 23);
2205+ output[7 + 22 + 31] = '\0';
2206+
2207+/* Overwrite the most obvious sensitive data we have on the stack. Note
2208+ * that this does not guarantee there's no sensitive data left on the
2209+ * stack and/or in registers; I'm not aware of portable code that does. */
2210+ clean(&data, sizeof(data));
2211+
2212+ return output;
2213+}
2214+
2215+char *_crypt_gensalt_blowfish_rn(unsigned long count,
2216+ __CONST char *input, int size, char *output, int output_size)
2217+{
2218+ if (size < 16 || output_size < 7 + 22 + 1 ||
2219+ (count && (count < 4 || count > 31))) {
2220+ if (output_size > 0) output[0] = '\0';
2221+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
2222+ return NULL;
2223+ }
2224+
2225+ if (!count) count = 5;
2226+
2227+ output[0] = '$';
2228+ output[1] = '2';
2229+ output[2] = 'a';
2230+ output[3] = '$';
2231+ output[4] = '0' + count / 10;
2232+ output[5] = '0' + count % 10;
2233+ output[6] = '$';
2234+
2235+ BF_encode(&output[7], (BF_word *)input, 16);
2236+ output[7 + 22] = '\0';
2237+
2238+ return output;
2239+}
2240diff -Nura php-5.1.2/ext/standard/crypt.c hardening-patch-5.1.2-0.4.8/ext/standard/crypt.c
2241--- php-5.1.2/ext/standard/crypt.c 2006-01-01 13:50:14.000000000 +0100
2242+++ hardening-patch-5.1.2-0.4.8/ext/standard/crypt.c 2006-01-12 19:50:03.188841984 +0100
2243@@ -100,6 +100,8 @@
2244 return SUCCESS;
2245 }
2246
2247+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
2248+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
2249
2250 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2251
2252@@ -135,7 +137,14 @@
2253
2254 /* The automatic salt generation only covers standard DES and md5-crypt */
2255 if(!*salt) {
2256-#if PHP_MD5_CRYPT
2257+#if PHP_BLOWFISH_CRYPT
2258+ char randat[16];
2259+ int i;
2260+
2261+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
2262+
2263+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
2264+#elif PHP_MD5_CRYPT
2265 strcpy(salt, "$1$");
2266 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
2267 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
2268@@ -145,8 +154,24 @@
2269 salt[2] = '\0';
2270 #endif
2271 }
2272-
2273- RETVAL_STRING(crypt(str, salt), 1);
2274+
2275+ if (salt[0] == '$' &&
2276+ salt[1] == '2' &&
2277+ salt[2] == 'a' &&
2278+ salt[3] == '$' &&
2279+ salt[4] >= '0' && salt[4] <= '3' &&
2280+ salt[5] >= '0' && salt[5] <= '9' &&
2281+ salt[6] == '$') {
2282+
2283+ char output[PHP_MAX_SALT_LEN+1];
2284+
2285+ output[0] = 0;
2286+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
2287+ RETVAL_STRING(output, 1);
2288+
2289+ } else {
2290+ RETVAL_STRING(crypt(str, salt), 1);
2291+ }
2292 }
2293 /* }}} */
2294 #endif
2295diff -Nura php-5.1.2/ext/standard/dl.c hardening-patch-5.1.2-0.4.8/ext/standard/dl.c
2296--- php-5.1.2/ext/standard/dl.c 2006-01-01 13:50:14.000000000 +0100
2297+++ hardening-patch-5.1.2-0.4.8/ext/standard/dl.c 2006-01-12 19:50:03.188841984 +0100
2298@@ -164,8 +164,35 @@
2299 RETURN_FALSE;
2300 }
2301 module_entry = get_module();
2302+
2303+ /* check if Hardening-Patch is installed */
2304+ if (module_entry->zend_api < 1000000000) {
2305+ php_error_docref(NULL TSRMLS_CC, error_type,
2306+ "%s: Unable to initialize module\n"
2307+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
2308+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2309+ "These options need to match\n",
2310+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
2311+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2312+ DL_UNLOAD(handle);
2313+ RETURN_FALSE;
2314+ }
2315+
2316+ /* check if correct Hardening-Patch is installed */
2317+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
2318+ php_error_docref(NULL TSRMLS_CC, error_type,
2319+ "%s: Unable to initialize module\n"
2320+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2321+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
2322+ "These options need to match\n",
2323+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
2324+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
2325+ DL_UNLOAD(handle);
2326+ RETURN_FALSE;
2327+ }
2328+
2329 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
2330- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
2331+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
2332 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
2333 struct pre_4_1_0_module_entry {
2334 char *name;
2335@@ -199,7 +226,7 @@
2336 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
2337 } else {
2338 name = module_entry->name;
2339- zend_api = module_entry->zend_api;
2340+ zend_api = module_entry->real_zend_api;
2341 zend_debug = module_entry->zend_debug;
2342 zts = module_entry->zts;
2343 }
2344diff -Nura php-5.1.2/ext/standard/file.c hardening-patch-5.1.2-0.4.8/ext/standard/file.c
2345--- php-5.1.2/ext/standard/file.c 2006-01-01 13:50:14.000000000 +0100
2346+++ hardening-patch-5.1.2-0.4.8/ext/standard/file.c 2006-01-12 19:50:03.190841680 +0100
2347@@ -2291,7 +2291,7 @@
2348 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
2349 /* {{{ proto string realpath(string path)
2350 Return the resolved path */
2351-PHP_FUNCTION(realpath)
2352+PHP_FUNCTION(real_path)
2353 {
2354 zval **path;
2355 char resolved_path_buff[MAXPATHLEN];
2356diff -Nura php-5.1.2/ext/standard/file.h hardening-patch-5.1.2-0.4.8/ext/standard/file.h
2357--- php-5.1.2/ext/standard/file.h 2006-01-01 13:50:14.000000000 +0100
2358+++ hardening-patch-5.1.2-0.4.8/ext/standard/file.h 2006-01-12 19:50:03.190841680 +0100
2359@@ -61,7 +61,7 @@
2360 PHP_FUNCTION(fd_set);
2361 PHP_FUNCTION(fd_isset);
2362 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
2363-PHP_FUNCTION(realpath);
2364+PHP_FUNCTION(real_path);
2365 PHP_FUNCTION(fnmatch);
2366 #endif
2367 PHP_NAMED_FUNCTION(php_if_ftruncate);
2368diff -Nura php-5.1.2/ext/standard/head.c hardening-patch-5.1.2-0.4.8/ext/standard/head.c
2369--- php-5.1.2/ext/standard/head.c 2006-01-01 13:50:14.000000000 +0100
2370+++ hardening-patch-5.1.2-0.4.8/ext/standard/head.c 2006-01-12 19:50:03.191841528 +0100
2371@@ -45,7 +45,7 @@
2372 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2373 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2374 return;
2375-
2376+
2377 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2378 }
2379 /* }}} */
2380diff -Nura php-5.1.2/ext/standard/info.c hardening-patch-5.1.2-0.4.8/ext/standard/info.c
2381--- php-5.1.2/ext/standard/info.c 2006-01-01 13:50:15.000000000 +0100
2382+++ hardening-patch-5.1.2-0.4.8/ext/standard/info.c 2006-01-12 19:50:03.191841528 +0100
2383@@ -411,7 +411,7 @@
2384
2385 if (flag & PHP_INFO_GENERAL) {
2386 char *zend_version = get_zend_version();
2387- char temp_api[10];
2388+ char temp_api[11];
2389 char *logo_guid;
2390
2391 php_uname = php_get_uname('a');
2392@@ -434,11 +434,22 @@
2393 PUTS("\" alt=\"PHP Logo\" /></a>");
2394 }
2395
2396+#if HARDENING_PATCH
2397+ if (!sapi_module.phpinfo_as_text) {
2398+ 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);
2399+ } else {
2400+ char temp_ver[40];
2401+
2402+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2403+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2404+ }
2405+#else
2406 if (!sapi_module.phpinfo_as_text) {
2407 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2408 } else {
2409 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2410- }
2411+ }
2412+#endif
2413 php_info_print_box_end();
2414 php_info_print_table_start();
2415 php_info_print_table_row(2, "System", php_uname );
2416diff -Nura php-5.1.2/ext/standard/php_standard.h hardening-patch-5.1.2-0.4.8/ext/standard/php_standard.h
2417--- php-5.1.2/ext/standard/php_standard.h 2006-01-04 22:31:29.000000000 +0100
2418+++ hardening-patch-5.1.2-0.4.8/ext/standard/php_standard.h 2006-01-12 19:50:03.192841376 +0100
2419@@ -28,6 +28,7 @@
2420 #include "php_mail.h"
2421 #include "md5.h"
2422 #include "sha1.h"
2423+#include "sha256.h"
2424 #include "html.h"
2425 #include "exec.h"
2426 #include "file.h"
2427diff -Nura php-5.1.2/ext/standard/sha256.c hardening-patch-5.1.2-0.4.8/ext/standard/sha256.c
2428--- php-5.1.2/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2429+++ hardening-patch-5.1.2-0.4.8/ext/standard/sha256.c 2006-01-12 20:09:28.413700880 +0100
2430@@ -0,0 +1,388 @@
2431+/*
2432+ +----------------------------------------------------------------------+
2433+ | PHP Version 5 |
2434+ +----------------------------------------------------------------------+
2435+ | Copyright (c) 1997-2004 The PHP Group |
2436+ +----------------------------------------------------------------------+
2437+ | This source file is subject to version 3.0 of the PHP license, |
2438+ | that is bundled with this package in the file LICENSE, and is |
2439+ | available through the world-wide-web at the following url: |
2440+ | http://www.php.net/license/3_0.txt. |
2441+ | If you did not receive a copy of the PHP license and are unable to |
2442+ | obtain it through the world-wide-web, please send a note to |
2443+ | license@php.net so we can mail you a copy immediately. |
2444+ +----------------------------------------------------------------------+
2445+ | Author: Stefan Esser <sesser@php.net> |
2446+ +----------------------------------------------------------------------+
2447+*/
2448+
2449+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2450+
2451+#include "php.h"
2452+
2453+/* This code is heavily based on the PHP md5/sha1 implementations */
2454+
2455+#include "sha256.h"
2456+
2457+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2458+{
2459+ int i;
2460+
2461+ for (i = 0; i < 32; i++) {
2462+ sprintf(sha256str, "%02x", digest[i]);
2463+ sha256str += 2;
2464+ }
2465+
2466+ *sha256str = '\0';
2467+}
2468+
2469+/* {{{ proto string sha256(string str [, bool raw_output])
2470+ Calculate the sha256 hash of a string */
2471+PHP_FUNCTION(sha256)
2472+{
2473+ char *arg;
2474+ int arg_len;
2475+ zend_bool raw_output = 0;
2476+ char sha256str[65];
2477+ PHP_SHA256_CTX context;
2478+ unsigned char digest[32];
2479+
2480+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2481+ return;
2482+ }
2483+
2484+ sha256str[0] = '\0';
2485+ PHP_SHA256Init(&context);
2486+ PHP_SHA256Update(&context, arg, arg_len);
2487+ PHP_SHA256Final(digest, &context);
2488+ if (raw_output) {
2489+ RETURN_STRINGL(digest, 32, 1);
2490+ } else {
2491+ make_sha256_digest(sha256str, digest);
2492+ RETVAL_STRING(sha256str, 1);
2493+ }
2494+
2495+}
2496+
2497+/* }}} */
2498+
2499+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2500+ Calculate the sha256 hash of given filename */
2501+PHP_FUNCTION(sha256_file)
2502+{
2503+ char *arg;
2504+ int arg_len;
2505+ zend_bool raw_output = 0;
2506+ char sha256str[65];
2507+ unsigned char buf[1024];
2508+ unsigned char digest[32];
2509+ PHP_SHA256_CTX context;
2510+ int n;
2511+ php_stream *stream;
2512+
2513+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2514+ return;
2515+ }
2516+
2517+ stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
2518+ if (!stream) {
2519+ RETURN_FALSE;
2520+ }
2521+
2522+ PHP_SHA256Init(&context);
2523+
2524+ while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
2525+ PHP_SHA256Update(&context, buf, n);
2526+ }
2527+
2528+ PHP_SHA256Final(digest, &context);
2529+
2530+ php_stream_close(stream);
2531+
2532+ if (n<0) {
2533+ RETURN_FALSE;
2534+ }
2535+
2536+ if (raw_output) {
2537+ RETURN_STRINGL(digest, 32, 1);
2538+ } else {
2539+ make_sha256_digest(sha256str, digest);
2540+ RETVAL_STRING(sha256str, 1);
2541+ }
2542+}
2543+/* }}} */
2544+
2545+
2546+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2547+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2548+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2549+
2550+static unsigned char PADDING[64] =
2551+{
2552+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2553+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2554+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2555+};
2556+
2557+/* F, G, H and I are basic SHA256 functions.
2558+ */
2559+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2560+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2561+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2562+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2563+
2564+/* ROTATE_RIGHT rotates x right n bits.
2565+ */
2566+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2567+
2568+/* W[i]
2569+ */
2570+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2571+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2572+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2573+
2574+/* ROUND function of sha256
2575+ */
2576+
2577+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2578+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2579+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2580+ (d) += t1; \
2581+ }
2582+
2583+
2584+/* {{{ PHP_SHA256Init
2585+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2586+ */
2587+static void PHP_SHA256Init(PHP_SHA256_CTX * context)
2588+{
2589+ context->count[0] = context->count[1] = 0;
2590+ /* Load magic initialization constants.
2591+ */
2592+ context->state[0] = 0x6a09e667;
2593+ context->state[1] = 0xbb67ae85;
2594+ context->state[2] = 0x3c6ef372;
2595+ context->state[3] = 0xa54ff53a;
2596+ context->state[4] = 0x510e527f;
2597+ context->state[5] = 0x9b05688c;
2598+ context->state[6] = 0x1f83d9ab;
2599+ context->state[7] = 0x5be0cd19;
2600+}
2601+/* }}} */
2602+
2603+/* {{{ PHP_SHA256Update
2604+ SHA256 block update operation. Continues an SHA256 message-digest
2605+ operation, processing another message block, and updating the
2606+ context.
2607+ */
2608+static void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2609+ unsigned int inputLen)
2610+{
2611+ unsigned int i, index, partLen;
2612+
2613+ /* Compute number of bytes mod 64 */
2614+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2615+
2616+ /* Update number of bits */
2617+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2618+ < ((php_uint32) inputLen << 3))
2619+ context->count[1]++;
2620+ context->count[1] += ((php_uint32) inputLen >> 29);
2621+
2622+ partLen = 64 - index;
2623+
2624+ /* Transform as many times as possible.
2625+ */
2626+ if (inputLen >= partLen) {
2627+ memcpy
2628+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2629+ SHA256Transform(context->state, context->buffer);
2630+
2631+ for (i = partLen; i + 63 < inputLen; i += 64)
2632+ SHA256Transform(context->state, &input[i]);
2633+
2634+ index = 0;
2635+ } else
2636+ i = 0;
2637+
2638+ /* Buffer remaining input */
2639+ memcpy
2640+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2641+ inputLen - i);
2642+}
2643+/* }}} */
2644+
2645+/* {{{ PHP_SHA256Final
2646+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2647+ the message digest and zeroizing the context.
2648+ */
2649+static void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2650+{
2651+ unsigned char bits[8];
2652+ unsigned int index, padLen;
2653+
2654+ /* Save number of bits */
2655+ bits[7] = context->count[0] & 0xFF;
2656+ bits[6] = (context->count[0] >> 8) & 0xFF;
2657+ bits[5] = (context->count[0] >> 16) & 0xFF;
2658+ bits[4] = (context->count[0] >> 24) & 0xFF;
2659+ bits[3] = context->count[1] & 0xFF;
2660+ bits[2] = (context->count[1] >> 8) & 0xFF;
2661+ bits[1] = (context->count[1] >> 16) & 0xFF;
2662+ bits[0] = (context->count[1] >> 24) & 0xFF;
2663+
2664+ /* Pad out to 56 mod 64.
2665+ */
2666+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2667+ padLen = (index < 56) ? (56 - index) : (120 - index);
2668+ PHP_SHA256Update(context, PADDING, padLen);
2669+
2670+ /* Append length (before padding) */
2671+ PHP_SHA256Update(context, bits, 8);
2672+
2673+ /* Store state in digest */
2674+ SHA256Encode(digest, context->state, 32);
2675+
2676+ /* Zeroize sensitive information.
2677+ */
2678+ memset((unsigned char*) context, 0, sizeof(*context));
2679+}
2680+/* }}} */
2681+
2682+/* {{{ SHA256Transform
2683+ * SHA256 basic transformation. Transforms state based on block.
2684+ */
2685+static void SHA256Transform(state, block)
2686+php_uint32 state[8];
2687+const unsigned char block[64];
2688+{
2689+ php_uint32 a = state[0], b = state[1], c = state[2];
2690+ php_uint32 d = state[3], e = state[4], f = state[5];
2691+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2692+
2693+ SHA256Decode(x, block, 64);
2694+
2695+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2696+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2697+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2698+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2699+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2700+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2701+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2702+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2703+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2704+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2705+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2706+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2707+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2708+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2709+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2710+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2711+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2712+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2713+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2714+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2715+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2716+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2717+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2718+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2719+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2720+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2721+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2722+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2723+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2724+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2725+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2726+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2727+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2728+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2729+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2730+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2731+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2732+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2733+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2734+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2735+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2736+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2737+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2738+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2739+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2740+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2741+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2742+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2743+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2744+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2745+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2746+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2747+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2748+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2749+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2750+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2751+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2752+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2753+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2754+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2755+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2756+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2757+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2758+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2759+
2760+ state[0] += a;
2761+ state[1] += b;
2762+ state[2] += c;
2763+ state[3] += d;
2764+ state[4] += e;
2765+ state[5] += f;
2766+ state[6] += g;
2767+ state[7] += h;
2768+
2769+ /* Zeroize sensitive information. */
2770+ memset((unsigned char*) x, 0, sizeof(x));
2771+}
2772+/* }}} */
2773+
2774+/* {{{ SHA256Encode
2775+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2776+ a multiple of 4.
2777+ */
2778+static void SHA256Encode(output, input, len)
2779+unsigned char *output;
2780+php_uint32 *input;
2781+unsigned int len;
2782+{
2783+ unsigned int i, j;
2784+
2785+ for (i = 0, j = 0; j < len; i++, j += 4) {
2786+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2787+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2788+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2789+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2790+ }
2791+}
2792+/* }}} */
2793+
2794+/* {{{ SHA256Decode
2795+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2796+ a multiple of 4.
2797+ */
2798+static void SHA256Decode(output, input, len)
2799+php_uint32 *output;
2800+const unsigned char *input;
2801+unsigned int len;
2802+{
2803+ unsigned int i, j;
2804+
2805+ for (i = 0, j = 0; j < len; i++, j += 4)
2806+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2807+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2808+}
2809+/* }}} */
2810+
2811+/*
2812+ * Local variables:
2813+ * tab-width: 4
2814+ * c-basic-offset: 4
2815+ * End:
2816+ * vim600: sw=4 ts=4 fdm=marker
2817+ * vim<600: sw=4 ts=4
2818+ */
2819diff -Nura php-5.1.2/ext/standard/sha256.h hardening-patch-5.1.2-0.4.8/ext/standard/sha256.h
2820--- php-5.1.2/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2821+++ hardening-patch-5.1.2-0.4.8/ext/standard/sha256.h 2006-01-12 20:09:40.242902568 +0100
2822@@ -0,0 +1,40 @@
2823+/*
2824+ +----------------------------------------------------------------------+
2825+ | PHP Version 5 |
2826+ +----------------------------------------------------------------------+
2827+ | Copyright (c) 1997-2004 The PHP Group |
2828+ +----------------------------------------------------------------------+
2829+ | This source file is subject to version 3.0 of the PHP license, |
2830+ | that is bundled with this package in the file LICENSE, and is |
2831+ | available through the world-wide-web at the following url: |
2832+ | http://www.php.net/license/3_0.txt. |
2833+ | If you did not receive a copy of the PHP license and are unable to |
2834+ | obtain it through the world-wide-web, please send a note to |
2835+ | license@php.net so we can mail you a copy immediately. |
2836+ +----------------------------------------------------------------------+
2837+ | Author: Stefan Esser <sesser@php.net> |
2838+ +----------------------------------------------------------------------+
2839+*/
2840+
2841+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2842+
2843+#ifndef SHA256_H
2844+#define SHA256_H
2845+
2846+#include "ext/standard/basic_functions.h"
2847+
2848+/* SHA1 context. */
2849+typedef struct {
2850+ php_uint32 state[8]; /* state (ABCD) */
2851+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2852+ unsigned char buffer[64]; /* input buffer */
2853+} PHP_SHA256_CTX;
2854+
2855+static void PHP_SHA256Init(PHP_SHA256_CTX *);
2856+static void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2857+static void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2858+
2859+PHP_FUNCTION(sha256);
2860+PHP_FUNCTION(sha256_file);
2861+
2862+#endif
2863diff -Nura php-5.1.2/ext/standard/syslog.c hardening-patch-5.1.2-0.4.8/ext/standard/syslog.c
2864--- php-5.1.2/ext/standard/syslog.c 2006-01-01 13:50:15.000000000 +0100
2865+++ hardening-patch-5.1.2-0.4.8/ext/standard/syslog.c 2006-01-12 19:50:03.193841224 +0100
2866@@ -42,6 +42,7 @@
2867 */
2868 PHP_MINIT_FUNCTION(syslog)
2869 {
2870+#if !HARDENING_PATCH
2871 /* error levels */
2872 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2873 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2874@@ -97,7 +98,7 @@
2875 /* AIX doesn't have LOG_PERROR */
2876 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2877 #endif
2878-
2879+#endif
2880 return SUCCESS;
2881 }
2882 /* }}} */
2883diff -Nura php-5.1.2/ext/varfilter/config.m4 hardening-patch-5.1.2-0.4.8/ext/varfilter/config.m4
2884--- php-5.1.2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2885+++ hardening-patch-5.1.2-0.4.8/ext/varfilter/config.m4 2006-01-12 19:50:03.193841224 +0100
2886@@ -0,0 +1,11 @@
2887+dnl
2888+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2889+dnl
2890+
2891+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2892+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2893+
2894+if test "$PHP_VARFILTER" != "no"; then
2895+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2896+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2897+fi
2898diff -Nura php-5.1.2/ext/varfilter/CREDITS hardening-patch-5.1.2-0.4.8/ext/varfilter/CREDITS
2899--- php-5.1.2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2900+++ hardening-patch-5.1.2-0.4.8/ext/varfilter/CREDITS 2006-01-12 19:50:03.194841072 +0100
2901@@ -0,0 +1,2 @@
2902+varfilter
2903+Stefan Esser
2904\ Kein Zeilenumbruch am Dateiende.
2905diff -Nura php-5.1.2/ext/varfilter/php_varfilter.h hardening-patch-5.1.2-0.4.8/ext/varfilter/php_varfilter.h
2906--- php-5.1.2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2907+++ hardening-patch-5.1.2-0.4.8/ext/varfilter/php_varfilter.h 2006-01-12 19:50:03.194841072 +0100
2908@@ -0,0 +1,144 @@
2909+/*
2910+ +----------------------------------------------------------------------+
2911+ | Hardened-PHP Project's varfilter extension |
2912+ +----------------------------------------------------------------------+
2913+ | Copyright (c) 2004-2005 Stefan Esser |
2914+ +----------------------------------------------------------------------+
2915+ | This source file is subject to version 2.02 of the PHP license, |
2916+ | that is bundled with this package in the file LICENSE, and is |
2917+ | available at through the world-wide-web at |
2918+ | http://www.php.net/license/2_02.txt. |
2919+ | If you did not receive a copy of the PHP license and are unable to |
2920+ | obtain it through the world-wide-web, please send a note to |
2921+ | license@php.net so we can mail you a copy immediately. |
2922+ +----------------------------------------------------------------------+
2923+ | Author: Stefan Esser <sesser@hardened-php.net> |
2924+ +----------------------------------------------------------------------+
2925+
2926+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2927+*/
2928+
2929+#ifndef PHP_VARFILTER_H
2930+#define PHP_VARFILTER_H
2931+
2932+extern zend_module_entry varfilter_module_entry;
2933+#define phpext_varfilter_ptr &varfilter_module_entry
2934+
2935+#ifdef PHP_WIN32
2936+#define PHP_VARFILTER_API __declspec(dllexport)
2937+#else
2938+#define PHP_VARFILTER_API
2939+#endif
2940+
2941+#ifdef ZTS
2942+#include "TSRM.h"
2943+#endif
2944+
2945+#include "SAPI.h"
2946+
2947+#include "php_variables.h"
2948+
2949+#ifdef ZEND_ENGINE_2
2950+#define HASH_HTTP_GET_VARS 0x2095733f
2951+#define HASH_HTTP_POST_VARS 0xbfee1265
2952+#define HASH_HTTP_COOKIE_VARS 0xaaca9d99
2953+#define HASH_HTTP_ENV_VARS 0x1fe186a8
2954+#define HASH_HTTP_SERVER_VARS 0xc987afd6
2955+#define HASH_HTTP_SESSION_VARS 0x7aba0d43
2956+#define HASH_HTTP_POST_FILES 0x98eb1ddc
2957+#define HASH_HTTP_RAW_POST_DATA 0xdd633fec
2958+#else
2959+#define HASH_HTTP_GET_VARS 0x8d8645bd
2960+#define HASH_HTTP_POST_VARS 0x7c699bf3
2961+#define HASH_HTTP_COOKIE_VARS 0x93ad0d6f
2962+#define HASH_HTTP_ENV_VARS 0x84da3016
2963+#define HASH_HTTP_SERVER_VARS 0x6dbf964e
2964+#define HASH_HTTP_SESSION_VARS 0x322906f5
2965+#define HASH_HTTP_POST_FILES 0xe4e4ce70
2966+#define HASH_HTTP_RAW_POST_DATA 0xe6137a0e
2967+#endif
2968+
2969+PHP_MINIT_FUNCTION(varfilter);
2970+PHP_MSHUTDOWN_FUNCTION(varfilter);
2971+PHP_RINIT_FUNCTION(varfilter);
2972+PHP_RSHUTDOWN_FUNCTION(varfilter);
2973+PHP_MINFO_FUNCTION(varfilter);
2974+
2975+
2976+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2977+/* request variables */
2978+ long max_request_variables;
2979+ long cur_request_variables;
2980+ long max_varname_length;
2981+ long max_totalname_length;
2982+ long max_value_length;
2983+ long max_array_depth;
2984+ long max_array_index_length;
2985+ zend_bool disallow_nul;
2986+/* cookie variables */
2987+ long max_cookie_vars;
2988+ long cur_cookie_vars;
2989+ long max_cookie_name_length;
2990+ long max_cookie_totalname_length;
2991+ long max_cookie_value_length;
2992+ long max_cookie_array_depth;
2993+ long max_cookie_array_index_length;
2994+ zend_bool disallow_cookie_nul;
2995+/* get variables */
2996+ long max_get_vars;
2997+ long cur_get_vars;
2998+ long max_get_name_length;
2999+ long max_get_totalname_length;
3000+ long max_get_value_length;
3001+ long max_get_array_depth;
3002+ long max_get_array_index_length;
3003+ zend_bool disallow_get_nul;
3004+/* post variables */
3005+ long max_post_vars;
3006+ long cur_post_vars;
3007+ long max_post_name_length;
3008+ long max_post_totalname_length;
3009+ long max_post_value_length;
3010+ long max_post_array_depth;
3011+ long max_post_array_index_length;
3012+ zend_bool disallow_post_nul;
3013+/* fileupload */
3014+ long max_uploads;
3015+ long cur_uploads;
3016+ zend_bool disallow_elf_files;
3017+ char *verification_script;
3018+
3019+ zend_bool no_more_variables;
3020+ zend_bool no_more_get_variables;
3021+ zend_bool no_more_post_variables;
3022+ zend_bool no_more_cookie_variables;
3023+ zend_bool no_more_uploads;
3024+
3025+ZEND_END_MODULE_GLOBALS(varfilter)
3026+
3027+
3028+#ifdef ZTS
3029+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
3030+#else
3031+#define VARFILTER_G(v) (varfilter_globals.v)
3032+#endif
3033+
3034+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
3035+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
3036+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
3037+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
3038+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
3039+SAPI_TREAT_DATA_FUNC(varfilter_treat_data);
3040+
3041+
3042+
3043+#endif /* PHP_VARFILTER_H */
3044+
3045+
3046+/*
3047+ * Local variables:
3048+ * tab-width: 4
3049+ * c-basic-offset: 4
3050+ * indent-tabs-mode: t
3051+ * End:
3052+ */
3053diff -Nura php-5.1.2/ext/varfilter/varfilter.c hardening-patch-5.1.2-0.4.8/ext/varfilter/varfilter.c
3054--- php-5.1.2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
3055+++ hardening-patch-5.1.2-0.4.8/ext/varfilter/varfilter.c 2006-01-12 19:50:03.196840768 +0100
3056@@ -0,0 +1,915 @@
3057+/*
3058+ +----------------------------------------------------------------------+
3059+ | Hardened-PHP Project's varfilter extension |
3060+ +----------------------------------------------------------------------+
3061+ | Copyright (c) 2004-2005 Stefan Esser |
3062+ +----------------------------------------------------------------------+
3063+ | This source file is subject to version 2.02 of the PHP license, |
3064+ | that is bundled with this package in the file LICENSE, and is |
3065+ | available at through the world-wide-web at |
3066+ | http://www.php.net/license/2_02.txt. |
3067+ | If you did not receive a copy of the PHP license and are unable to |
3068+ | obtain it through the world-wide-web, please send a note to |
3069+ | license@php.net so we can mail you a copy immediately. |
3070+ +----------------------------------------------------------------------+
3071+ | Author: Stefan Esser <sesser@hardened-php.net> |
3072+ +----------------------------------------------------------------------+
3073+
3074+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
3075+*/
3076+
3077+#ifdef HAVE_CONFIG_H
3078+#include "config.h"
3079+#endif
3080+
3081+#include "php.h"
3082+#include "php_ini.h"
3083+#include "ext/standard/info.h"
3084+#include "php_varfilter.h"
3085+#include "hardening_patch.h"
3086+
3087+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
3088+
3089+/* True global resources - no need for thread safety here */
3090+static int le_varfilter;
3091+
3092+static void (*orig_register_server_variables)(zval *track_vars_array TSRMLS_DC) = NULL;
3093+static int (*orig_header_handler)(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) = NULL;
3094+static zend_bool hooked = 0;
3095+
3096+/* {{{ varfilter_module_entry
3097+ */
3098+zend_module_entry varfilter_module_entry = {
3099+#if ZEND_MODULE_API_NO >= 20010901
3100+ STANDARD_MODULE_HEADER,
3101+#endif
3102+ "varfilter",
3103+ NULL,
3104+ PHP_MINIT(varfilter),
3105+ PHP_MSHUTDOWN(varfilter),
3106+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
3107+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
3108+ PHP_MINFO(varfilter),
3109+#if ZEND_MODULE_API_NO >= 20010901
3110+ "0.4.8", /* Replace with version number for your extension */
3111+#endif
3112+ STANDARD_MODULE_PROPERTIES
3113+};
3114+/* }}} */
3115+
3116+#ifdef COMPILE_DL_VARFILTER
3117+ZEND_GET_MODULE(varfilter)
3118+#endif
3119+
3120+/* {{{ PHP_INI
3121+ */
3122+PHP_INI_BEGIN()
3123+ /* for backward compatibility */
3124+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3125+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3126+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3127+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3128+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3129+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3130+
3131+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
3132+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
3133+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
3134+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
3135+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
3136+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
3137+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
3138+
3139+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
3140+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
3141+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
3142+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
3143+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
3144+ 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)
3145+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
3146+
3147+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
3148+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
3149+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
3150+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
3151+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
3152+ 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)
3153+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
3154+
3155+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
3156+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
3157+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
3158+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
3159+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
3160+ 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)
3161+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
3162+
3163+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
3164+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
3165+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
3166+
3167+
3168+PHP_INI_END()
3169+/* }}} */
3170+
3171+/* {{{ php_varfilter_init_globals
3172+ */
3173+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
3174+{
3175+ varfilter_globals->max_request_variables = 200;
3176+ varfilter_globals->max_varname_length = 64;
3177+ varfilter_globals->max_value_length = 10000;
3178+ varfilter_globals->max_array_depth = 100;
3179+ varfilter_globals->max_totalname_length = 256;
3180+ varfilter_globals->max_array_index_length = 64;
3181+ varfilter_globals->disallow_nul = 1;
3182+
3183+ varfilter_globals->max_cookie_vars = 100;
3184+ varfilter_globals->max_cookie_name_length = 64;
3185+ varfilter_globals->max_cookie_totalname_length = 256;
3186+ varfilter_globals->max_cookie_value_length = 10000;
3187+ varfilter_globals->max_cookie_array_depth = 100;
3188+ varfilter_globals->max_cookie_array_index_length = 64;
3189+ varfilter_globals->disallow_cookie_nul = 1;
3190+
3191+ varfilter_globals->max_get_vars = 100;
3192+ varfilter_globals->max_get_name_length = 64;
3193+ varfilter_globals->max_get_totalname_length = 256;
3194+ varfilter_globals->max_get_value_length = 512;
3195+ varfilter_globals->max_get_array_depth = 50;
3196+ varfilter_globals->max_get_array_index_length = 64;
3197+ varfilter_globals->disallow_get_nul = 1;
3198+
3199+ varfilter_globals->max_post_vars = 200;
3200+ varfilter_globals->max_post_name_length = 64;
3201+ varfilter_globals->max_post_totalname_length = 256;
3202+ varfilter_globals->max_post_value_length = 65000;
3203+ varfilter_globals->max_post_array_depth = 100;
3204+ varfilter_globals->max_post_array_index_length = 64;
3205+ varfilter_globals->disallow_post_nul = 1;
3206+
3207+ varfilter_globals->max_uploads = 25;
3208+ varfilter_globals->disallow_elf_files = 1;
3209+ varfilter_globals->verification_script = NULL;
3210+
3211+ varfilter_globals->no_more_variables = 0;
3212+ varfilter_globals->no_more_get_variables = 0;
3213+ varfilter_globals->no_more_post_variables = 0;
3214+ varfilter_globals->no_more_cookie_variables = 0;
3215+ varfilter_globals->no_more_uploads = 0;
3216+
3217+ varfilter_globals->cur_request_variables = 0;
3218+ varfilter_globals->cur_get_vars = 0;
3219+ varfilter_globals->cur_post_vars = 0;
3220+ varfilter_globals->cur_cookie_vars = 0;
3221+
3222+ varfilter_globals->cur_uploads = 0;
3223+
3224+}
3225+/* }}} */
3226+
3227+
3228+void varfilter_register_server_variables(zval *track_vars_array TSRMLS_DC)
3229+{
3230+ HashTable *svars;
3231+ int retval, failure=0;
3232+
3233+ orig_register_server_variables(track_vars_array TSRMLS_CC);
3234+
3235+ svars = Z_ARRVAL_P(track_vars_array);
3236+
3237+ retval = zend_hash_del_key_or_index(svars, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), HASH_HTTP_GET_VARS, HASH_DEL_INDEX);
3238+ if (retval == SUCCESS) failure = 1;
3239+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), HASH_HTTP_POST_VARS, HASH_DEL_INDEX);
3240+ if (retval == SUCCESS) failure = 1;
3241+ retval = zend_hash_del_key_or_index(svars, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), HASH_HTTP_COOKIE_VARS, HASH_DEL_INDEX);
3242+ if (retval == SUCCESS) failure = 1;
3243+ retval = zend_hash_del_key_or_index(svars, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS"), HASH_HTTP_ENV_VARS, HASH_DEL_INDEX);
3244+ if (retval == SUCCESS) failure = 1;
3245+ retval = zend_hash_del_key_or_index(svars, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), HASH_HTTP_SERVER_VARS, HASH_DEL_INDEX);
3246+ if (retval == SUCCESS) failure = 1;
3247+ retval = zend_hash_del_key_or_index(svars, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS"), HASH_HTTP_SESSION_VARS, HASH_DEL_INDEX);
3248+ if (retval == SUCCESS) failure = 1;
3249+ retval = zend_hash_del_key_or_index(svars, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES"), HASH_HTTP_POST_FILES, HASH_DEL_INDEX);
3250+ if (retval == SUCCESS) failure = 1;
3251+ 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);
3252+ if (retval == SUCCESS) failure = 1;
3253+
3254+ if (failure) {
3255+ php_security_log(S_VARS, "Attacker tried to overwrite a superglobal through a HTTP header");
3256+ }
3257+}
3258+
3259+int varfilter_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
3260+{
3261+ int retval = SAPI_HEADER_ADD, i;
3262+ char *tmp;
3263+
3264+ if (!HG(hphp_multiheader) && sapi_header && sapi_header->header) {
3265+
3266+ tmp = sapi_header->header;
3267+ for (i=0; i<sapi_header->header_len; i++, tmp++) {
3268+ if (tmp[0] == 0) {
3269+ char *fname = get_active_function_name(TSRMLS_C);
3270+
3271+ if (!fname) {
3272+ fname = "unknown";
3273+ }
3274+
3275+ php_security_log(S_MISC, "%s() - wanted to send a HTTP header with an ASCII NUL in it", fname);
3276+ sapi_header->header_len = i;
3277+ } else if (tmp[0] == '\n' && (i == sapi_header->header_len-1 || (tmp[1] != ' ' && tmp[1] != '\t'))) {
3278+ char *fname = get_active_function_name(TSRMLS_C);
3279+
3280+ if (!fname) {
3281+ fname = "unknown";
3282+ }
3283+
3284+ php_security_log(S_MISC, "%s() - wanted to send multiple HTTP headers at once", fname);
3285+ sapi_header->header_len = i;
3286+ tmp[0] = 0;
3287+ }
3288+ }
3289+ }
3290+
3291+ if (orig_header_handler) {
3292+ retval = orig_header_handler(sapi_header, sapi_headers TSRMLS_CC);
3293+ }
3294+
3295+ return retval;
3296+}
3297+
3298+/* {{{ PHP_MINIT_FUNCTION
3299+ */
3300+PHP_MINIT_FUNCTION(varfilter)
3301+{
3302+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
3303+ REGISTER_INI_ENTRIES();
3304+
3305+ if (!hooked) {
3306+ void *temp;
3307+ hooked = 1;
3308+
3309+ temp = (void *)sapi_module.register_server_variables;
3310+ if (temp != varfilter_register_server_variables) {
3311+ orig_register_server_variables = temp;
3312+ }
3313+ temp = (void *)sapi_module.header_handler;
3314+ if (temp != varfilter_header_handler) {
3315+ orig_header_handler = temp;
3316+ }
3317+ }
3318+
3319+ sapi_register_input_filter(varfilter_input_filter);
3320+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
3321+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
3322+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
3323+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
3324+
3325+ sapi_module.header_handler = varfilter_header_handler;
3326+ sapi_module.register_server_variables = varfilter_register_server_variables;
3327+
3328+
3329+ return SUCCESS;
3330+}
3331+/* }}} */
3332+
3333+/* {{{ PHP_MSHUTDOWN_FUNCTION
3334+ */
3335+PHP_MSHUTDOWN_FUNCTION(varfilter)
3336+{
3337+ UNREGISTER_INI_ENTRIES();
3338+
3339+ return SUCCESS;
3340+}
3341+/* }}} */
3342+
3343+/* Remove if there's nothing to do at request start */
3344+/* {{{ PHP_RINIT_FUNCTION
3345+ */
3346+PHP_RINIT_FUNCTION(varfilter)
3347+{
3348+ VARFILTER_G(cur_request_variables) = 0;
3349+ VARFILTER_G(cur_get_vars) = 0;
3350+ VARFILTER_G(cur_post_vars) = 0;
3351+ VARFILTER_G(cur_cookie_vars) = 0;
3352+
3353+ VARFILTER_G(cur_uploads) = 0;
3354+
3355+ VARFILTER_G(no_more_variables) = 0;
3356+ VARFILTER_G(no_more_get_variables) = 0;
3357+ VARFILTER_G(no_more_post_variables) = 0;
3358+ VARFILTER_G(no_more_cookie_variables) = 0;
3359+ VARFILTER_G(no_more_uploads) = 0;
3360+
3361+ return SUCCESS;
3362+}
3363+/* }}} */
3364+
3365+/* Remove if there's nothing to do at request end */
3366+/* {{{ PHP_RSHUTDOWN_FUNCTION
3367+ */
3368+PHP_RSHUTDOWN_FUNCTION(varfilter)
3369+{
3370+ return SUCCESS;
3371+}
3372+/* }}} */
3373+
3374+/* {{{ PHP_MINFO_FUNCTION
3375+ */
3376+PHP_MINFO_FUNCTION(varfilter)
3377+{
3378+ php_info_print_table_start();
3379+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
3380+ php_info_print_table_end();
3381+
3382+ DISPLAY_INI_ENTRIES();
3383+}
3384+/* }}} */
3385+
3386+/* {{{ normalize_varname
3387+ */
3388+static void normalize_varname(char *varname)
3389+{
3390+ char *s=varname, *index=NULL, *indexend=NULL, *p;
3391+
3392+ /* overjump leading space */
3393+ while (*s == ' ') {
3394+ s++;
3395+ }
3396+
3397+ /* and remove it */
3398+ if (s != varname) {
3399+ memmove(varname, s, strlen(s)+1);
3400+ }
3401+
3402+ for (p=varname; *p && *p != '['; p++) {
3403+ switch(*p) {
3404+ case ' ':
3405+ case '.':
3406+ *p='_';
3407+ break;
3408+ }
3409+ }
3410+
3411+ /* find index */
3412+ index = strchr(varname, '[');
3413+ if (index) {
3414+ index++;
3415+ s=index;
3416+ } else {
3417+ return;
3418+ }
3419+
3420+ /* done? */
3421+ while (index) {
3422+
3423+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3424+ index++;
3425+ }
3426+ indexend = strchr(index, ']');
3427+ indexend = indexend ? indexend + 1 : index + strlen(index);
3428+
3429+ if (s != index) {
3430+ memmove(s, index, strlen(index)+1);
3431+ s += indexend-index;
3432+ } else {
3433+ s = indexend;
3434+ }
3435+
3436+ if (*s == '[') {
3437+ s++;
3438+ index = s;
3439+ } else {
3440+ index = NULL;
3441+ }
3442+ }
3443+ *s++='\0';
3444+}
3445+/* }}} */
3446+
3447+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3448+ */
3449+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3450+{
3451+ char *index, *prev_index = NULL, *var;
3452+ unsigned int var_len, total_len, depth = 0;
3453+
3454+ var = estrdup(varname);
3455+
3456+ /* Normalize the variable name */
3457+ normalize_varname(var);
3458+
3459+ /* Find length of variable name */
3460+ index = strchr(var, '[');
3461+ total_len = strlen(var);
3462+ var_len = index ? index-var : total_len;
3463+
3464+ /* Drop this variable if it exceeds the varname/total length limit */
3465+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3466+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3467+ goto return_failure;
3468+ }
3469+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3470+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3471+ goto return_failure;
3472+ }
3473+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3474+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3475+
3476+ goto return_failure;
3477+ }
3478+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3479+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3480+ goto return_failure;
3481+ }
3482+
3483+ /* Find out array depth */
3484+ while (index) {
3485+ unsigned int index_length;
3486+
3487+ depth++;
3488+ index = strchr(index+1, '[');
3489+
3490+ if (prev_index) {
3491+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3492+
3493+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3494+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3495+ goto return_failure;
3496+ }
3497+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3498+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3499+ goto return_failure;
3500+ }
3501+ prev_index = index;
3502+ }
3503+
3504+ }
3505+
3506+ /* Drop this variable if it exceeds the array depth limit */
3507+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3508+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3509+ goto return_failure;
3510+ }
3511+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3512+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3513+ goto return_failure;
3514+ }
3515+
3516+
3517+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3518+ /* This is to protect several silly scripts that do globalizing themself */
3519+
3520+ switch (var_len) {
3521+ case 18:
3522+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3523+ break;
3524+ case 17:
3525+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3526+ break;
3527+ case 16:
3528+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3529+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3530+ break;
3531+ case 15:
3532+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3533+ break;
3534+ case 14:
3535+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3536+ break;
3537+ case 13:
3538+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3539+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3540+ break;
3541+ case 8:
3542+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3543+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3544+ break;
3545+ case 7:
3546+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3547+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3548+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3549+ break;
3550+ case 6:
3551+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3552+ break;
3553+ case 5:
3554+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3555+ break;
3556+ case 4:
3557+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3558+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3559+ break;
3560+ }
3561+
3562+ efree(var);
3563+ return SUCCESS;
3564+protected_varname2:
3565+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3566+return_failure:
3567+ efree(var);
3568+ return FAILURE;
3569+}
3570+/* }}} */
3571+
3572+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3573+ */
3574+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3575+{
3576+ /* Drop if no more variables flag is set */
3577+ if (VARFILTER_G(no_more_uploads)) {
3578+ return FAILURE;
3579+ }
3580+ /* Drop this fileupload if the limit is reached */
3581+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3582+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3583+ VARFILTER_G(no_more_uploads) = 1;
3584+ return FAILURE;
3585+ }
3586+
3587+ return SUCCESS;
3588+}
3589+/* }}} */
3590+
3591+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3592+ */
3593+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3594+{
3595+
3596+ if (VARFILTER_G(disallow_elf_files)) {
3597+
3598+ if (offset == 0 && buffer_len > 10) {
3599+
3600+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3601+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3602+ return FAILURE;
3603+ }
3604+ }
3605+
3606+ }
3607+
3608+ return SUCCESS;
3609+}
3610+/* }}} */
3611+
3612+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3613+ */
3614+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3615+{
3616+ int retval = SUCCESS;
3617+
3618+ if (VARFILTER_G(verification_script)) {
3619+ char cmd[8192];
3620+ FILE *in;
3621+ int first=1;
3622+
3623+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3624+
3625+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3626+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3627+ return FAILURE;
3628+ }
3629+
3630+ retval = FAILURE;
3631+
3632+ /* read and forget the result */
3633+ while (1) {
3634+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3635+ if (readbytes<=0) {
3636+ break;
3637+ }
3638+ if (first) {
3639+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3640+ first = 0;
3641+ }
3642+ }
3643+ pclose(in);
3644+ }
3645+
3646+ if (retval != SUCCESS) {
3647+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3648+ return FAILURE;
3649+ }
3650+
3651+ VARFILTER_G(cur_uploads)++;
3652+ return SUCCESS;
3653+}
3654+/* }}} */
3655+
3656+/* {{{ SAPI_INPUT_FILTER_FUNC
3657+ */
3658+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3659+{
3660+ char *index, *prev_index = NULL;
3661+ unsigned int var_len, total_len, depth = 0;
3662+
3663+ /* Drop this variable if the limit was reached */
3664+ switch (arg) {
3665+ case PARSE_GET:
3666+ if (VARFILTER_G(no_more_get_variables)) {
3667+ return 0;
3668+ }
3669+ break;
3670+ case PARSE_POST:
3671+ if (VARFILTER_G(no_more_post_variables)) {
3672+ return 0;
3673+ }
3674+ break;
3675+ case PARSE_COOKIE:
3676+ if (VARFILTER_G(no_more_cookie_variables)) {
3677+ return 0;
3678+ }
3679+ break;
3680+ default: /* we do not want to protect parse_str() and friends */
3681+ if (new_val_len) {
3682+ *new_val_len = val_len;
3683+ }
3684+ return 1;
3685+ }
3686+ if (VARFILTER_G(no_more_variables)) {
3687+ return 0;
3688+ }
3689+
3690+ /* Drop this variable if the limit is now reached */
3691+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3692+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3693+ VARFILTER_G(no_more_variables) = 1;
3694+ return 0;
3695+ }
3696+ switch (arg) {
3697+ case PARSE_GET:
3698+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3699+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3700+ VARFILTER_G(no_more_get_variables) = 1;
3701+ return 0;
3702+ }
3703+ break;
3704+ case PARSE_COOKIE:
3705+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3706+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3707+ VARFILTER_G(no_more_cookie_variables) = 1;
3708+ return 0;
3709+ }
3710+ break;
3711+ case PARSE_POST:
3712+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3713+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3714+ VARFILTER_G(no_more_post_variables) = 1;
3715+ return 0;
3716+ }
3717+ break;
3718+ }
3719+
3720+
3721+ /* Drop this variable if it exceeds the value length limit */
3722+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3723+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3724+ return 0;
3725+ }
3726+ switch (arg) {
3727+ case PARSE_GET:
3728+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3729+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3730+ return 0;
3731+ }
3732+ break;
3733+ case PARSE_COOKIE:
3734+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3735+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3736+ return 0;
3737+ }
3738+ break;
3739+ case PARSE_POST:
3740+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3741+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3742+ return 0;
3743+ }
3744+ break;
3745+ }
3746+
3747+ /* Normalize the variable name */
3748+ normalize_varname(var);
3749+
3750+ /* Find length of variable name */
3751+ index = strchr(var, '[');
3752+ total_len = strlen(var);
3753+ var_len = index ? index-var : total_len;
3754+
3755+ /* Drop this variable if it exceeds the varname/total length limit */
3756+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3757+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3758+ return 0;
3759+ }
3760+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3761+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3762+ return 0;
3763+ }
3764+ switch (arg) {
3765+ case PARSE_GET:
3766+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3767+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3768+ return 0;
3769+ }
3770+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3771+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3772+ return 0;
3773+ }
3774+ break;
3775+ case PARSE_COOKIE:
3776+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3777+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3778+ return 0;
3779+ }
3780+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3781+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3782+ return 0;
3783+ }
3784+ break;
3785+ case PARSE_POST:
3786+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3787+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3788+ return 0;
3789+ }
3790+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3791+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3792+ return 0;
3793+ }
3794+ break;
3795+ }
3796+
3797+ /* Find out array depth */
3798+ while (index) {
3799+ unsigned int index_length;
3800+
3801+ depth++;
3802+ index = strchr(index+1, '[');
3803+
3804+ if (prev_index) {
3805+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3806+
3807+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3808+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3809+ return 0;
3810+ }
3811+ switch (arg) {
3812+ case PARSE_GET:
3813+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3814+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3815+ return 0;
3816+ }
3817+ break;
3818+ case PARSE_COOKIE:
3819+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3820+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3821+ return 0;
3822+ }
3823+ break;
3824+ case PARSE_POST:
3825+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3826+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3827+ return 0;
3828+ }
3829+ break;
3830+ }
3831+ prev_index = index;
3832+ }
3833+
3834+ }
3835+
3836+ /* Drop this variable if it exceeds the array depth limit */
3837+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3838+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3839+ return 0;
3840+ }
3841+ switch (arg) {
3842+ case PARSE_GET:
3843+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3844+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3845+ return 0;
3846+ }
3847+ break;
3848+ case PARSE_COOKIE:
3849+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3850+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3851+ return 0;
3852+ }
3853+ break;
3854+ case PARSE_POST:
3855+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3856+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3857+ return 0;
3858+ }
3859+ break;
3860+ }
3861+
3862+ /* Check if variable value is truncated by a \0 */
3863+
3864+ if (val && *val && val_len != strlen(*val)) {
3865+
3866+ if (VARFILTER_G(disallow_nul)) {
3867+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3868+ return 0;
3869+ }
3870+ switch (arg) {
3871+ case PARSE_GET:
3872+ if (VARFILTER_G(disallow_get_nul)) {
3873+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3874+ return 0;
3875+ }
3876+ break;
3877+ case PARSE_COOKIE:
3878+ if (VARFILTER_G(disallow_cookie_nul)) {
3879+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3880+ return 0;
3881+ }
3882+ break;
3883+ case PARSE_POST:
3884+ if (VARFILTER_G(disallow_post_nul)) {
3885+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3886+ return 0;
3887+ }
3888+ break;
3889+ }
3890+ }
3891+
3892+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3893+ /* This is to protect several silly scripts that do globalizing themself */
3894+
3895+ switch (var_len) {
3896+ case 18:
3897+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3898+ break;
3899+ case 17:
3900+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3901+ break;
3902+ case 16:
3903+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3904+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3905+ break;
3906+ case 15:
3907+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3908+ break;
3909+ case 14:
3910+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3911+ break;
3912+ case 13:
3913+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3914+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3915+ break;
3916+ case 8:
3917+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3918+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3919+ break;
3920+ case 7:
3921+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3922+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3923+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3924+ break;
3925+ case 6:
3926+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3927+ break;
3928+ case 5:
3929+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3930+ break;
3931+ case 4:
3932+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3933+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3934+ break;
3935+ }
3936+
3937+ /* Okay let PHP register this variable */
3938+ VARFILTER_G(cur_request_variables)++;
3939+ switch (arg) {
3940+ case PARSE_GET:
3941+ VARFILTER_G(cur_get_vars)++;
3942+ break;
3943+ case PARSE_COOKIE:
3944+ VARFILTER_G(cur_cookie_vars)++;
3945+ break;
3946+ case PARSE_POST:
3947+ VARFILTER_G(cur_post_vars)++;
3948+ break;
3949+ }
3950+
3951+ if (new_val_len) {
3952+ *new_val_len = val_len;
3953+ }
3954+
3955+ return 1;
3956+protected_varname:
3957+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3958+ return 0;
3959+}
3960+/* }}} */
3961+
3962+/*
3963+ * Local variables:
3964+ * tab-width: 4
3965+ * c-basic-offset: 4
3966+ * End:
3967+ * vim600: noet sw=4 ts=4 fdm=marker
3968+ * vim<600: noet sw=4 ts=4
3969+ */
3970+
3971+
3972diff -Nura php-5.1.2/main/fopen_wrappers.c hardening-patch-5.1.2-0.4.8/main/fopen_wrappers.c
3973--- php-5.1.2/main/fopen_wrappers.c 2006-01-01 13:50:17.000000000 +0100
3974+++ hardening-patch-5.1.2-0.4.8/main/fopen_wrappers.c 2006-01-12 19:50:03.196840768 +0100
3975@@ -154,6 +154,21 @@
3976 char *pathbuf;
3977 char *ptr;
3978 char *end;
3979+ char path_copy[MAXPATHLEN];
3980+ int path_len;
3981+
3982+ /* Special case path ends with a trailing slash */
3983+ path_len = strlen(path);
3984+ if (path_len >= MAXPATHLEN) {
3985+ errno = EPERM; /* we deny permission to open it */
3986+ return -1;
3987+ }
3988+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3989+ memcpy(path_copy, path, path_len+1);
3990+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3991+ path_copy[path_len] = '\0';
3992+ path = (const char *)&path_copy;
3993+ }
3994
3995 pathbuf = estrdup(PG(open_basedir));
3996
3997diff -Nura php-5.1.2/main/hardened_globals.h hardening-patch-5.1.2-0.4.8/main/hardened_globals.h
3998--- php-5.1.2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3999+++ hardening-patch-5.1.2-0.4.8/main/hardened_globals.h 2006-01-12 19:50:03.197840616 +0100
4000@@ -0,0 +1,62 @@
4001+/*
4002+ +----------------------------------------------------------------------+
4003+ | Hardening-Patch for PHP |
4004+ +----------------------------------------------------------------------+
4005+ | Copyright (c) 2004-2005 Stefan Esser |
4006+ +----------------------------------------------------------------------+
4007+ | This source file is subject to version 2.02 of the PHP license, |
4008+ | that is bundled with this package in the file LICENSE, and is |
4009+ | available at through the world-wide-web at |
4010+ | http://www.php.net/license/2_02.txt. |
4011+ | If you did not receive a copy of the PHP license and are unable to |
4012+ | obtain it through the world-wide-web, please send a note to |
4013+ | license@php.net so we can mail you a copy immediately. |
4014+ +----------------------------------------------------------------------+
4015+ | Author: Stefan Esser <sesser@hardened-php.net> |
4016+ +----------------------------------------------------------------------+
4017+ */
4018+
4019+#ifndef HARDENED_GLOBALS_H
4020+#define HARDENED_GLOBALS_H
4021+
4022+typedef struct _hardened_globals hardened_globals_struct;
4023+
4024+#ifdef ZTS
4025+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
4026+extern int hardened_globals_id;
4027+#else
4028+# define HG(v) (hardened_globals.v)
4029+extern struct _hardened_globals hardened_globals;
4030+#endif
4031+
4032+
4033+struct _hardened_globals {
4034+#if HARDENING_PATCH_MM_PROTECT
4035+ unsigned int canary_1;
4036+ unsigned int canary_2;
4037+#endif
4038+#if HARDENING_PATCH_LL_PROTECT
4039+ unsigned int canary_3;
4040+ unsigned int canary_4;
4041+ unsigned int ll_canary_inited;
4042+#endif
4043+ zend_bool hphp_sql_bailout_on_error;
4044+ zend_bool hphp_multiheader;
4045+ HashTable *eval_whitelist;
4046+ HashTable *eval_blacklist;
4047+ HashTable *func_whitelist;
4048+ HashTable *func_blacklist;
4049+ HashTable *include_whitelist;
4050+ HashTable *include_blacklist;
4051+ unsigned int dummy;
4052+};
4053+
4054+
4055+#endif /* HARDENED_GLOBALS_H */
4056+
4057+/*
4058+ * Local variables:
4059+ * tab-width: 4
4060+ * c-basic-offset: 4
4061+ * End:
4062+ */
4063diff -Nura php-5.1.2/main/hardening_patch.c hardening-patch-5.1.2-0.4.8/main/hardening_patch.c
4064--- php-5.1.2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
4065+++ hardening-patch-5.1.2-0.4.8/main/hardening_patch.c 2006-01-12 19:50:03.197840616 +0100
4066@@ -0,0 +1,430 @@
4067+/*
4068+ +----------------------------------------------------------------------+
4069+ | Hardening Patch for PHP |
4070+ +----------------------------------------------------------------------+
4071+ | Copyright (c) 2004-2005 Stefan Esser |
4072+ +----------------------------------------------------------------------+
4073+ | This source file is subject to version 2.02 of the PHP license, |
4074+ | that is bundled with this package in the file LICENSE, and is |
4075+ | available at through the world-wide-web at |
4076+ | http://www.php.net/license/2_02.txt. |
4077+ | If you did not receive a copy of the PHP license and are unable to |
4078+ | obtain it through the world-wide-web, please send a note to |
4079+ | license@php.net so we can mail you a copy immediately. |
4080+ +----------------------------------------------------------------------+
4081+ | Author: Stefan Esser <sesser@hardened-php.net> |
4082+ +----------------------------------------------------------------------+
4083+ */
4084+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
4085+
4086+#include "php.h"
4087+
4088+#include <stdio.h>
4089+#include <stdlib.h>
4090+
4091+#if HAVE_UNISTD_H
4092+#include <unistd.h>
4093+#endif
4094+#include "SAPI.h"
4095+#include "php_globals.h"
4096+
4097+#if HARDENING_PATCH
4098+
4099+#ifdef HAVE_SYS_SOCKET_H
4100+#include <sys/socket.h>
4101+#endif
4102+
4103+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
4104+#undef AF_UNIX
4105+#endif
4106+
4107+#if defined(AF_UNIX)
4108+#include <sys/un.h>
4109+#endif
4110+
4111+#define SYSLOG_PATH "/dev/log"
4112+
4113+#include "snprintf.h"
4114+
4115+#include "hardening_patch.h"
4116+
4117+#ifdef ZTS
4118+#include "hardened_globals.h"
4119+int hardened_globals_id;
4120+#else
4121+struct _hardened_globals hardened_globals;
4122+#endif
4123+
4124+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
4125+{
4126+ memset(hardened_globals, 0, sizeof(*hardened_globals));
4127+}
4128+
4129+
4130+PHPAPI void hardened_startup()
4131+{
4132+#ifdef ZTS
4133+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
4134+#else
4135+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
4136+#endif
4137+}
4138+
4139+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
4140+{
4141+ HG(canary_1) = php_canary();
4142+ HG(canary_2) = php_canary();
4143+}
4144+
4145+char *loglevel2string(int loglevel)
4146+{
4147+ switch (loglevel) {
4148+ case S_FILES:
4149+ return "FILES";
4150+ case S_INCLUDE:
4151+ return "INCLUDE";
4152+ case S_MEMORY:
4153+ return "MEMORY";
4154+ case S_MISC:
4155+ return "MISC";
4156+ case S_SQL:
4157+ return "SQL";
4158+ case S_EXECUTOR:
4159+ return "EXECUTOR";
4160+ case S_VARS:
4161+ return "VARS";
4162+ default:
4163+ return "UNKNOWN";
4164+ }
4165+}
4166+
4167+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
4168+{
4169+#if defined(AF_UNIX)
4170+ int s, r, i=0;
4171+ struct sockaddr_un saun;
4172+ char buf[4096+64];
4173+ char error[4096+100];
4174+ char *ip_address;
4175+ char *fname;
4176+ int lineno;
4177+ va_list ap;
4178+ TSRMLS_FETCH();
4179+
4180+ if (EG(hphp_log_use_x_forwarded_for)) {
4181+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
4182+ if (ip_address == NULL) {
4183+ ip_address = "X-FORWARDED-FOR not set";
4184+ }
4185+ } else {
4186+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
4187+ if (ip_address == NULL) {
4188+ ip_address = "REMOTE_ADDR not set";
4189+ }
4190+ }
4191+
4192+
4193+ va_start(ap, fmt);
4194+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
4195+ va_end(ap);
4196+ while (error[i]) {
4197+ if (error[i] < 32) error[i] = '.';
4198+ i++;
4199+ }
4200+
4201+ if (zend_is_executing(TSRMLS_C)) {
4202+ lineno = zend_get_executed_lineno(TSRMLS_C);
4203+ fname = zend_get_executed_filename(TSRMLS_C);
4204+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
4205+ } else {
4206+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
4207+ if (fname==NULL) {
4208+ fname = "unknown";
4209+ }
4210+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
4211+ }
4212+
4213+ /* Syslog-Logging disabled? */
4214+ if ((EG(hphp_log_syslog) & loglevel)==0) {
4215+ goto log_sapi;
4216+ }
4217+
4218+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
4219+
4220+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
4221+ if (s == -1) {
4222+ goto log_sapi;
4223+ }
4224+
4225+ memset(&saun, 0, sizeof(saun));
4226+ saun.sun_family = AF_UNIX;
4227+ strcpy(saun.sun_path, SYSLOG_PATH);
4228+ /*saun.sun_len = sizeof(saun);*/
4229+
4230+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4231+ if (r) {
4232+ close(s);
4233+ s = socket(AF_UNIX, SOCK_STREAM, 0);
4234+ if (s == -1) {
4235+ goto log_sapi;
4236+ }
4237+
4238+ memset(&saun, 0, sizeof(saun));
4239+ saun.sun_family = AF_UNIX;
4240+ strcpy(saun.sun_path, SYSLOG_PATH);
4241+ /*saun.sun_len = sizeof(saun);*/
4242+
4243+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
4244+ if (r) {
4245+ close(s);
4246+ goto log_sapi;
4247+ }
4248+ }
4249+ send(s, error, strlen(error), 0);
4250+
4251+ close(s);
4252+
4253+log_sapi:
4254+ /* SAPI Logging activated? */
4255+ if ((EG(hphp_log_sapi) & loglevel)!=0) {
4256+ sapi_module.log_message(buf);
4257+ }
4258+
4259+log_script:
4260+ /* script logging activaed? */
4261+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
4262+ char cmd[8192], *cmdpos, *bufpos;
4263+ FILE *in;
4264+ int space;
4265+
4266+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
4267+ space = sizeof(cmd) - strlen(cmd);
4268+ cmdpos = cmd + strlen(cmd);
4269+ bufpos = buf;
4270+ if (space <= 1) return;
4271+ while (space > 2 && *bufpos) {
4272+ if (*bufpos == '\'') {
4273+ if (space<=5) break;
4274+ *cmdpos++ = '\'';
4275+ *cmdpos++ = '\\';
4276+ *cmdpos++ = '\'';
4277+ *cmdpos++ = '\'';
4278+ bufpos++;
4279+ space-=4;
4280+ } else {
4281+ *cmdpos++ = *bufpos++;
4282+ space--;
4283+ }
4284+ }
4285+ *cmdpos++ = '\'';
4286+ *cmdpos = 0;
4287+
4288+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
4289+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
4290+ return;
4291+ }
4292+ /* read and forget the result */
4293+ while (1) {
4294+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
4295+ if (readbytes<=0) {
4296+ break;
4297+ }
4298+ }
4299+ pclose(in);
4300+ }
4301+
4302+#endif
4303+}
4304+#endif
4305+
4306+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4307+
4308+/* will be replaced later with more compatible method */
4309+PHPAPI unsigned int php_canary()
4310+{
4311+ time_t t;
4312+ unsigned int canary;
4313+ int fd;
4314+
4315+ fd = open("/dev/urandom", 0);
4316+ if (fd != -1) {
4317+ int r = read(fd, &canary, sizeof(canary));
4318+ close(fd);
4319+ if (r == sizeof(canary)) {
4320+ return (canary);
4321+ }
4322+ }
4323+ /* not good but we never want to do this */
4324+ time(&t);
4325+ canary = *(unsigned int *)&t + getpid() << 16;
4326+ return (canary);
4327+}
4328+#endif
4329+
4330+#if HARDENING_PATCH_INC_PROTECT
4331+
4332+PHPAPI int php_is_valid_include(zval *z)
4333+{
4334+ char *filename;
4335+ int len, i;
4336+ TSRMLS_FETCH();
4337+
4338+ /* must be of type string */
4339+ if (z->type != IS_STRING || z->value.str.val == NULL) {
4340+ return (0);
4341+ }
4342+
4343+ /* short cut */
4344+ filename = z->value.str.val;
4345+ len = z->value.str.len;
4346+
4347+ /* 1. must be shorter than MAXPATHLEN */
4348+ if (len > MAXPATHLEN) {
4349+ char *fname = estrndup(filename, len);
4350+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4351+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
4352+ efree(fname);
4353+ return (0);
4354+ }
4355+
4356+ /* 2. must not be cutted */
4357+ if (len != strlen(filename)) {
4358+ char *fname = estrndup(filename, len);
4359+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
4360+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
4361+ efree(fname);
4362+ return (0);
4363+ }
4364+
4365+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
4366+ if (strstr(filename, "://")) {
4367+ char *fname = estrndup(filename, len);
4368+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
4369+
4370+ /* no black or whitelist then disallow all */
4371+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
4372+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
4373+ efree(fname);
4374+ return (0);
4375+ }
4376+
4377+ /* whitelist is stronger than blacklist */
4378+ if (HG(include_whitelist)) {
4379+ char *s, *t, *h, *index;
4380+ uint indexlen;
4381+ ulong numindex;
4382+
4383+ s = filename;
4384+
4385+ do {
4386+ zend_bool isOk = 0;
4387+ int tlen;
4388+
4389+ t = h = strstr(s, "://");
4390+ if (h == NULL) break;
4391+
4392+
4393+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
4394+ t--;
4395+ }
4396+
4397+ tlen = strlen(t);
4398+
4399+ zend_hash_internal_pointer_reset(HG(include_whitelist));
4400+ do {
4401+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
4402+
4403+ if (r==HASH_KEY_NON_EXISTANT) {
4404+ break;
4405+ }
4406+ if (r==HASH_KEY_IS_STRING) {
4407+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4408+ if (strncmp(t, index, indexlen-1)==0) {
4409+ isOk = 1;
4410+ break;
4411+ }
4412+ }
4413+ }
4414+
4415+ zend_hash_move_forward(HG(include_whitelist));
4416+ } while (1);
4417+
4418+ /* not found in whitelist */
4419+ if (!isOk) {
4420+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4421+ efree(fname);
4422+ return 0;
4423+ }
4424+
4425+ s = h + 3;
4426+ } while (1);
4427+ } else {
4428+ /* okay then handle the blacklist */
4429+ char *s, *t, *h, *index;
4430+ uint indexlen;
4431+ ulong numindex;
4432+
4433+ s = filename;
4434+
4435+ do {
4436+ int tlen;
4437+
4438+ t = h = strstr(s, "://");
4439+ if (h == NULL) break;
4440+
4441+
4442+ while (t > s) {
4443+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4444+ }
4445+
4446+ tlen = strlen(t);
4447+
4448+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4449+ do {
4450+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4451+
4452+ if (r==HASH_KEY_NON_EXISTANT) {
4453+ break;
4454+ }
4455+ if (r==HASH_KEY_IS_STRING) {
4456+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4457+ if (strncmp(t, index, indexlen-1)==0) {
4458+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4459+ efree(fname);
4460+ return 0;
4461+ }
4462+ }
4463+ }
4464+
4465+ zend_hash_move_forward(HG(include_blacklist));
4466+ } while (1);
4467+
4468+ s = h + 3;
4469+ } while (1);
4470+ }
4471+
4472+ efree(fname);
4473+ }
4474+
4475+ /* 4. must not be an uploaded file */
4476+ if (SG(rfc1867_uploaded_files)) {
4477+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4478+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4479+ return (0);
4480+ }
4481+ }
4482+
4483+ /* passed all tests */
4484+ return (1);
4485+}
4486+
4487+#endif
4488+
4489+/*
4490+ * Local variables:
4491+ * tab-width: 4
4492+ * c-basic-offset: 4
4493+ * End:
4494+ * vim600: sw=4 ts=4 fdm=marker
4495+ * vim<600: sw=4 ts=4
4496+ */
4497diff -Nura php-5.1.2/main/hardening_patch.h hardening-patch-5.1.2-0.4.8/main/hardening_patch.h
4498--- php-5.1.2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4499+++ hardening-patch-5.1.2-0.4.8/main/hardening_patch.h 2006-01-12 19:50:03.198840464 +0100
4500@@ -0,0 +1,46 @@
4501+/*
4502+ +----------------------------------------------------------------------+
4503+ | Hardening Patch for PHP |
4504+ +----------------------------------------------------------------------+
4505+ | Copyright (c) 2004-2005 Stefan Esser |
4506+ +----------------------------------------------------------------------+
4507+ | This source file is subject to version 2.02 of the PHP license, |
4508+ | that is bundled with this package in the file LICENSE, and is |
4509+ | available at through the world-wide-web at |
4510+ | http://www.php.net/license/2_02.txt. |
4511+ | If you did not receive a copy of the PHP license and are unable to |
4512+ | obtain it through the world-wide-web, please send a note to |
4513+ | license@php.net so we can mail you a copy immediately. |
4514+ +----------------------------------------------------------------------+
4515+ | Author: Stefan Esser <sesser@hardened-php.net> |
4516+ +----------------------------------------------------------------------+
4517+ */
4518+
4519+#ifndef HARDENING_PATCH_H
4520+#define HARDENING_PATCH_H
4521+
4522+#include "zend.h"
4523+
4524+#if HARDENING_PATCH
4525+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4526+PHPAPI void hardened_startup();
4527+#define HARDENING_PATCH_VERSION "0.4.8"
4528+
4529+#endif
4530+
4531+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4532+PHPAPI unsigned int php_canary();
4533+#endif
4534+
4535+#if HARDENING_PATCH_INC_PROTECT
4536+PHPAPI int php_is_valid_include(zval *z);
4537+#endif
4538+
4539+#endif /* HARDENING_PATCH_H */
4540+
4541+/*
4542+ * Local variables:
4543+ * tab-width: 4
4544+ * c-basic-offset: 4
4545+ * End:
4546+ */
4547diff -Nura php-5.1.2/main/hardening_patch.m4 hardening-patch-5.1.2-0.4.8/main/hardening_patch.m4
4548--- php-5.1.2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4549+++ hardening-patch-5.1.2-0.4.8/main/hardening_patch.m4 2006-01-12 19:50:03.198840464 +0100
4550@@ -0,0 +1,95 @@
4551+dnl
4552+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4553+dnl
4554+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4555+dnl
4556+
4557+AC_ARG_ENABLE(hardening-patch-mm-protect,
4558+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4559+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4560+],[
4561+ DO_HARDENING_PATCH_MM_PROTECT=yes
4562+])
4563+
4564+AC_ARG_ENABLE(hardening-patch-ll-protect,
4565+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4566+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4567+],[
4568+ DO_HARDENING_PATCH_LL_PROTECT=yes
4569+])
4570+
4571+AC_ARG_ENABLE(hardening-patch-inc-protect,
4572+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4573+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4574+],[
4575+ DO_HARDENING_PATCH_INC_PROTECT=yes
4576+])
4577+
4578+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4579+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4580+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4581+],[
4582+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4583+])
4584+
4585+AC_ARG_ENABLE(hardening-patch-hash-protect,
4586+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4587+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4588+],[
4589+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4590+])
4591+
4592+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4593+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4594+
4595+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4596+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4597+
4598+AC_MSG_CHECKING(whether to protect include/require statements)
4599+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4600+
4601+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4602+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4603+
4604+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4605+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4606+
4607+
4608+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4609+
4610+
4611+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4612+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4613+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4614+else
4615+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4616+fi
4617+
4618+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4619+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4620+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4621+else
4622+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4623+fi
4624+
4625+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4626+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4627+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4628+else
4629+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4630+fi
4631+
4632+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4633+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4634+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4635+else
4636+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4637+fi
4638+
4639+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4640+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4641+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4642+else
4643+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4644+fi
4645+
4646diff -Nura php-5.1.2/main/main.c hardening-patch-5.1.2-0.4.8/main/main.c
4647--- php-5.1.2/main/main.c 2006-01-01 13:50:17.000000000 +0100
4648+++ hardening-patch-5.1.2-0.4.8/main/main.c 2006-01-12 19:50:03.200840160 +0100
4649@@ -85,6 +85,10 @@
4650
4651 #include "SAPI.h"
4652 #include "rfc1867.h"
4653+#if HARDENING_PATCH
4654+#include "hardened_globals.h"
4655+#endif
4656+
4657 /* }}} */
4658
4659 #ifndef ZTS
4660@@ -109,10 +113,33 @@
4661 */
4662 static PHP_INI_MH(OnChangeMemoryLimit)
4663 {
4664+#if HARDENING_PATCH
4665+ long orig_memory_limit;
4666+
4667+ if (entry->modified) {
4668+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4669+ } else {
4670+ orig_memory_limit = 1<<30;
4671+ }
4672+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4673+ orig_memory_limit = 1<<30;
4674+ }
4675+#endif
4676 if (new_value) {
4677 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4678+#if HARDENING_PATCH
4679+ if (PG(memory_limit) > orig_memory_limit) {
4680+ PG(memory_limit) = orig_memory_limit;
4681+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4682+ return FAILURE;
4683+ }
4684+#endif
4685 } else {
4686+#if HARDENING_PATCH
4687+ PG(memory_limit) = orig_memory_limit;
4688+#else
4689 PG(memory_limit) = 1<<30; /* effectively, no limit */
4690+#endif
4691 }
4692 return zend_set_memory_limit(PG(memory_limit));
4693 }
4694@@ -1219,6 +1246,9 @@
4695
4696 zend_try {
4697 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4698+#if HARDENING_PATCH
4699+ hardened_clear_mm_canaries(TSRMLS_C);
4700+#endif
4701 } zend_end_try();
4702
4703 zend_try {
4704@@ -1390,6 +1420,10 @@
4705 tsrm_ls = ts_resource(0);
4706 #endif
4707
4708+#if HARDENING_PATCH
4709+ hardened_startup();
4710+#endif
4711+
4712 module_shutdown = 0;
4713 module_startup = 1;
4714 sapi_initialize_empty_request(TSRMLS_C);
4715@@ -1403,6 +1437,12 @@
4716
4717 php_output_startup();
4718
4719+#if HARDENING_PATCH_INC_PROTECT
4720+ zuf.is_valid_include = php_is_valid_include;
4721+#endif
4722+#if HARDENING_PATCH
4723+ zuf.security_log_function = php_security_log;
4724+#endif
4725 zuf.error_function = php_error_cb;
4726 zuf.printf_function = php_printf;
4727 zuf.write_function = php_body_write_wrapper;
4728@@ -1514,6 +1554,10 @@
4729 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
4730 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);
4731 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4732+#if HARDENING_PATCH
4733+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4734+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4735+#endif
4736 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4737 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4738 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4739diff -Nura php-5.1.2/main/php_config.h.in hardening-patch-5.1.2-0.4.8/main/php_config.h.in
4740--- php-5.1.2/main/php_config.h.in 2006-01-11 15:25:52.000000000 +0100
4741+++ hardening-patch-5.1.2-0.4.8/main/php_config.h.in 2006-01-12 19:50:03.202839856 +0100
4742@@ -782,6 +782,39 @@
4743 /* Enabling BIND8 compatibility for Panther */
4744 #undef BIND_8_COMPAT
4745
4746+/* Hardening-Patch for PHP */
4747+#undef HARDENING_PATCH
4748+
4749+/* Memory Manager Protection */
4750+#undef HARDENING_PATCH_MM_PROTECT
4751+
4752+/* Memory Manager Protection */
4753+#undef HARDENING_PATCH_MM_PROTECT
4754+
4755+/* Linked List Protection */
4756+#undef HARDENING_PATCH_LL_PROTECT
4757+
4758+/* Linked List Protection */
4759+#undef HARDENING_PATCH_LL_PROTECT
4760+
4761+/* Include/Require Protection */
4762+#undef HARDENING_PATCH_INC_PROTECT
4763+
4764+/* Include/Require Protection */
4765+#undef HARDENING_PATCH_INC_PROTECT
4766+
4767+/* Fmt String Protection */
4768+#undef HARDENING_PATCH_FMT_PROTECT
4769+
4770+/* Fmt String Protection */
4771+#undef HARDENING_PATCH_FMT_PROTECT
4772+
4773+/* HashTable DTOR Protection */
4774+#undef HARDENING_PATCH_HASH_PROTECT
4775+
4776+/* HashTable DTOR Protection */
4777+#undef HARDENING_PATCH_HASH_PROTECT
4778+
4779 /* Whether you have AOLserver */
4780 #undef HAVE_AOLSERVER
4781
4782@@ -1125,6 +1158,12 @@
4783 /* Define if you have the getaddrinfo function */
4784 #undef HAVE_GETADDRINFO
4785
4786+/* Whether realpath is broken */
4787+#undef PHP_BROKEN_REALPATH
4788+
4789+/* Whether realpath is broken */
4790+#undef PHP_BROKEN_REALPATH
4791+
4792 /* Whether system headers declare timezone */
4793 #undef HAVE_DECLARED_TIMEZONE
4794
4795diff -Nura php-5.1.2/main/php.h hardening-patch-5.1.2-0.4.8/main/php.h
4796--- php-5.1.2/main/php.h 2006-01-01 13:50:17.000000000 +0100
4797+++ hardening-patch-5.1.2-0.4.8/main/php.h 2006-01-12 19:50:03.202839856 +0100
4798@@ -35,11 +35,19 @@
4799 #include "zend_qsort.h"
4800 #include "php_compat.h"
4801
4802+
4803 #include "zend_API.h"
4804
4805 #undef sprintf
4806 #define sprintf php_sprintf
4807
4808+#if HARDENING_PATCH
4809+#if HAVE_REALPATH
4810+#undef realpath
4811+#define realpath php_realpath
4812+#endif
4813+#endif
4814+
4815 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4816 #undef PHP_DEBUG
4817 #define PHP_DEBUG ZEND_DEBUG
4818@@ -338,6 +346,7 @@
4819 #define PHP_FUNCTION ZEND_FUNCTION
4820 #define PHP_METHOD ZEND_METHOD
4821
4822+#define PHP_STATIC_FE ZEND_STATIC_FE
4823 #define PHP_NAMED_FE ZEND_NAMED_FE
4824 #define PHP_FE ZEND_FE
4825 #define PHP_FALIAS ZEND_FALIAS
4826@@ -445,6 +454,10 @@
4827 #endif
4828 #endif /* !XtOffsetOf */
4829
4830+#if HARDENING_PATCH
4831+#include "hardening_patch.h"
4832+#endif
4833+
4834 #endif
4835
4836 /*
4837diff -Nura php-5.1.2/main/php_variables.c hardening-patch-5.1.2-0.4.8/main/php_variables.c
4838--- php-5.1.2/main/php_variables.c 2006-01-01 13:50:17.000000000 +0100
4839+++ hardening-patch-5.1.2-0.4.8/main/php_variables.c 2006-01-12 19:50:03.203839704 +0100
4840@@ -73,6 +73,10 @@
4841 symtable1 = Z_ARRVAL_P(track_vars_array);
4842 } else if (PG(register_globals)) {
4843 symtable1 = EG(active_symbol_table);
4844+ /* GLOBALS hijack attempt, reject parameter */
4845+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) {
4846+ symtable1 = NULL;
4847+ }
4848 }
4849 if (!symtable1) {
4850 /* Nothing to do */
4851@@ -521,7 +525,7 @@
4852 */
4853 static inline void php_register_server_variables(TSRMLS_D)
4854 {
4855- zval *array_ptr = NULL;
4856+ zval *array_ptr = NULL, *vptr;
4857 /* turn off magic_quotes while importing server variables */
4858 int magic_quotes_gpc = PG(magic_quotes_gpc);
4859
4860diff -Nura php-5.1.2/main/rfc1867.c hardening-patch-5.1.2-0.4.8/main/rfc1867.c
4861--- php-5.1.2/main/rfc1867.c 2006-01-01 13:50:17.000000000 +0100
4862+++ hardening-patch-5.1.2-0.4.8/main/rfc1867.c 2006-01-12 19:50:03.204839552 +0100
4863@@ -132,6 +132,7 @@
4864 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4865 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4866 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4867+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
4868
4869 void php_rfc1867_register_constants(TSRMLS_D)
4870 {
4871@@ -142,6 +143,7 @@
4872 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4873 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4874 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4875+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4876 }
4877
4878 static void normalize_protected_variable(char *varname TSRMLS_DC)
4879@@ -854,6 +856,7 @@
4880 char buff[FILLUNIT];
4881 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4882 int blen=0, wlen=0;
4883+ unsigned long offset;
4884
4885 zend_llist_clean(&header);
4886
4887@@ -970,7 +973,11 @@
4888 tmp++;
4889 }
4890 }
4891-
4892+
4893+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4894+ skip_upload = 1;
4895+ }
4896+
4897 total_bytes = cancel_upload = 0;
4898
4899 if (!skip_upload) {
4900@@ -994,6 +1001,11 @@
4901 cancel_upload = UPLOAD_ERROR_D;
4902 }
4903
4904+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4905+ cancel_upload = UPLOAD_ERROR_X;
4906+ }
4907+
4908+ offset = 0;
4909 end = 0;
4910 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4911 {
4912@@ -1008,6 +1020,10 @@
4913 #endif
4914 cancel_upload = UPLOAD_ERROR_B;
4915 } else if (blen > 0) {
4916+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4917+ cancel_upload = UPLOAD_ERROR_X;
4918+ }
4919+
4920 wlen = write(fd, buff, blen);
4921
4922 if (wlen < blen) {
4923@@ -1036,6 +1052,10 @@
4924 }
4925 #endif
4926
4927+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4928+ cancel_upload = UPLOAD_ERROR_X;
4929+ }
4930+
4931 if (cancel_upload) {
4932 if (temp_filename) {
4933 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4934diff -Nura php-5.1.2/main/SAPI.c hardening-patch-5.1.2-0.4.8/main/SAPI.c
4935--- php-5.1.2/main/SAPI.c 2006-01-01 13:50:17.000000000 +0100
4936+++ hardening-patch-5.1.2-0.4.8/main/SAPI.c 2006-01-12 19:50:03.205839400 +0100
4937@@ -870,6 +870,36 @@
4938 post_entry->content_type_len+1);
4939 }
4940
4941+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))
4942+{
4943+ sapi_module.input_filter = input_filter;
4944+ return SUCCESS;
4945+}
4946+
4947+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
4948+{
4949+ sapi_module.upload_varname_filter = upload_varname_filter;
4950+ return SUCCESS;
4951+}
4952+
4953+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4954+{
4955+ sapi_module.pre_upload_filter = pre_upload_filter;
4956+ return SUCCESS;
4957+}
4958+
4959+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))
4960+{
4961+ sapi_module.upload_content_filter = upload_content_filter;
4962+ return SUCCESS;
4963+}
4964+
4965+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4966+{
4967+ sapi_module.post_upload_filter = post_upload_filter;
4968+ return SUCCESS;
4969+}
4970+
4971
4972 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
4973 {
4974@@ -884,11 +914,6 @@
4975 return SUCCESS;
4976 }
4977
4978-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))
4979-{
4980- sapi_module.input_filter = input_filter;
4981- return SUCCESS;
4982-}
4983
4984 SAPI_API int sapi_flush(TSRMLS_D)
4985 {
4986diff -Nura php-5.1.2/main/SAPI.h hardening-patch-5.1.2-0.4.8/main/SAPI.h
4987--- php-5.1.2/main/SAPI.h 2006-01-01 13:50:17.000000000 +0100
4988+++ hardening-patch-5.1.2-0.4.8/main/SAPI.h 2006-01-12 19:50:03.206839248 +0100
4989@@ -190,6 +190,10 @@
4990 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4991 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));
4992
4993+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4994+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));
4995+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4996+
4997 SAPI_API int sapi_flush(TSRMLS_D);
4998 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4999 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
5000@@ -254,6 +258,11 @@
5001 int (*get_target_gid)(gid_t * TSRMLS_DC);
5002
5003 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
5004+
5005+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
5006+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
5007+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
5008+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
5009
5010 void (*ini_defaults)(HashTable *configuration_hash);
5011 int phpinfo_as_text;
5012@@ -279,7 +288,11 @@
5013
5014 #define SAPI_DEFAULT_MIMETYPE "text/html"
5015 #define SAPI_DEFAULT_CHARSET ""
5016+#if HARDENING_PATCH
5017+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
5018+#else
5019 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
5020+#endif
5021
5022 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
5023 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
5024@@ -287,6 +300,11 @@
5025 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
5026 #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)
5027
5028+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
5029+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
5030+#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)
5031+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
5032+
5033 BEGIN_EXTERN_C()
5034 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
5035 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
5036diff -Nura php-5.1.2/main/snprintf.c hardening-patch-5.1.2-0.4.8/main/snprintf.c
5037--- php-5.1.2/main/snprintf.c 2006-01-01 13:50:17.000000000 +0100
5038+++ hardening-patch-5.1.2-0.4.8/main/snprintf.c 2006-01-12 20:00:23.577528568 +0100
5039@@ -1014,7 +1014,13 @@
5040
5041
5042 case 'n':
5043+ s = NULL;
5044+ s_len = 0;
5045+#if HARDENING_PATCH_FMT_PROTECT
5046+ php_security_log(S_MISC, "'n' specifier within format string");
5047+#else
5048 *(va_arg(ap, int *)) = cc;
5049+#endif
5050 break;
5051
5052 /*
5053diff -Nura php-5.1.2/main/spprintf.c hardening-patch-5.1.2-0.4.8/main/spprintf.c
5054--- php-5.1.2/main/spprintf.c 2006-01-01 13:50:17.000000000 +0100
5055+++ hardening-patch-5.1.2-0.4.8/main/spprintf.c 2006-01-12 20:00:39.587094744 +0100
5056@@ -630,7 +630,13 @@
5057
5058
5059 case 'n':
5060+ s = NULL;
5061+ s_len = 0;
5062+#if HARDENING_PATCH_FMT_PROTECT
5063+ php_security_log(S_MISC, "'n' specifier within format string");
5064+#else
5065 *(va_arg(ap, int *)) = xbuf->len;
5066+#endif
5067 break;
5068
5069 /*
5070diff -Nura php-5.1.2/pear/Makefile.frag hardening-patch-5.1.2-0.4.8/pear/Makefile.frag
5071--- php-5.1.2/pear/Makefile.frag 2005-12-12 13:39:50.000000000 +0100
5072+++ hardening-patch-5.1.2-0.4.8/pear/Makefile.frag 2006-01-12 19:50:03.208838944 +0100
5073@@ -3,7 +3,7 @@
5074 peardir=$(PEAR_INSTALLDIR)
5075
5076 # Skip all php.ini files altogether
5077-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -ddetect_unicode=0
5078+PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -derror_reporting=E_ALL -ddetect_unicode=0 -dhphp.executor.include.whitelist=phar
5079
5080 install-pear-installer: $(SAPI_CLI_PATH)
5081 @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)"
5082diff -Nura php-5.1.2/php.ini-dist hardening-patch-5.1.2-0.4.8/php.ini-dist
5083--- php-5.1.2/php.ini-dist 2005-12-30 18:15:55.000000000 +0100
5084+++ hardening-patch-5.1.2-0.4.8/php.ini-dist 2006-01-12 19:50:03.209838792 +0100
5085@@ -1178,6 +1178,209 @@
5086 ; instead of original one.
5087 soap.wsdl_cache_ttl=86400
5088
5089+[hardening-patch]
5090+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5091+; Hardening-Patch's logging ;
5092+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5093+
5094+;
5095+; hphp.log.syslog - Configures level for alerts reported through syslog
5096+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5097+; hphp.log.script - Configures level for alerts reported through external script
5098+;
5099+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5100+; Or each number up to get desired Hardening-Patch's reporting level
5101+;
5102+; S_ALL - All alerts
5103+; S_MEMORY - All canary violations and the safe unlink protection use this class
5104+; S_VARS - All variable filters trigger this class
5105+; S_FILES - All violation of uploaded files filter use this class
5106+; S_INCLUDE - The protection against malicious include filenames use this class
5107+; S_SQL - Failed SQL queries in MySQL are logged with this class
5108+; S_EXECUTOR - The execution depth protection uses this logging class
5109+; S_MISC - All other log messages (f.e. format string protection) use this class
5110+;
5111+; Example:
5112+;
5113+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5114+; memory alerts through syslog and SQL+Include alerts fo the script
5115+;
5116+;hphp.log.syslog = S_MEMORY
5117+;hphp.log.sapi = S_ALL & ~S_MEMORY
5118+;hphp.log.script = S_INCLUDE | S_SQL
5119+;
5120+; Syslog logging:
5121+;
5122+; - Facility configuration: one of the following facilities
5123+;
5124+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5125+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5126+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5127+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5128+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5129+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5130+; LOG_PERROR
5131+;
5132+; - Priority configuration: one of the followinf priorities
5133+;
5134+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5135+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5136+;
5137+hphp.log.syslog.priority = LOG_ALERT
5138+hphp.log.syslog.facility = LOG_USER
5139+;
5140+; Script logging:
5141+;
5142+;hphp.log.script.name = /home/hphp/log_script
5143+;
5144+; Alert configuration:
5145+;
5146+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5147+;
5148+;hphp.log.use-x-forwarded-for = On
5149+;
5150+
5151+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5152+; Hardening-Patch's Executor options ;
5153+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5154+
5155+; Execution depth limit
5156+;hphp.executor.max_depth = 8000
5157+
5158+; White-/blacklist for function calls during normal execution
5159+;hphp.executor.func.whitelist = ord,chr
5160+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5161+
5162+; White-/blacklist for function calls during eval() execution
5163+;hphp.executor.eval.whitelist = ord,chr
5164+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5165+
5166+; White-/blacklist for URLs allowes in include filenames
5167+;
5168+; - When both options are not set all URLs are forbidden
5169+;
5170+; - When both options are set whitelist is taken and blacklist ignored
5171+;
5172+; - An entry in the lists is either a URL sheme like: http, https
5173+; or the beginning of an URL like: php://input
5174+;
5175+;hphp.executor.include.whitelist = cookietest
5176+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5177+
5178+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5179+; Hardening-Patch's REQUEST variable filters ;
5180+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5181+
5182+; Limits the number of REQUEST variables
5183+hphp.request.max_vars = 200
5184+
5185+; Limits the length of variable names (without indices)
5186+hphp.request.max_varname_length = 64
5187+
5188+; Limits the length of complete variable names (with indices)
5189+hphp.request.max_totalname_length = 256
5190+
5191+; Limits the length of array indices
5192+hphp.request.max_array_index_length = 64
5193+
5194+; Limits the depth of arrays
5195+hphp.request.max_array_depth = 100
5196+
5197+; Limits the length of variable values
5198+hphp.request.max_value_length = 65000
5199+
5200+; Disallow ASCII-NUL characters in input
5201+hphp.request.disallow_nul = 1
5202+
5203+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5204+; Hardening-Patch's COOKIE variable filters ;
5205+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5206+
5207+; Limits the number of COOKIE variables
5208+hphp.cookie.max_vars = 100
5209+
5210+; Limits the length of variable names (without indices)
5211+hphp.cookie.max_name_length = 64
5212+
5213+; Limits the length of complete variable names (with indices)
5214+hphp.cookie.max_totalname_length = 256
5215+
5216+; Limits the length of array indices
5217+hphp.cookie.max_array_index_length = 64
5218+
5219+; Limits the depth of arrays
5220+hphp.cookie.max_array_depth = 100
5221+
5222+; Limits the length of variable values
5223+hphp.cookie.max_value_length = 10000
5224+
5225+; Disallow ASCII-NUL characters in input
5226+hphp.cookie.disallow_nul = 1
5227+
5228+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5229+; Hardening-Patch's GET variable filters ;
5230+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5231+
5232+; Limits the number of COOKIE variables
5233+hphp.get.max_vars = 100
5234+
5235+; Limits the length of variable names (without indices)
5236+hphp.get.max_name_length = 64
5237+
5238+; Limits the length of complete variable names (with indices)
5239+hphp.get.max_totalname_length = 256
5240+
5241+; Limits the length of array indices
5242+hphp.get.max_array_index_length = 64
5243+
5244+; Limits the depth of arrays
5245+hphp.get.max_array_depth = 50
5246+
5247+; Limits the length of variable values
5248+hphp.get.max_value_length = 512
5249+
5250+; Disallow ASCII-NUL characters in input
5251+hphp.get.disallow_nul = 1
5252+
5253+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5254+; Hardening-Patch's POST variable filters ;
5255+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5256+
5257+; Limits the number of POST variables
5258+hphp.post.max_vars = 200
5259+
5260+; Limits the length of variable names (without indices)
5261+hphp.post.max_name_length = 64
5262+
5263+; Limits the length of complete variable names (with indices)
5264+hphp.post.max_totalname_length = 256
5265+
5266+; Limits the length of array indices
5267+hphp.post.max_array_index_length = 64
5268+
5269+; Limits the depth of arrays
5270+hphp.post.max_array_depth = 100
5271+
5272+; Limits the length of variable values
5273+hphp.post.max_value_length = 65000
5274+
5275+; Disallow ASCII-NUL characters in input
5276+hphp.post.disallow_nul = 1
5277+
5278+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5279+; Hardening-Patch's fileupload variable filters ;
5280+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5281+
5282+; Limits the number of uploadable files
5283+hphp.upload.max_uploads = 25
5284+
5285+; Filter out the upload of ELF executables
5286+hphp.upload.disallow_elf_files = On
5287+
5288+; External filterscript for upload verification
5289+;hphp.upload.verification_script = /home/hphp/verify_script
5290+
5291+
5292 ; Local Variables:
5293 ; tab-width: 4
5294 ; End:
5295diff -Nura php-5.1.2/php.ini-recommended hardening-patch-5.1.2-0.4.8/php.ini-recommended
5296--- php-5.1.2/php.ini-recommended 2005-12-30 18:15:55.000000000 +0100
5297+++ hardening-patch-5.1.2-0.4.8/php.ini-recommended 2006-01-12 19:50:03.211838488 +0100
5298@@ -1236,6 +1236,209 @@
5299 ; instead of original one.
5300 soap.wsdl_cache_ttl=86400
5301
5302+[hardening-patch]
5303+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5304+; Hardening-Patch's logging ;
5305+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5306+
5307+;
5308+; hphp.log.syslog - Configures level for alerts reported through syslog
5309+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
5310+; hphp.log.script - Configures level for alerts reported through external script
5311+;
5312+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
5313+; Or each number up to get desired Hardening-Patch's reporting level
5314+;
5315+; S_ALL - All alerts
5316+; S_MEMORY - All canary violations and the safe unlink protection use this class
5317+; S_VARS - All variable filters trigger this class
5318+; S_FILES - All violation of uploaded files filter use this class
5319+; S_INCLUDE - The protection against malicious include filenames use this class
5320+; S_SQL - Failed SQL queries in MySQL are logged with this class
5321+; S_EXECUTOR - The execution depth protection uses this logging class
5322+; S_MISC - All other log messages (f.e. format string protection) use this class
5323+;
5324+; Example:
5325+;
5326+; - Report all alerts (except memory alerts) to the SAPI errorlog,
5327+; memory alerts through syslog and SQL+Include alerts fo the script
5328+;
5329+;hphp.log.syslog = S_MEMORY
5330+;hphp.log.sapi = S_ALL & ~S_MEMORY
5331+;hphp.log.script = S_INCLUDE | S_SQL
5332+;
5333+; Syslog logging:
5334+;
5335+; - Facility configuration: one of the following facilities
5336+;
5337+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
5338+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
5339+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
5340+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
5341+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
5342+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
5343+; LOG_PERROR
5344+;
5345+; - Priority configuration: one of the followinf priorities
5346+;
5347+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
5348+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
5349+;
5350+hphp.log.syslog.priority = LOG_ALERT
5351+hphp.log.syslog.facility = LOG_USER
5352+;
5353+; Script logging:
5354+;
5355+;hphp.log.script.name = /home/hphp/log_script
5356+;
5357+; Alert configuration:
5358+;
5359+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
5360+;
5361+;hphp.log.use-x-forwarded-for = On
5362+;
5363+
5364+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5365+; Hardening-Patch's Executor options ;
5366+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5367+
5368+; Execution depth limit
5369+;hphp.executor.max_depth = 8000
5370+
5371+; White-/blacklist for function calls during normal execution
5372+;hphp.executor.func.whitelist = ord,chr
5373+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5374+
5375+; White-/blacklist for function calls during eval() execution
5376+;hphp.executor.eval.whitelist = ord,chr
5377+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
5378+
5379+; White-/blacklist for URLs allowes in include filenames
5380+;
5381+; - When both options are not set all URLs are forbidden
5382+;
5383+; - When both options are set whitelist is taken and blacklist ignored
5384+;
5385+; - An entry in the lists is either a URL sheme like: http, https
5386+; or the beginning of an URL like: php://input
5387+;
5388+;hphp.executor.include.whitelist = cookietest
5389+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
5390+
5391+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5392+; Hardening-Patch's REQUEST variable filters ;
5393+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5394+
5395+; Limits the number of REQUEST variables
5396+hphp.request.max_vars = 200
5397+
5398+; Limits the length of variable names (without indices)
5399+hphp.request.max_varname_length = 64
5400+
5401+; Limits the length of complete variable names (with indices)
5402+hphp.request.max_totalname_length = 256
5403+
5404+; Limits the length of array indices
5405+hphp.request.max_array_index_length = 64
5406+
5407+; Limits the depth of arrays
5408+hphp.request.max_array_depth = 100
5409+
5410+; Limits the length of variable values
5411+hphp.request.max_value_length = 65000
5412+
5413+; Disallow ASCII-NUL characters in input
5414+hphp.request.disallow_nul = 1
5415+
5416+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5417+; Hardening-Patch's COOKIE variable filters ;
5418+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5419+
5420+; Limits the number of COOKIE variables
5421+hphp.cookie.max_vars = 100
5422+
5423+; Limits the length of variable names (without indices)
5424+hphp.cookie.max_name_length = 64
5425+
5426+; Limits the length of complete variable names (with indices)
5427+hphp.cookie.max_totalname_length = 256
5428+
5429+; Limits the length of array indices
5430+hphp.cookie.max_array_index_length = 64
5431+
5432+; Limits the depth of arrays
5433+hphp.cookie.max_array_depth = 100
5434+
5435+; Limits the length of variable values
5436+hphp.cookie.max_value_length = 10000
5437+
5438+; Disallow ASCII-NUL characters in input
5439+hphp.cookie.disallow_nul = 1
5440+
5441+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5442+; Hardening-Patch's GET variable filters ;
5443+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5444+
5445+; Limits the number of COOKIE variables
5446+hphp.get.max_vars = 100
5447+
5448+; Limits the length of variable names (without indices)
5449+hphp.get.max_name_length = 64
5450+
5451+; Limits the length of complete variable names (with indices)
5452+hphp.get.max_totalname_length = 256
5453+
5454+; Limits the length of array indices
5455+hphp.get.max_array_index_length = 64
5456+
5457+; Limits the depth of arrays
5458+hphp.get.max_array_depth = 50
5459+
5460+; Limits the length of variable values
5461+hphp.get.max_value_length = 512
5462+
5463+; Disallow ASCII-NUL characters in input
5464+hphp.get.disallow_nul = 1
5465+
5466+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5467+; Hardening-Patch's POST variable filters ;
5468+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5469+
5470+; Limits the number of POST variables
5471+hphp.post.max_vars = 200
5472+
5473+; Limits the length of variable names (without indices)
5474+hphp.post.max_name_length = 64
5475+
5476+; Limits the length of complete variable names (with indices)
5477+hphp.post.max_totalname_length = 256
5478+
5479+; Limits the length of array indices
5480+hphp.post.max_array_index_length = 64
5481+
5482+; Limits the depth of arrays
5483+hphp.post.max_array_depth = 100
5484+
5485+; Limits the length of variable values
5486+hphp.post.max_value_length = 65000
5487+
5488+; Disallow ASCII-NUL characters in input
5489+hphp.post.disallow_nul = 1
5490+
5491+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5492+; Hardening-Patch's fileupload variable filters ;
5493+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5494+
5495+; Limits the number of uploadable files
5496+hphp.upload.max_uploads = 25
5497+
5498+; Filter out the upload of ELF executables
5499+hphp.upload.disallow_elf_files = On
5500+
5501+; External filterscript for upload verification
5502+;hphp.upload.verification_script = /home/hphp/verify_script
5503+
5504+
5505 ; Local Variables:
5506 ; tab-width: 4
5507 ; End:
5508diff -Nura php-5.1.2/run-tests.php hardening-patch-5.1.2-0.4.8/run-tests.php
5509--- php-5.1.2/run-tests.php 2006-01-04 16:17:41.000000000 +0100
5510+++ hardening-patch-5.1.2-0.4.8/run-tests.php 2006-01-12 19:50:03.212838336 +0100
5511@@ -151,6 +151,10 @@
5512 'error_reporting=4095',
5513 'display_errors=1',
5514 'log_errors=0',
5515+ 'hphp.executor.include.whitelist=cookietest',
5516+ 'hphp.log.syslog=0',
5517+ 'hphp.log.sapi=0',
5518+ 'hphp.log.script=0',
5519 'html_errors=0',
5520 'track_errors=1',
5521 'report_memleaks=1',
5522diff -Nura php-5.1.2/sapi/apache/mod_php5.c hardening-patch-5.1.2-0.4.8/sapi/apache/mod_php5.c
5523--- php-5.1.2/sapi/apache/mod_php5.c 2006-01-06 19:06:38.000000000 +0100
5524+++ hardening-patch-5.1.2-0.4.8/sapi/apache/mod_php5.c 2006-01-12 19:50:03.213838184 +0100
5525@@ -464,7 +464,7 @@
5526 sapi_apache_get_fd,
5527 sapi_apache_force_http_10,
5528 sapi_apache_get_target_uid,
5529- sapi_apache_get_target_gid
5530+ sapi_apache_get_target_gid,
5531 };
5532 /* }}} */
5533
5534@@ -918,7 +918,11 @@
5535 {
5536 TSRMLS_FETCH();
5537 if (PG(expose_php)) {
5538+#if HARDENING_PATCH
5539+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5540+#else
5541 ap_add_version_component("PHP/" PHP_VERSION);
5542+#endif
5543 }
5544 }
5545 #endif
5546diff -Nura php-5.1.2/sapi/apache2filter/sapi_apache2.c hardening-patch-5.1.2-0.4.8/sapi/apache2filter/sapi_apache2.c
5547--- php-5.1.2/sapi/apache2filter/sapi_apache2.c 2006-01-01 13:50:18.000000000 +0100
5548+++ hardening-patch-5.1.2-0.4.8/sapi/apache2filter/sapi_apache2.c 2006-01-12 19:50:03.213838184 +0100
5549@@ -571,7 +571,11 @@
5550 {
5551 TSRMLS_FETCH();
5552 if (PG(expose_php)) {
5553+#if HARDENING_PATCH
5554+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5555+#else
5556 ap_add_version_component(p, "PHP/" PHP_VERSION);
5557+#endif
5558 }
5559 }
5560
5561diff -Nura php-5.1.2/sapi/apache2handler/sapi_apache2.c hardening-patch-5.1.2-0.4.8/sapi/apache2handler/sapi_apache2.c
5562--- php-5.1.2/sapi/apache2handler/sapi_apache2.c 2006-01-01 13:50:18.000000000 +0100
5563+++ hardening-patch-5.1.2-0.4.8/sapi/apache2handler/sapi_apache2.c 2006-01-12 19:50:03.214838032 +0100
5564@@ -339,7 +339,11 @@
5565 {
5566 TSRMLS_FETCH();
5567 if (PG(expose_php)) {
5568+#if HARDENING_PATCH
5569+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5570+#else
5571 ap_add_version_component(p, "PHP/" PHP_VERSION);
5572+#endif
5573 }
5574 }
5575
5576diff -Nura php-5.1.2/sapi/cgi/cgi_main.c hardening-patch-5.1.2-0.4.8/sapi/cgi/cgi_main.c
5577--- php-5.1.2/sapi/cgi/cgi_main.c 2006-01-01 13:50:18.000000000 +0100
5578+++ hardening-patch-5.1.2-0.4.8/sapi/cgi/cgi_main.c 2006-01-12 20:03:53.218658272 +0100
5579@@ -1405,10 +1405,18 @@
5580 SG(headers_sent) = 1;
5581 SG(request_info).no_headers = 1;
5582 }
5583+#if HARDENING_PATCH
5584 #if ZEND_DEBUG
5585- 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());
5586+ 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());
5587 #else
5588- 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());
5589+ 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());
5590+#endif
5591+#else
5592+#if ZEND_DEBUG
5593+ 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());
5594+#else
5595+ 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());
5596+#endif
5597 #endif
5598 php_end_ob_buffers(1 TSRMLS_CC);
5599 exit(0);
5600diff -Nura php-5.1.2/sapi/cli/php_cli.c hardening-patch-5.1.2-0.4.8/sapi/cli/php_cli.c
5601--- php-5.1.2/sapi/cli/php_cli.c 2006-01-01 13:50:19.000000000 +0100
5602+++ hardening-patch-5.1.2-0.4.8/sapi/cli/php_cli.c 2006-01-12 20:04:28.061361376 +0100
5603@@ -750,10 +750,18 @@
5604 if (php_request_startup(TSRMLS_C)==FAILURE) {
5605 goto err;
5606 }
5607+#if HARDENING_PATCH
5608 #if ZEND_DEBUG
5609- 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());
5610+ 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());
5611 #else
5612- 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());
5613+ 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());
5614+#endif
5615+#else
5616+#if ZEND_DEBUG
5617+ 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());
5618+#else
5619+ 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());
5620+#endif
5621 #endif
5622 php_end_ob_buffers(1 TSRMLS_CC);
5623 exit_status=0;
5624diff -Nura php-5.1.2/TSRM/TSRM.h hardening-patch-5.1.2-0.4.8/TSRM/TSRM.h
5625--- php-5.1.2/TSRM/TSRM.h 2006-01-05 00:55:42.000000000 +0100
5626+++ hardening-patch-5.1.2-0.4.8/TSRM/TSRM.h 2006-01-12 19:50:03.218837424 +0100
5627@@ -33,6 +33,13 @@
5628 # define TSRM_API
5629 #endif
5630
5631+#if HARDENING_PATCH
5632+# if HAVE_REALPATH
5633+# undef realpath
5634+# define realpath php_realpath
5635+# endif
5636+#endif
5637+
5638 /* Only compile multi-threading functions if we're in ZTS mode */
5639 #ifdef ZTS
5640
5641@@ -88,6 +95,7 @@
5642
5643 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5644
5645+
5646 #ifdef __cplusplus
5647 extern "C" {
5648 #endif
5649diff -Nura php-5.1.2/TSRM/tsrm_virtual_cwd.c hardening-patch-5.1.2-0.4.8/TSRM/tsrm_virtual_cwd.c
5650--- php-5.1.2/TSRM/tsrm_virtual_cwd.c 2006-01-01 13:50:00.000000000 +0100
5651+++ hardening-patch-5.1.2-0.4.8/TSRM/tsrm_virtual_cwd.c 2006-01-12 19:50:03.219837272 +0100
5652@@ -205,6 +205,165 @@
5653 return p;
5654 }
5655
5656+#if HARDENING_PATCH
5657+CWD_API char *php_realpath(const char *path, char *resolved)
5658+{
5659+ struct stat sb;
5660+ char *p, *q, *s;
5661+ size_t left_len, resolved_len;
5662+ unsigned symlinks;
5663+ int serrno, slen;
5664+ int is_dir = 1;
5665+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5666+
5667+ serrno = errno;
5668+ symlinks = 0;
5669+ if (path[0] == '/') {
5670+ resolved[0] = '/';
5671+ resolved[1] = '\0';
5672+ if (path[1] == '\0')
5673+ return (resolved);
5674+ resolved_len = 1;
5675+ left_len = strlcpy(left, path + 1, sizeof(left));
5676+ } else {
5677+ if (getcwd(resolved, PATH_MAX) == NULL) {
5678+ strlcpy(resolved, ".", PATH_MAX);
5679+ return (NULL);
5680+ }
5681+ resolved_len = strlen(resolved);
5682+ left_len = strlcpy(left, path, sizeof(left));
5683+ }
5684+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5685+ errno = ENAMETOOLONG;
5686+ return (NULL);
5687+ }
5688+
5689+ /*
5690+ * Iterate over path components in `left'.
5691+ */
5692+ while (left_len != 0) {
5693+ /*
5694+ * Extract the next path component and adjust `left'
5695+ * and its length.
5696+ */
5697+ p = strchr(left, '/');
5698+ s = p ? p : left + left_len;
5699+ if (s - left >= sizeof(next_token)) {
5700+ errno = ENAMETOOLONG;
5701+ return (NULL);
5702+ }
5703+ memcpy(next_token, left, s - left);
5704+ next_token[s - left] = '\0';
5705+ left_len -= s - left;
5706+ if (p != NULL)
5707+ memmove(left, s + 1, left_len + 1);
5708+ if (resolved[resolved_len - 1] != '/') {
5709+ if (resolved_len + 1 >= PATH_MAX) {
5710+ errno = ENAMETOOLONG;
5711+ return (NULL);
5712+ }
5713+ resolved[resolved_len++] = '/';
5714+ resolved[resolved_len] = '\0';
5715+ }
5716+ if (next_token[0] == '\0')
5717+ continue;
5718+ else if (strcmp(next_token, ".") == 0)
5719+ continue;
5720+ else if (strcmp(next_token, "..") == 0) {
5721+ /*
5722+ * Strip the last path component except when we have
5723+ * single "/"
5724+ */
5725+ if (!is_dir) {
5726+ errno = ENOENT;
5727+ return (NULL);
5728+ }
5729+ if (resolved_len > 1) {
5730+ resolved[resolved_len - 1] = '\0';
5731+ q = strrchr(resolved, '/');
5732+ *q = '\0';
5733+ resolved_len = q - resolved;
5734+ }
5735+ continue;
5736+ }
5737+
5738+ /*
5739+ * Append the next path component and lstat() it. If
5740+ * lstat() fails we still can return successfully if
5741+ * there are no more path components left.
5742+ */
5743+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
5744+ if (resolved_len >= PATH_MAX) {
5745+ errno = ENAMETOOLONG;
5746+ return (NULL);
5747+ }
5748+ if (lstat(resolved, &sb) != 0) {
5749+ if (errno == ENOENT && p == NULL) {
5750+ errno = serrno;
5751+ return (resolved);
5752+ }
5753+ return (NULL);
5754+ }
5755+ if (S_ISLNK(sb.st_mode)) {
5756+ if (symlinks++ > MAXSYMLINKS) {
5757+ errno = ELOOP;
5758+ return (NULL);
5759+ }
5760+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
5761+ if (slen < 0)
5762+ return (NULL);
5763+ symlink[slen] = '\0';
5764+ if (symlink[0] == '/') {
5765+ resolved[1] = 0;
5766+ resolved_len = 1;
5767+ } else if (resolved_len > 1) {
5768+ /* Strip the last path component. */
5769+ resolved[resolved_len - 1] = '\0';
5770+ q = strrchr(resolved, '/');
5771+ *q = '\0';
5772+ resolved_len = q - resolved;
5773+ }
5774+
5775+ /*
5776+ * If there are any path components left, then
5777+ * append them to symlink. The result is placed
5778+ * in `left'.
5779+ */
5780+ if (p != NULL) {
5781+ if (symlink[slen - 1] != '/') {
5782+ if (slen + 1 >= sizeof(symlink)) {
5783+ errno = ENAMETOOLONG;
5784+ return (NULL);
5785+ }
5786+ symlink[slen] = '/';
5787+ symlink[slen + 1] = 0;
5788+ }
5789+ left_len = strlcat(symlink, left, sizeof(left));
5790+ if (left_len >= sizeof(left)) {
5791+ errno = ENAMETOOLONG;
5792+ return (NULL);
5793+ }
5794+ }
5795+ left_len = strlcpy(left, symlink, sizeof(left));
5796+ } else {
5797+ if (S_ISDIR(sb.st_mode)) {
5798+ is_dir = 1;
5799+ } else {
5800+ is_dir = 0;
5801+ }
5802+ }
5803+ }
5804+
5805+ /*
5806+ * Remove trailing slash except when the resolved pathname
5807+ * is a single "/".
5808+ */
5809+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
5810+ resolved[resolved_len - 1] = '\0';
5811+ return (resolved);
5812+}
5813+#endif
5814+
5815 CWD_API void virtual_cwd_startup(void)
5816 {
5817 char cwd[MAXPATHLEN];
5818@@ -395,8 +554,11 @@
5819
5820 if (path_length == 0)
5821 return (0);
5822- if (path_length >= MAXPATHLEN)
5823+ if (path_length >= MAXPATHLEN) {
5824+ state->cwd[0] = 0;
5825+ state->cwd_length = 0;
5826 return (1);
5827+ }
5828
5829 #ifdef REALPATH_CACHE
5830 if (use_realpath && CWDG(realpath_cache_size_limit)) {
5831@@ -406,6 +568,8 @@
5832 } else {
5833 orig_path_len = path_length + state->cwd_length + 1;
5834 if (orig_path_len >= MAXPATHLEN) {
5835+ state->cwd[0] = 0;
5836+ state->cwd_length = 0;
5837 return 1;
5838 }
5839 memcpy(orig_path, state->cwd, state->cwd_length);
5840@@ -423,6 +587,8 @@
5841 if (verify_path && verify_path(state)) {
5842 CWD_STATE_FREE(state);
5843 *state = old_state;
5844+ state->cwd[0] = 0;
5845+ state->cwd_length = 0;
5846 return 1;
5847 } else {
5848 CWD_STATE_FREE(&old_state);
5849@@ -441,8 +607,9 @@
5850 path = resolved_path;
5851 path_length = strlen(path);
5852 } else {
5853- /* disable for now
5854- return 1; */
5855+ state->cwd[0] = 0;
5856+ state->cwd_length = 0;
5857+ return 1;
5858 }
5859 }
5860 } else { /* Concat current directory with relative path and then run realpath() on it */
5861@@ -451,6 +618,8 @@
5862
5863 ptr = tmp = (char *) malloc(state->cwd_length+path_length+sizeof("/"));
5864 if (!tmp) {
5865+ state->cwd[0] = 0;
5866+ state->cwd_length = 0;
5867 return 1;
5868 }
5869 memcpy(ptr, state->cwd, state->cwd_length);
5870@@ -461,6 +630,8 @@
5871 *ptr = '\0';
5872 if (strlen(tmp) >= MAXPATHLEN) {
5873 free(tmp);
5874+ state->cwd[0] = 0;
5875+ state->cwd_length = 0;
5876 return 1;
5877 }
5878 if (use_realpath) {
5879@@ -468,9 +639,10 @@
5880 path = resolved_path;
5881 path_length = strlen(path);
5882 } else {
5883- /* disable for now
5884 free(tmp);
5885- return 1; */
5886+ state->cwd[0] = 0;
5887+ state->cwd_length = 0;
5888+ return 1;
5889 }
5890 }
5891 free(tmp);
5892diff -Nura php-5.1.2/TSRM/tsrm_virtual_cwd.h hardening-patch-5.1.2-0.4.8/TSRM/tsrm_virtual_cwd.h
5893--- php-5.1.2/TSRM/tsrm_virtual_cwd.h 2006-01-01 13:50:00.000000000 +0100
5894+++ hardening-patch-5.1.2-0.4.8/TSRM/tsrm_virtual_cwd.h 2006-01-12 19:50:03.220837120 +0100
5895@@ -127,6 +127,22 @@
5896
5897 typedef int (*verify_path_func)(const cwd_state *);
5898
5899+#ifndef HAVE_STRLCPY
5900+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
5901+#undef strlcpy
5902+#define strlcpy php_strlcpy
5903+#endif
5904+
5905+#ifndef HAVE_STRLCAT
5906+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
5907+#undef strlcat
5908+#define strlcat php_strlcat
5909+#endif
5910+
5911+
5912+#if HARDENING_PATCH
5913+CWD_API char *php_realpath(const char *path, char *resolved);
5914+#endif
5915 CWD_API void virtual_cwd_startup(void);
5916 CWD_API void virtual_cwd_shutdown(void);
5917 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
5918diff -Nura php-5.1.2/Zend/zend_alloc.c hardening-patch-5.1.2-0.4.8/Zend/zend_alloc.c
5919--- php-5.1.2/Zend/zend_alloc.c 2006-01-05 00:53:03.000000000 +0100
5920+++ hardening-patch-5.1.2-0.4.8/Zend/zend_alloc.c 2006-01-12 19:50:03.221836968 +0100
5921@@ -64,6 +64,11 @@
5922 # define END_MAGIC_SIZE 0
5923 #endif
5924
5925+#if HARDENING_PATCH_MM_PROTECT
5926+# define CANARY_SIZE sizeof(unsigned int)
5927+#else
5928+# define CANARY_SIZE 0
5929+#endif
5930
5931 # if MEMORY_LIMIT
5932 # if ZEND_DEBUG
5933@@ -105,9 +110,17 @@
5934 if (p==AG(head)) { \
5935 AG(head) = p->pNext; \
5936 } else { \
5937+ if (p != p->pLast->pNext) { \
5938+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5939+ exit(1); \
5940+ } \
5941 p->pLast->pNext = p->pNext; \
5942 } \
5943 if (p->pNext) { \
5944+ if (p != p->pNext->pLast) { \
5945+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5946+ exit(1); \
5947+ } \
5948 p->pNext->pLast = p->pLast; \
5949 }
5950 #else
5951@@ -146,6 +159,12 @@
5952 DECLARE_CACHE_VARS();
5953 TSRMLS_FETCH();
5954
5955+#if HARDENING_PATCH_MM_PROTECT
5956+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
5957+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
5958+ exit(1);
5959+ }
5960+#endif
5961 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
5962
5963 #if !ZEND_DISABLE_MEMORY_CACHE
5964@@ -164,6 +183,10 @@
5965 AG(cache_stats)[CACHE_INDEX][1]++;
5966 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5967 #endif
5968+#if HARDENING_PATCH_MM_PROTECT
5969+ p->canary = HG(canary_1);
5970+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5971+#endif
5972 p->size = size;
5973 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5974 } else {
5975@@ -179,7 +202,7 @@
5976 AG(allocated_memory_peak) = AG(allocated_memory);
5977 }
5978 #endif
5979- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
5980+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
5981 #if !ZEND_DISABLE_MEMORY_CACHE
5982 }
5983 #endif
5984@@ -210,7 +233,10 @@
5985 # endif
5986 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5987 #endif
5988-
5989+#if HARDENING_PATCH_MM_PROTECT
5990+ p->canary = HG(canary_1);
5991+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5992+#endif
5993 HANDLE_UNBLOCK_INTERRUPTIONS();
5994 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5995 }
5996@@ -238,6 +264,10 @@
5997 }
5998 }
5999
6000+
6001+#if HARDENING_PATCH
6002+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
6003+#endif
6004 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
6005 return 0;
6006 }
6007@@ -270,9 +300,25 @@
6008
6009 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6010 {
6011+#if HARDENING_PATCH_MM_PROTECT
6012+ unsigned int canary_2;
6013+#endif
6014 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
6015 DECLARE_CACHE_VARS();
6016 TSRMLS_FETCH();
6017+
6018+#if HARDENING_PATCH_MM_PROTECT
6019+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
6020+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6021+ if (canary_2 != HG(canary_2)) {
6022+efree_canary_mismatch:
6023+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
6024+ exit(1);
6025+ }
6026+ /* to catch double efree()s */
6027+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
6028+ p->canary = 0;
6029+#endif
6030
6031 #if defined(ZTS) && TSRM_DEBUG
6032 if (p->thread_id != tsrm_thread_id()) {
6033@@ -313,23 +359,35 @@
6034
6035 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6036 {
6037- void *p;
6038- int final_size = size*nmemb;
6039+ char *p;
6040+ size_t _size = nmemb * size;
6041+
6042+ if (nmemb && (_size/nmemb!=size)) {
6043+#if HARDENING_PATCH
6044+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
6045+#endif
6046+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
6047+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
6048+ kill(getpid(), SIGSEGV);
6049+#else
6050+ exit(1);
6051+#endif
6052+ }
6053
6054- HANDLE_BLOCK_INTERRUPTIONS();
6055- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6056- if (!p) {
6057- HANDLE_UNBLOCK_INTERRUPTIONS();
6058- return (void *) p;
6059+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
6060+ if (p) {
6061+ memset(p, 0, _size);
6062 }
6063- memset(p, 0, final_size);
6064- HANDLE_UNBLOCK_INTERRUPTIONS();
6065- return p;
6066+
6067+ return ((void *)p);
6068 }
6069
6070
6071 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
6072 {
6073+#if HARDENING_PATCH_MM_PROTECT
6074+ unsigned int canary_2;
6075+#endif
6076 zend_mem_header *p;
6077 zend_mem_header *orig;
6078 DECLARE_CACHE_VARS();
6079@@ -341,6 +399,16 @@
6080
6081 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
6082
6083+#if HARDENING_PATCH_MM_PROTECT
6084+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
6085+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
6086+ if (canary_2 != HG(canary_2)) {
6087+erealloc_canary_mismatch:
6088+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
6089+ exit(1);
6090+ }
6091+#endif
6092+
6093 #if defined(ZTS) && TSRM_DEBUG
6094 if (p->thread_id != tsrm_thread_id()) {
6095 void *new_p;
6096@@ -364,7 +432,7 @@
6097 }
6098 #endif
6099 REMOVE_POINTER_FROM_LIST(p);
6100- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
6101+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
6102 if (!p) {
6103 if (!allow_failure) {
6104 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
6105@@ -386,6 +454,9 @@
6106 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
6107 #endif
6108
6109+#if HARDENING_PATCH_MM_PROTECT
6110+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
6111+#endif
6112 p->size = size;
6113
6114 HANDLE_UNBLOCK_INTERRUPTIONS();
6115@@ -460,6 +531,10 @@
6116 {
6117 AG(head) = NULL;
6118
6119+#if HARDENING_PATCH_MM_PROTECT
6120+ HG(canary_1) = zend_canary();
6121+ HG(canary_2) = zend_canary();
6122+#endif
6123 #if MEMORY_LIMIT
6124 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
6125 AG(allocated_memory) = 0;
6126diff -Nura php-5.1.2/Zend/zend_alloc.h hardening-patch-5.1.2-0.4.8/Zend/zend_alloc.h
6127--- php-5.1.2/Zend/zend_alloc.h 2006-01-05 00:53:03.000000000 +0100
6128+++ hardening-patch-5.1.2-0.4.8/Zend/zend_alloc.h 2006-01-12 19:50:03.221836968 +0100
6129@@ -35,6 +35,9 @@
6130 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
6131
6132 typedef struct _zend_mem_header {
6133+#if HARDENING_PATCH_MM_PROTECT
6134+ unsigned int canary;
6135+#endif
6136 #if ZEND_DEBUG
6137 long magic;
6138 char *filename;
6139diff -Nura php-5.1.2/Zend/zend_API.h hardening-patch-5.1.2-0.4.8/Zend/zend_API.h
6140--- php-5.1.2/Zend/zend_API.h 2006-01-05 00:53:03.000000000 +0100
6141+++ hardening-patch-5.1.2-0.4.8/Zend/zend_API.h 2006-01-12 19:50:03.222836816 +0100
6142@@ -47,6 +47,7 @@
6143 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
6144
6145 #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 },
6146+#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 },
6147
6148 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
6149 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
6150diff -Nura php-5.1.2/Zend/zend_builtin_functions.c hardening-patch-5.1.2-0.4.8/Zend/zend_builtin_functions.c
6151--- php-5.1.2/Zend/zend_builtin_functions.c 2006-01-05 00:53:04.000000000 +0100
6152+++ hardening-patch-5.1.2-0.4.8/Zend/zend_builtin_functions.c 2006-01-12 19:50:03.223836664 +0100
6153@@ -53,6 +53,9 @@
6154 static ZEND_FUNCTION(crash);
6155 #endif
6156 #endif
6157+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6158+static ZEND_FUNCTION(heap_overflow);
6159+#endif
6160 static ZEND_FUNCTION(get_included_files);
6161 static ZEND_FUNCTION(is_subclass_of);
6162 static ZEND_FUNCTION(is_a);
6163@@ -113,6 +116,9 @@
6164 ZEND_FE(crash, NULL)
6165 #endif
6166 #endif
6167+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6168+ ZEND_FE(heap_overflow, NULL)
6169+#endif
6170 ZEND_FE(get_included_files, NULL)
6171 ZEND_FALIAS(get_required_files, get_included_files, NULL)
6172 ZEND_FE(is_subclass_of, NULL)
6173@@ -1086,6 +1092,19 @@
6174
6175 #endif /* ZEND_DEBUG */
6176
6177+
6178+#if HARDENING_PATCH_MM_PROTECT_DEBUG
6179+ZEND_FUNCTION(heap_overflow)
6180+{
6181+ char *nowhere = emalloc(10);
6182+
6183+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
6184+
6185+ efree(nowhere);
6186+}
6187+#endif
6188+
6189+
6190 /* {{{ proto array get_included_files(void)
6191 Returns an array with the file names that were include_once()'d */
6192 ZEND_FUNCTION(get_included_files)
6193diff -Nura php-5.1.2/Zend/zend.c hardening-patch-5.1.2-0.4.8/Zend/zend.c
6194--- php-5.1.2/Zend/zend.c 2006-01-05 00:53:03.000000000 +0100
6195+++ hardening-patch-5.1.2-0.4.8/Zend/zend.c 2006-01-12 19:50:03.225836360 +0100
6196@@ -55,6 +55,12 @@
6197 ZEND_API void (*zend_unblock_interruptions)(void);
6198 ZEND_API void (*zend_ticks_function)(int ticks);
6199 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
6200+#if HARDENING_PATCH
6201+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6202+#endif
6203+#if HARDENING_PATCH_INC_PROTECT
6204+ZEND_API int (*zend_is_valid_include)(zval *z);
6205+#endif
6206 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
6207 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
6208
6209@@ -74,9 +80,390 @@
6210 return SUCCESS;
6211 }
6212
6213+#if HARDENING_PATCH
6214+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
6215+{
6216+ if (!new_value) {
6217+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
6218+ } else {
6219+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
6220+ }
6221+ return SUCCESS;
6222+}
6223+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
6224+{
6225+ if (!new_value) {
6226+ EG(hphp_log_syslog_facility) = LOG_USER;
6227+ } else {
6228+ EG(hphp_log_syslog_facility) = atoi(new_value);
6229+ }
6230+ return SUCCESS;
6231+}
6232+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
6233+{
6234+ if (!new_value) {
6235+ EG(hphp_log_syslog_priority) = LOG_ALERT;
6236+ } else {
6237+ EG(hphp_log_syslog_priority) = atoi(new_value);
6238+ }
6239+ return SUCCESS;
6240+}
6241+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
6242+{
6243+ if (!new_value) {
6244+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
6245+ } else {
6246+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
6247+ }
6248+ return SUCCESS;
6249+}
6250+static ZEND_INI_MH(OnUpdateHPHP_log_script)
6251+{
6252+ if (!new_value) {
6253+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
6254+ } else {
6255+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
6256+ }
6257+ return SUCCESS;
6258+}
6259+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
6260+{
6261+ if (EG(hphp_log_scriptname)) {
6262+ pefree(EG(hphp_log_scriptname),1);
6263+ }
6264+ EG(hphp_log_scriptname) = NULL;
6265+ if (new_value) {
6266+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
6267+ }
6268+ return SUCCESS;
6269+}
6270+
6271+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
6272+{
6273+ char *s = NULL, *e, *val;
6274+ unsigned long dummy = 1;
6275+
6276+ if (!new_value) {
6277+include_whitelist_destroy:
6278+ if (HG(include_whitelist)) {
6279+ zend_hash_destroy(HG(include_whitelist));
6280+ pefree(HG(include_whitelist),1);
6281+ }
6282+ HG(include_whitelist) = NULL;
6283+ return SUCCESS;
6284+ }
6285+ if (!(*new_value)) {
6286+ goto include_whitelist_destroy;
6287+ }
6288+
6289+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
6290+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
6291+
6292+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6293+ e = val;
6294+
6295+ while (*e) {
6296+ switch (*e) {
6297+ case ' ':
6298+ case ',':
6299+ if (s) {
6300+ *e = '\0';
6301+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6302+ s = NULL;
6303+ }
6304+ break;
6305+ default:
6306+ if (!s) {
6307+ s = e;
6308+ }
6309+ break;
6310+ }
6311+ e++;
6312+ }
6313+ if (s) {
6314+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6315+ }
6316+ efree(val);
6317+
6318+ return SUCCESS;
6319+}
6320+
6321+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
6322+{
6323+ char *s = NULL, *e, *val;
6324+ unsigned long dummy = 1;
6325+
6326+ if (!new_value) {
6327+include_blacklist_destroy:
6328+ if (HG(include_blacklist)) {
6329+ zend_hash_destroy(HG(include_blacklist));
6330+ pefree(HG(include_blacklist),1);
6331+ }
6332+ HG(include_blacklist) = NULL;
6333+ return SUCCESS;
6334+ }
6335+ if (!(*new_value)) {
6336+ goto include_blacklist_destroy;
6337+ }
6338+
6339+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
6340+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
6341+
6342+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6343+ e = val;
6344+
6345+ while (*e) {
6346+ switch (*e) {
6347+ case ' ':
6348+ case ',':
6349+ if (s) {
6350+ *e = '\0';
6351+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6352+ s = NULL;
6353+ }
6354+ break;
6355+ default:
6356+ if (!s) {
6357+ s = e;
6358+ }
6359+ break;
6360+ }
6361+ e++;
6362+ }
6363+ if (s) {
6364+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6365+ }
6366+ efree(val);
6367+
6368+ return SUCCESS;
6369+}
6370+
6371+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
6372+{
6373+ char *s = NULL, *e, *val;
6374+ unsigned long dummy = 1;
6375+
6376+ if (!new_value) {
6377+eval_whitelist_destroy:
6378+ if (HG(eval_whitelist)) {
6379+ zend_hash_destroy(HG(eval_whitelist));
6380+ pefree(HG(eval_whitelist),1);
6381+ }
6382+ HG(eval_whitelist) = NULL;
6383+ return SUCCESS;
6384+ }
6385+ if (!(*new_value)) {
6386+ goto eval_whitelist_destroy;
6387+ }
6388+
6389+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6390+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6391+
6392+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6393+ e = val;
6394+
6395+ while (*e) {
6396+ switch (*e) {
6397+ case ' ':
6398+ case ',':
6399+ if (s) {
6400+ *e = '\0';
6401+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6402+ s = NULL;
6403+ }
6404+ break;
6405+ default:
6406+ if (!s) {
6407+ s = e;
6408+ }
6409+ break;
6410+ }
6411+ e++;
6412+ }
6413+ if (s) {
6414+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6415+ }
6416+ efree(val);
6417+
6418+ return SUCCESS;
6419+}
6420+
6421+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6422+{
6423+ char *s = NULL, *e, *val;
6424+ unsigned long dummy = 1;
6425+
6426+ if (!new_value) {
6427+eval_blacklist_destroy:
6428+ if (HG(eval_blacklist)) {
6429+ zend_hash_destroy(HG(eval_blacklist));
6430+ pefree(HG(eval_blacklist), 1);
6431+ }
6432+ HG(eval_blacklist) = NULL;
6433+ return SUCCESS;
6434+ }
6435+ if (!(*new_value)) {
6436+ goto eval_blacklist_destroy;
6437+ }
6438+
6439+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6440+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6441+
6442+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6443+ e = val;
6444+
6445+ while (*e) {
6446+ switch (*e) {
6447+ case ' ':
6448+ case ',':
6449+ if (s) {
6450+ *e = '\0';
6451+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6452+ s = NULL;
6453+ }
6454+ break;
6455+ default:
6456+ if (!s) {
6457+ s = e;
6458+ }
6459+ break;
6460+ }
6461+ e++;
6462+ }
6463+ if (s) {
6464+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6465+ }
6466+ efree(val);
6467+
6468+
6469+ return SUCCESS;
6470+}
6471+
6472+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6473+{
6474+ char *s = NULL, *e, *val;
6475+ unsigned long dummy = 1;
6476+
6477+ if (!new_value) {
6478+func_whitelist_destroy:
6479+ if (HG(func_whitelist)) {
6480+ zend_hash_destroy(HG(func_whitelist));
6481+ pefree(HG(func_whitelist),1);
6482+ }
6483+ HG(func_whitelist) = NULL;
6484+ return SUCCESS;
6485+ }
6486+ if (!(*new_value)) {
6487+ goto func_whitelist_destroy;
6488+ }
6489+
6490+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6491+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6492+
6493+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6494+ e = val;
6495+
6496+ while (*e) {
6497+ switch (*e) {
6498+ case ' ':
6499+ case ',':
6500+ if (s) {
6501+ *e = '\0';
6502+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6503+ s = NULL;
6504+ }
6505+ break;
6506+ default:
6507+ if (!s) {
6508+ s = e;
6509+ }
6510+ break;
6511+ }
6512+ e++;
6513+ }
6514+ if (s) {
6515+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6516+ }
6517+ efree(val);
6518+
6519+ return SUCCESS;
6520+}
6521+
6522+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6523+{
6524+ char *s = NULL, *e, *val;
6525+ unsigned long dummy = 1;
6526+
6527+ if (!new_value) {
6528+func_blacklist_destroy:
6529+ if (HG(func_blacklist)) {
6530+ zend_hash_destroy(HG(func_blacklist));
6531+ pefree(HG(func_blacklist),1);
6532+ }
6533+ HG(func_blacklist) = NULL;
6534+ return SUCCESS;
6535+ }
6536+ if (!(*new_value)) {
6537+ goto func_blacklist_destroy;
6538+ }
6539+
6540+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6541+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6542+
6543+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6544+ e = val;
6545+
6546+ while (*e) {
6547+ switch (*e) {
6548+ case ' ':
6549+ case ',':
6550+ if (s) {
6551+ *e = '\0';
6552+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6553+ s = NULL;
6554+ }
6555+ break;
6556+ default:
6557+ if (!s) {
6558+ s = e;
6559+ }
6560+ break;
6561+ }
6562+ e++;
6563+ }
6564+ if (s) {
6565+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6566+ }
6567+ efree(val);
6568+
6569+
6570+ return SUCCESS;
6571+}
6572+
6573+#endif
6574
6575 ZEND_INI_BEGIN()
6576 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6577+#if HARDENING_PATCH
6578+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6579+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6580+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6581+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6582+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6583+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6584+ 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)
6585+
6586+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6587+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6588+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6589+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6590+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6591+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6592+
6593+ 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)
6594+ 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)
6595+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6596+#endif
6597 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
6598 #ifdef ZEND_MULTIBYTE
6599 STD_ZEND_INI_BOOLEAN("detect_unicode", "1", ZEND_INI_ALL, OnUpdateBool, detect_unicode, zend_compiler_globals, compiler_globals)
6600@@ -493,9 +880,13 @@
6601 EG(user_error_handler) = NULL;
6602 EG(user_exception_handler) = NULL;
6603 EG(in_execution) = 0;
6604+ EG(in_code_type) = 0;
6605 EG(in_autoload) = NULL;
6606 EG(current_execute_data) = NULL;
6607 EG(current_module) = NULL;
6608+#if HARDENING_PATCH
6609+ EG(hphp_log_scriptname) = NULL;
6610+#endif
6611 }
6612
6613
6614@@ -566,6 +957,14 @@
6615 extern zend_scanner_globals language_scanner_globals;
6616 #endif
6617
6618+ /* Set up Hardening-Patch utility functions first */
6619+#if HARDENING_PATCH
6620+ zend_security_log = utility_functions->security_log_function;
6621+#endif
6622+#if HARDENING_PATCH_INC_PROTECT
6623+ zend_is_valid_include = utility_functions->is_valid_include;
6624+#endif
6625+
6626 #ifdef ZTS
6627 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6628 #else
6629@@ -769,6 +1168,7 @@
6630 }
6631 CG(unclean_shutdown) = 1;
6632 CG(in_compilation) = EG(in_execution) = 0;
6633+ EG(in_code_type) = 0;
6634 EG(current_execute_data) = NULL;
6635 longjmp(EG(bailout), FAILURE);
6636 }
6637diff -Nura php-5.1.2/Zend/zend_canary.c hardening-patch-5.1.2-0.4.8/Zend/zend_canary.c
6638--- php-5.1.2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6639+++ hardening-patch-5.1.2-0.4.8/Zend/zend_canary.c 2006-01-12 19:50:03.225836360 +0100
6640@@ -0,0 +1,58 @@
6641+/*
6642+ +----------------------------------------------------------------------+
6643+ | Hardening-Patch for PHP |
6644+ +----------------------------------------------------------------------+
6645+ | Copyright (c) 2004-2005 Stefan Esser |
6646+ +----------------------------------------------------------------------+
6647+ | This source file is subject to version 2.02 of the PHP license, |
6648+ | that is bundled with this package in the file LICENSE, and is |
6649+ | available at through the world-wide-web at |
6650+ | http://www.php.net/license/2_02.txt. |
6651+ | If you did not receive a copy of the PHP license and are unable to |
6652+ | obtain it through the world-wide-web, please send a note to |
6653+ | license@php.net so we can mail you a copy immediately. |
6654+ +----------------------------------------------------------------------+
6655+ | Author: Stefan Esser <sesser@hardened-php.net> |
6656+ +----------------------------------------------------------------------+
6657+ */
6658+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6659+
6660+#include "zend.h"
6661+
6662+#include <stdio.h>
6663+#include <stdlib.h>
6664+
6665+
6666+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6667+
6668+/* will be replaced later with more compatible method */
6669+ZEND_API unsigned int zend_canary()
6670+{
6671+ time_t t;
6672+ unsigned int canary;
6673+ int fd;
6674+
6675+ fd = open("/dev/urandom", 0);
6676+ if (fd != -1) {
6677+ int r = read(fd, &canary, sizeof(canary));
6678+ close(fd);
6679+ if (r == sizeof(canary)) {
6680+ return (canary);
6681+ }
6682+ }
6683+ /* not good but we never want to do this */
6684+ time(&t);
6685+ canary = *(unsigned int *)&t + getpid() << 16;
6686+ return (canary);
6687+}
6688+#endif
6689+
6690+
6691+/*
6692+ * Local variables:
6693+ * tab-width: 4
6694+ * c-basic-offset: 4
6695+ * End:
6696+ * vim600: sw=4 ts=4 fdm=marker
6697+ * vim<600: sw=4 ts=4
6698+ */
6699diff -Nura php-5.1.2/Zend/zend_compile.c hardening-patch-5.1.2-0.4.8/Zend/zend_compile.c
6700--- php-5.1.2/Zend/zend_compile.c 2006-01-05 00:53:04.000000000 +0100
6701+++ hardening-patch-5.1.2-0.4.8/Zend/zend_compile.c 2006-01-12 19:50:03.227836056 +0100
6702@@ -1092,6 +1092,13 @@
6703 op_array.prototype = NULL;
6704
6705 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
6706+#if HARDENING_PATCH
6707+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6708+ op_array.created_by_eval = 1;
6709+ } else {
6710+ op_array.created_by_eval = 0;
6711+ }
6712+#endif
6713
6714 if (is_method) {
6715 char *short_class_name = CG(active_class_entry)->name;
6716diff -Nura php-5.1.2/Zend/zend_compile.h hardening-patch-5.1.2-0.4.8/Zend/zend_compile.h
6717--- php-5.1.2/Zend/zend_compile.h 2006-01-05 00:53:04.000000000 +0100
6718+++ hardening-patch-5.1.2-0.4.8/Zend/zend_compile.h 2006-01-12 19:50:03.228835904 +0100
6719@@ -214,6 +214,9 @@
6720 zend_uint doc_comment_len;
6721
6722 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6723+#if HARDENING_PATCH
6724+ zend_bool created_by_eval;
6725+#endif
6726 };
6727
6728
6729@@ -292,6 +295,8 @@
6730 zval ***CVs;
6731 zend_bool original_in_execution;
6732 HashTable *symbol_table;
6733+ zend_uint original_in_code_type;
6734+ zend_uint execute_depth;
6735 struct _zend_execute_data *prev_execute_data;
6736 zval *old_error_reporting;
6737 };
6738@@ -613,6 +618,7 @@
6739 #define ZEND_OVERLOADED_FUNCTION 3
6740 #define ZEND_EVAL_CODE 4
6741 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
6742+#define ZEND_SANDBOX_CODE 6
6743
6744 #define ZEND_INTERNAL_CLASS 1
6745 #define ZEND_USER_CLASS 2
6746diff -Nura php-5.1.2/Zend/zend_constants.c hardening-patch-5.1.2-0.4.8/Zend/zend_constants.c
6747--- php-5.1.2/Zend/zend_constants.c 2006-01-05 00:53:04.000000000 +0100
6748+++ hardening-patch-5.1.2-0.4.8/Zend/zend_constants.c 2006-01-12 19:50:03.229835752 +0100
6749@@ -107,6 +107,73 @@
6750 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6751
6752 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6753+#if HARDENING_PATCH
6754+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6755+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6756+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6757+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6758+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6759+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6760+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6761+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6762+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6763+
6764+ /* error levels */
6765+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6766+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6767+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6768+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6769+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6770+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6771+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6772+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6773+ /* facility: type of program logging the message */
6774+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6775+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6776+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6777+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6778+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6779+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6780+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6781+#ifdef LOG_NEWS
6782+ /* No LOG_NEWS on HP-UX */
6783+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6784+#endif
6785+#ifdef LOG_UUCP
6786+ /* No LOG_UUCP on HP-UX */
6787+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6788+#endif
6789+#ifdef LOG_CRON
6790+ /* apparently some systems don't have this one */
6791+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6792+#endif
6793+#ifdef LOG_AUTHPRIV
6794+ /* AIX doesn't have LOG_AUTHPRIV */
6795+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
6796+#endif
6797+#if !defined(PHP_WIN32) && !defined(NETWARE)
6798+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
6799+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
6800+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
6801+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
6802+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
6803+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
6804+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
6805+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
6806+#endif
6807+ /* options */
6808+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
6809+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
6810+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
6811+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
6812+#ifdef LOG_NOWAIT
6813+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
6814+#endif
6815+#ifdef LOG_PERROR
6816+ /* AIX doesn't have LOG_PERROR */
6817+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
6818+#endif
6819+#endif
6820
6821 /* true/false constants */
6822 {
6823diff -Nura php-5.1.2/Zend/zend_errors.h hardening-patch-5.1.2-0.4.8/Zend/zend_errors.h
6824--- php-5.1.2/Zend/zend_errors.h 2006-01-05 00:53:04.000000000 +0100
6825+++ hardening-patch-5.1.2-0.4.8/Zend/zend_errors.h 2006-01-12 19:50:03.229835752 +0100
6826@@ -38,6 +38,18 @@
6827 #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)
6828 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
6829
6830+#if HARDENING_PATCH
6831+#define S_MEMORY (1<<0L)
6832+#define S_VARS (1<<1L)
6833+#define S_FILES (1<<2L)
6834+#define S_INCLUDE (1<<3L)
6835+#define S_SQL (1<<4L)
6836+#define S_EXECUTOR (1<<5L)
6837+#define S_MISC (1<<30L)
6838+#define S_INTERNAL (1<<29L)
6839+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
6840+#endif
6841+
6842 #endif /* ZEND_ERRORS_H */
6843
6844 /*
6845diff -Nura php-5.1.2/Zend/zend_execute_API.c hardening-patch-5.1.2-0.4.8/Zend/zend_execute_API.c
6846--- php-5.1.2/Zend/zend_execute_API.c 2006-01-05 00:53:04.000000000 +0100
6847+++ hardening-patch-5.1.2-0.4.8/Zend/zend_execute_API.c 2006-01-12 19:50:03.231835448 +0100
6848@@ -138,6 +138,7 @@
6849 EG(class_table) = CG(class_table);
6850
6851 EG(in_execution) = 0;
6852+ EG(in_code_type) = 0;
6853 EG(in_autoload) = NULL;
6854 EG(autoload_func) = NULL;
6855
6856@@ -766,6 +767,39 @@
6857 if (zend_hash_find(fci->function_table, function_name_lc, fname_len+1, (void **) &EX(function_state).function)==FAILURE) {
6858 EX(function_state).function = NULL;
6859 }
6860+#if HARDENING_PATCH
6861+ else {
6862+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6863+ if (HG(eval_whitelist) != NULL) {
6864+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6865+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
6866+ efree(function_name_lc);
6867+ zend_bailout();
6868+ }
6869+ } else if (HG(eval_blacklist) != NULL) {
6870+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6871+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
6872+ efree(function_name_lc);
6873+ zend_bailout();
6874+ }
6875+ }
6876+ }
6877+
6878+ if (HG(func_whitelist) != NULL) {
6879+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6880+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
6881+ efree(function_name_lc);
6882+ zend_bailout();
6883+ }
6884+ } else if (HG(func_blacklist) != NULL) {
6885+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6886+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
6887+ efree(function_name_lc);
6888+ zend_bailout();
6889+ }
6890+ }
6891+ }
6892+#endif
6893 efree(function_name_lc);
6894 }
6895
6896@@ -1045,7 +1079,7 @@
6897 return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
6898 }
6899
6900-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6901+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
6902 {
6903 zval pv;
6904 zend_op_array *new_op_array;
6905@@ -1078,6 +1112,7 @@
6906 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
6907 zend_op **original_opline_ptr = EG(opline_ptr);
6908
6909+ new_op_array->type = type;
6910 EG(return_value_ptr_ptr) = &local_retval_ptr;
6911 EG(active_op_array) = new_op_array;
6912 EG(no_extensions)=1;
6913@@ -1112,6 +1147,12 @@
6914 }
6915
6916
6917+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6918+{
6919+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
6920+}
6921+
6922+
6923 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
6924 {
6925 int result;
6926diff -Nura php-5.1.2/Zend/zend_execute.c hardening-patch-5.1.2-0.4.8/Zend/zend_execute.c
6927--- php-5.1.2/Zend/zend_execute.c 2006-01-05 00:53:04.000000000 +0100
6928+++ hardening-patch-5.1.2-0.4.8/Zend/zend_execute.c 2006-01-12 19:50:03.233835144 +0100
6929@@ -1341,6 +1341,37 @@
6930 /* OBJ-TBI - doesn't support new object model! */
6931 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
6932 }
6933+#if HARDENING_PATCH
6934+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6935+ if (HG(eval_whitelist) != NULL) {
6936+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
6937+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
6938+ efree(lcname);
6939+ zend_bailout();
6940+ }
6941+ } else if (HG(eval_blacklist) != NULL) {
6942+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
6943+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
6944+ efree(lcname);
6945+ zend_bailout();
6946+ }
6947+ }
6948+ }
6949+
6950+ if (HG(func_whitelist) != NULL) {
6951+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
6952+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
6953+ efree(lcname);
6954+ zend_bailout();
6955+ }
6956+ } else if (HG(func_blacklist) != NULL) {
6957+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
6958+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
6959+ efree(lcname);
6960+ zend_bailout();
6961+ }
6962+ }
6963+#endif
6964
6965 return 0;
6966 }
6967@@ -1386,6 +1417,7 @@
6968 efree(EX(Ts)); \
6969 } \
6970 EG(in_execution) = EX(original_in_execution); \
6971+ EG(in_code_type) = EX(original_in_code_type); \
6972 EG(current_execute_data) = EX(prev_execute_data); \
6973 ZEND_VM_RETURN()
6974
6975diff -Nura php-5.1.2/Zend/zend_extensions.c hardening-patch-5.1.2-0.4.8/Zend/zend_extensions.c
6976--- php-5.1.2/Zend/zend_extensions.c 2006-01-05 00:53:04.000000000 +0100
6977+++ hardening-patch-5.1.2-0.4.8/Zend/zend_extensions.c 2006-01-12 19:50:03.233835144 +0100
6978@@ -55,23 +55,44 @@
6979 return FAILURE;
6980 }
6981
6982+ /* check if module is compiled against Hardening-Patch */
6983+ if (extension_version_info->zend_extension_api_no < 1000000000) {
6984+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
6985+ "The Hardening-Patch version %d is installed.\n\n",
6986+ new_extension->name,
6987+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
6988+ DL_UNLOAD(handle);
6989+ return FAILURE;
6990+ }
6991+
6992+
6993+ /* check if module is compiled against correct Hardening-Patch version */
6994+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
6995+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
6996+ "The Hardening-Patch version %d is installed.\n\n",
6997+ new_extension->name,
6998+ extension_version_info->zend_extension_api_no,
6999+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
7000+ DL_UNLOAD(handle);
7001+ return FAILURE;
7002+ }
7003
7004 /* allow extension to proclaim compatibility with any Zend version */
7005- 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)) {
7006- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7007+ 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)) {
7008+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
7009 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7010 "The Zend Engine API version %d which is installed, is outdated.\n\n",
7011 new_extension->name,
7012- extension_version_info->zend_extension_api_no,
7013+ extension_version_info->real_zend_extension_api_no,
7014 ZEND_EXTENSION_API_NO);
7015 DL_UNLOAD(handle);
7016 return FAILURE;
7017- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7018+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
7019 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
7020 "The Zend Engine API version %d which is installed, is newer.\n"
7021 "Contact %s at %s for a later version of %s.\n\n",
7022 new_extension->name,
7023- extension_version_info->zend_extension_api_no,
7024+ extension_version_info->real_zend_extension_api_no,
7025 ZEND_EXTENSION_API_NO,
7026 new_extension->author,
7027 new_extension->URL,
7028diff -Nura php-5.1.2/Zend/zend_extensions.h hardening-patch-5.1.2-0.4.8/Zend/zend_extensions.h
7029--- php-5.1.2/Zend/zend_extensions.h 2006-01-05 00:53:04.000000000 +0100
7030+++ hardening-patch-5.1.2-0.4.8/Zend/zend_extensions.h 2006-01-12 19:50:03.234834992 +0100
7031@@ -24,9 +24,11 @@
7032
7033 #include "zend_compile.h"
7034
7035-/* The first number is the engine version and the rest is the date.
7036+/* The first API number is a flag saying that Hardening-Patch is used.
7037+ * The second number is the engine version and the date.
7038 * This way engine 2 API no. is always greater than engine 1 API no..
7039 */
7040+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1022051106
7041 #define ZEND_EXTENSION_API_NO 220051025
7042
7043 typedef struct _zend_extension_version_info {
7044@@ -34,6 +36,7 @@
7045 char *required_zend_version;
7046 unsigned char thread_safe;
7047 unsigned char debug;
7048+ int real_zend_extension_api_no;
7049 } zend_extension_version_info;
7050
7051
7052@@ -101,7 +104,7 @@
7053
7054
7055 #define ZEND_EXTENSION() \
7056- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
7057+ 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 }
7058
7059 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7060 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
7061diff -Nura php-5.1.2/Zend/zend_globals.h hardening-patch-5.1.2-0.4.8/Zend/zend_globals.h
7062--- php-5.1.2/Zend/zend_globals.h 2006-01-05 00:53:04.000000000 +0100
7063+++ hardening-patch-5.1.2-0.4.8/Zend/zend_globals.h 2006-01-12 19:50:03.234834992 +0100
7064@@ -180,6 +180,16 @@
7065
7066 int error_reporting;
7067 int orig_error_reporting;
7068+#if HARDENING_PATCH
7069+ int hphp_log_syslog;
7070+ int hphp_log_syslog_facility;
7071+ int hphp_log_syslog_priority;
7072+ int hphp_log_sapi;
7073+ int hphp_log_script;
7074+ char *hphp_log_scriptname;
7075+ zend_bool hphp_log_use_x_forwarded_for;
7076+ long hphp_executor_max_depth;
7077+#endif
7078 int exit_status;
7079
7080 zend_op_array *active_op_array;
7081@@ -197,6 +207,7 @@
7082 int ticks_count;
7083
7084 zend_bool in_execution;
7085+ zend_uint in_code_type;
7086 HashTable *in_autoload;
7087 zend_function *autoload_func;
7088 zend_bool bailout_set;
7089diff -Nura php-5.1.2/Zend/zend.h hardening-patch-5.1.2-0.4.8/Zend/zend.h
7090--- php-5.1.2/Zend/zend.h 2006-01-05 00:53:03.000000000 +0100
7091+++ hardening-patch-5.1.2-0.4.8/Zend/zend.h 2006-01-12 19:50:03.236834688 +0100
7092@@ -297,6 +297,7 @@
7093 /* Variable information */
7094 zvalue_value value; /* value */
7095 zend_uint refcount;
7096+ zend_ushort flags;
7097 zend_uchar type; /* active type */
7098 zend_uchar is_ref;
7099 };
7100@@ -382,6 +383,12 @@
7101 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7102 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
7103 char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
7104+#if HARDENING_PATCH
7105+ void (*security_log_function)(int loglevel, char *fmt, ...);
7106+#endif
7107+#if HARDENING_PATCH_INC_PROTECT
7108+ int (*is_valid_include)(zval *z);
7109+#endif
7110 } zend_utility_functions;
7111
7112
7113@@ -519,7 +526,16 @@
7114 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
7115 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
7116 extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
7117+#if HARDENING_PATCH
7118+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
7119+#endif
7120+#if HARDENING_PATCH_INC_PROTECT
7121+extern ZEND_API int (*zend_is_valid_include)(zval *z);
7122+#endif
7123
7124+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
7125+ZEND_API unsigned int zend_canary(void);
7126+#endif
7127
7128 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
7129
7130@@ -644,6 +660,11 @@
7131
7132 #include "zend_variables.h"
7133
7134+#if HARDENING_PATCH
7135+#include "hardened_globals.h"
7136+#include "php_syslog.h"
7137+#endif
7138+
7139 #endif /* ZEND_H */
7140
7141 /*
7142diff -Nura php-5.1.2/Zend/zend_hash.c hardening-patch-5.1.2-0.4.8/Zend/zend_hash.c
7143--- php-5.1.2/Zend/zend_hash.c 2006-01-05 00:53:04.000000000 +0100
7144+++ hardening-patch-5.1.2-0.4.8/Zend/zend_hash.c 2006-01-12 19:50:03.237834536 +0100
7145@@ -21,6 +21,18 @@
7146
7147 #include "zend.h"
7148
7149+#if HARDENING_PATCH_HASH_PROTECT
7150+ unsigned int zend_hash_canary = 0x1234567;
7151+ zend_bool zend_hash_canary_inited = 0;
7152+#endif
7153+
7154+#define CHECK_HASH_CANARY(hash) \
7155+ if (zend_hash_canary != (hash)->canary) { \
7156+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
7157+ exit(1); \
7158+ }
7159+
7160+
7161 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
7162 (element)->pNext = (list_head); \
7163 (element)->pLast = NULL; \
7164@@ -138,6 +150,9 @@
7165 {
7166 uint i = 3;
7167 Bucket **tmp;
7168+#if HARDENING_PATCH_HASH_PROTECT
7169+ TSRMLS_FETCH();
7170+#endif
7171
7172 SET_INCONSISTENT(HT_OK);
7173
7174@@ -147,6 +162,13 @@
7175
7176 ht->nTableSize = 1 << i;
7177 ht->nTableMask = ht->nTableSize - 1;
7178+#if HARDENING_PATCH_HASH_PROTECT
7179+ if (zend_hash_canary_inited==0) {
7180+ zend_hash_canary = zend_canary();
7181+ zend_hash_canary_inited = 1;
7182+ }
7183+ ht->canary = zend_hash_canary;
7184+#endif
7185 ht->pDestructor = pDestructor;
7186 ht->arBuckets = NULL;
7187 ht->pListHead = NULL;
7188@@ -226,6 +248,9 @@
7189 }
7190 #endif
7191 if (ht->pDestructor) {
7192+#if HARDENING_PATCH_HASH_PROTECT
7193+ CHECK_HASH_CANARY(ht);
7194+#endif
7195 ht->pDestructor(p->pData);
7196 }
7197 UPDATE_DATA(ht, p, pData, nDataSize);
7198@@ -291,6 +316,9 @@
7199 }
7200 #endif
7201 if (ht->pDestructor) {
7202+#if HARDENING_PATCH_HASH_PROTECT
7203+ CHECK_HASH_CANARY(ht);
7204+#endif
7205 ht->pDestructor(p->pData);
7206 }
7207 UPDATE_DATA(ht, p, pData, nDataSize);
7208@@ -366,6 +394,9 @@
7209 }
7210 #endif
7211 if (ht->pDestructor) {
7212+#if HARDENING_PATCH_HASH_PROTECT
7213+ CHECK_HASH_CANARY(ht);
7214+#endif
7215 ht->pDestructor(p->pData);
7216 }
7217 UPDATE_DATA(ht, p, pData, nDataSize);
7218@@ -414,7 +445,7 @@
7219 IS_CONSISTENT(ht);
7220
7221 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
7222- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7223+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
7224 if (t) {
7225 HANDLE_BLOCK_INTERRUPTIONS();
7226 ht->arBuckets = t;
7227@@ -424,6 +455,7 @@
7228 HANDLE_UNBLOCK_INTERRUPTIONS();
7229 return SUCCESS;
7230 }
7231+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
7232 return FAILURE;
7233 }
7234 return SUCCESS;
7235@@ -487,6 +519,9 @@
7236 ht->pInternalPointer = p->pListNext;
7237 }
7238 if (ht->pDestructor) {
7239+#if HARDENING_PATCH_HASH_PROTECT
7240+ CHECK_HASH_CANARY(ht);
7241+#endif
7242 ht->pDestructor(p->pData);
7243 }
7244 if (!p->pDataPtr) {
7245@@ -516,6 +551,9 @@
7246 q = p;
7247 p = p->pListNext;
7248 if (ht->pDestructor) {
7249+#if HARDENING_PATCH_HASH_PROTECT
7250+ CHECK_HASH_CANARY(ht);
7251+#endif
7252 ht->pDestructor(q->pData);
7253 }
7254 if (!q->pDataPtr && q->pData) {
7255@@ -542,6 +580,9 @@
7256 q = p;
7257 p = p->pListNext;
7258 if (ht->pDestructor) {
7259+#if HARDENING_PATCH_HASH_PROTECT
7260+ CHECK_HASH_CANARY(ht);
7261+#endif
7262 ht->pDestructor(q->pData);
7263 }
7264 if (!q->pDataPtr && q->pData) {
7265@@ -571,6 +612,9 @@
7266 HANDLE_BLOCK_INTERRUPTIONS();
7267
7268 if (ht->pDestructor) {
7269+#if HARDENING_PATCH_HASH_PROTECT
7270+ CHECK_HASH_CANARY(ht);
7271+#endif
7272 ht->pDestructor(p->pData);
7273 }
7274 if (!p->pDataPtr) {
7275diff -Nura php-5.1.2/Zend/zend_hash.h hardening-patch-5.1.2-0.4.8/Zend/zend_hash.h
7276--- php-5.1.2/Zend/zend_hash.h 2006-01-05 00:53:04.000000000 +0100
7277+++ hardening-patch-5.1.2-0.4.8/Zend/zend_hash.h 2006-01-12 19:50:03.238834384 +0100
7278@@ -58,6 +58,9 @@
7279 } Bucket;
7280
7281 typedef struct _hashtable {
7282+#if HARDENING_PATCH_HASH_PROTECT
7283+ unsigned int canary;
7284+#endif
7285 uint nTableSize;
7286 uint nTableMask;
7287 uint nNumOfElements;
7288diff -Nura php-5.1.2/Zend/zend_language_scanner.l hardening-patch-5.1.2-0.4.8/Zend/zend_language_scanner.l
7289--- php-5.1.2/Zend/zend_language_scanner.l 2006-01-05 00:53:04.000000000 +0100
7290+++ hardening-patch-5.1.2-0.4.8/Zend/zend_language_scanner.l 2006-01-12 19:50:03.238834384 +0100
7291@@ -389,6 +389,13 @@
7292 compilation_successful=0;
7293 } else {
7294 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7295+#if HARDENING_PATCH
7296+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7297+ op_array->created_by_eval = 1;
7298+ } else {
7299+ op_array->created_by_eval = 0;
7300+ }
7301+#endif
7302 CG(in_compilation) = 1;
7303 CG(active_op_array) = op_array;
7304 compiler_result = zendparse(TSRMLS_C);
7305diff -Nura php-5.1.2/Zend/zend_language_scanner.c hardening-patch-5.1.2-0.4.8/Zend/zend_language_scanner.c
7306--- php-5.1.2/Zend/zend_language_scanner.c 2006-01-11 15:26:08.000000000 +0100
7307+++ hardening-patch-5.1.2-0.4.8/Zend/zend_language_scanner.c 2006-01-12 19:50:03.242833776 +0100
7308@@ -3075,6 +3075,13 @@
7309 compilation_successful=0;
7310 } else {
7311 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7312+#if HARDENING_PATCH
7313+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7314+ op_array->created_by_eval = 1;
7315+ } else {
7316+ op_array->created_by_eval = 0;
7317+ }
7318+#endif
7319 CG(in_compilation) = 1;
7320 CG(active_op_array) = op_array;
7321 compiler_result = zendparse(TSRMLS_C);
7322diff -Nura php-5.1.2/Zend/zend_llist.c hardening-patch-5.1.2-0.4.8/Zend/zend_llist.c
7323--- php-5.1.2/Zend/zend_llist.c 2006-01-05 00:53:04.000000000 +0100
7324+++ hardening-patch-5.1.2-0.4.8/Zend/zend_llist.c 2006-01-12 19:50:03.243833624 +0100
7325@@ -22,9 +22,49 @@
7326 #include "zend.h"
7327 #include "zend_llist.h"
7328 #include "zend_qsort.h"
7329+#include "zend_globals.h"
7330+
7331+#if HARDENING_PATCH_LL_PROTECT
7332+ unsigned int zend_llist_canary_1 = 0x1234567;
7333+ unsigned int zend_llist_canary_2 = 0x1553425;
7334+ zend_bool zend_llist_canary_inited = 0;
7335+#endif
7336+
7337+#define CHECK_LIST_CANARY(list) \
7338+ if (((list)->persistent && (zend_llist_canary_1 != (list)->canary_h || zend_llist_canary_2 != (list)->canary_t)) \
7339+ ||(!(list)->persistent && (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t))) { \
7340+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7341+ exit(1); \
7342+ }
7343+
7344+#define CHECK_LISTELEMENT_CANARY(elem, list) \
7345+ if (((list)->persistent && zend_llist_canary_1 != (elem)->canary)||(!(list)->persistent && HG(canary_3) != (elem)->canary)) { \
7346+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7347+ exit(1); \
7348+ }
7349+
7350
7351 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7352 {
7353+#if HARDENING_PATCH_LL_PROTECT
7354+ TSRMLS_FETCH();
7355+
7356+ if (persistent) {
7357+ if (!zend_llist_canary_inited) {
7358+ /* do not change order to ensure thread safety */
7359+ zend_llist_canary_1 = zend_canary();
7360+ zend_llist_canary_2 = zend_canary();
7361+ zend_llist_canary_inited = 1;
7362+ }
7363+ } else
7364+ if (!HG(ll_canary_inited)) {
7365+ HG(canary_3) = zend_canary();
7366+ HG(canary_4) = zend_canary();
7367+ HG(ll_canary_inited) = 1;
7368+ }
7369+ l->canary_h = persistent ? zend_llist_canary_1 : HG(canary_3);
7370+ l->canary_t = persistent ? zend_llist_canary_2 : HG(canary_4);
7371+#endif
7372 l->head = NULL;
7373 l->tail = NULL;
7374 l->count = 0;
7375@@ -38,6 +78,11 @@
7376 {
7377 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7378
7379+#if HARDENING_PATCH_LL_PROTECT
7380+ TSRMLS_FETCH();
7381+ CHECK_LIST_CANARY(l)
7382+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7383+#endif
7384 tmp->prev = l->tail;
7385 tmp->next = NULL;
7386 if (l->tail) {
7387@@ -56,6 +101,11 @@
7388 {
7389 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7390
7391+#if HARDENING_PATCH_LL_PROTECT
7392+ TSRMLS_FETCH();
7393+ CHECK_LIST_CANARY(l)
7394+ tmp->canary = l->persistent ? zend_llist_canary_1 : HG(canary_3);
7395+#endif
7396 tmp->next = l->head;
7397 tmp->prev = NULL;
7398 if (l->head) {
7399@@ -93,10 +143,20 @@
7400 zend_llist_element *current=l->head;
7401 zend_llist_element *next;
7402
7403+#if HARDENING_PATCH_LL_PROTECT
7404+ TSRMLS_FETCH();
7405+ CHECK_LIST_CANARY(l)
7406+#endif
7407 while (current) {
7408+#if HARDENING_PATCH_LL_PROTECT
7409+ CHECK_LISTELEMENT_CANARY(current, l)
7410+#endif
7411 next = current->next;
7412 if (compare(current->data, element)) {
7413 DEL_LLIST_ELEMENT(current, l);
7414+#if HARDENING_PATCH_LL_PROTECT
7415+ current->canary = 0;
7416+#endif
7417 break;
7418 }
7419 current = next;
7420@@ -108,7 +168,14 @@
7421 {
7422 zend_llist_element *current=l->head, *next;
7423
7424+#if HARDENING_PATCH_LL_PROTECT
7425+ TSRMLS_FETCH();
7426+ CHECK_LIST_CANARY(l)
7427+#endif
7428 while (current) {
7429+#if HARDENING_PATCH_LL_PROTECT
7430+ CHECK_LISTELEMENT_CANARY(current, l)
7431+#endif
7432 next = current->next;
7433 if (l->dtor) {
7434 l->dtor(current->data);
7435@@ -133,7 +200,14 @@
7436 zend_llist_element *old_tail;
7437 void *data;
7438
7439+#if HARDENING_PATCH_LL_PROTECT
7440+ TSRMLS_FETCH();
7441+ CHECK_LIST_CANARY(l)
7442+#endif
7443 if ((old_tail = l->tail)) {
7444+#if HARDENING_PATCH_LL_PROTECT
7445+ CHECK_LISTELEMENT_CANARY(old_tail, l)
7446+#endif
7447 if (l->tail->prev) {
7448 l->tail->prev->next = NULL;
7449 }
7450@@ -159,9 +233,16 @@
7451 {
7452 zend_llist_element *ptr;
7453
7454+#if HARDENING_PATCH_LL_PROTECT
7455+ TSRMLS_FETCH();
7456+ CHECK_LIST_CANARY(src)
7457+#endif
7458 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7459 ptr = src->head;
7460 while (ptr) {
7461+#if HARDENING_PATCH_LL_PROTECT
7462+ CHECK_LISTELEMENT_CANARY(ptr, src)
7463+#endif
7464 zend_llist_add_element(dst, ptr->data);
7465 ptr = ptr->next;
7466 }
7467@@ -172,11 +253,21 @@
7468 {
7469 zend_llist_element *element, *next;
7470
7471+#if HARDENING_PATCH_LL_PROTECT
7472+ TSRMLS_FETCH();
7473+ CHECK_LIST_CANARY(l)
7474+#endif
7475 element=l->head;
7476 while (element) {
7477+#if HARDENING_PATCH_LL_PROTECT
7478+ CHECK_LISTELEMENT_CANARY(element, l)
7479+#endif
7480 next = element->next;
7481 if (func(element->data)) {
7482 DEL_LLIST_ELEMENT(element, l);
7483+#if HARDENING_PATCH_LL_PROTECT
7484+ element->canary = 0;
7485+#endif
7486 }
7487 element = next;
7488 }
7489@@ -187,7 +278,13 @@
7490 {
7491 zend_llist_element *element;
7492
7493+#if HARDENING_PATCH_LL_PROTECT
7494+ CHECK_LIST_CANARY(l)
7495+#endif
7496 for (element=l->head; element; element=element->next) {
7497+#if HARDENING_PATCH_LL_PROTECT
7498+ CHECK_LISTELEMENT_CANARY(element, l)
7499+#endif
7500 func(element->data TSRMLS_CC);
7501 }
7502 }
7503@@ -199,6 +296,9 @@
7504 zend_llist_element **elements;
7505 zend_llist_element *element, **ptr;
7506
7507+#if HARDENING_PATCH_LL_PROTECT
7508+ CHECK_LIST_CANARY(l)
7509+#endif
7510 if (l->count <= 0) {
7511 return;
7512 }
7513@@ -208,6 +308,9 @@
7514 ptr = &elements[0];
7515
7516 for (element=l->head; element; element=element->next) {
7517+#if HARDENING_PATCH_LL_PROTECT
7518+ CHECK_LISTELEMENT_CANARY(element, l)
7519+#endif
7520 *ptr++ = element;
7521 }
7522
7523@@ -230,7 +333,13 @@
7524 {
7525 zend_llist_element *element;
7526
7527+#if HARDENING_PATCH_LL_PROTECT
7528+ CHECK_LIST_CANARY(l)
7529+#endif
7530 for (element=l->head; element; element=element->next) {
7531+#if HARDENING_PATCH_LL_PROTECT
7532+ CHECK_LISTELEMENT_CANARY(element, l)
7533+#endif
7534 func(element->data, arg TSRMLS_CC);
7535 }
7536 }
7537@@ -241,8 +350,14 @@
7538 zend_llist_element *element;
7539 va_list args;
7540
7541+#if HARDENING_PATCH_LL_PROTECT
7542+ CHECK_LIST_CANARY(l)
7543+#endif
7544 va_start(args, num_args);
7545 for (element=l->head; element; element=element->next) {
7546+#if HARDENING_PATCH_LL_PROTECT
7547+ CHECK_LISTELEMENT_CANARY(element, l)
7548+#endif
7549 func(element->data, num_args, args TSRMLS_CC);
7550 }
7551 va_end(args);
7552@@ -251,6 +366,10 @@
7553
7554 ZEND_API int zend_llist_count(zend_llist *l)
7555 {
7556+#if HARDENING_PATCH_LL_PROTECT
7557+ TSRMLS_FETCH();
7558+ CHECK_LIST_CANARY(l)
7559+#endif
7560 return l->count;
7561 }
7562
7563@@ -259,8 +378,15 @@
7564 {
7565 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7566
7567+#if HARDENING_PATCH_LL_PROTECT
7568+ TSRMLS_FETCH();
7569+ CHECK_LIST_CANARY(l)
7570+#endif
7571 *current = l->head;
7572 if (*current) {
7573+#if HARDENING_PATCH_LL_PROTECT
7574+ CHECK_LISTELEMENT_CANARY(*current, l)
7575+#endif
7576 return (*current)->data;
7577 } else {
7578 return NULL;
7579@@ -272,8 +398,15 @@
7580 {
7581 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7582
7583+#if HARDENING_PATCH_LL_PROTECT
7584+ TSRMLS_FETCH();
7585+ CHECK_LIST_CANARY(l)
7586+#endif
7587 *current = l->tail;
7588 if (*current) {
7589+#if HARDENING_PATCH_LL_PROTECT
7590+ CHECK_LISTELEMENT_CANARY(*current, l)
7591+#endif
7592 return (*current)->data;
7593 } else {
7594 return NULL;
7595@@ -285,9 +418,19 @@
7596 {
7597 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7598
7599+#if HARDENING_PATCH_LL_PROTECT
7600+ TSRMLS_FETCH();
7601+ CHECK_LIST_CANARY(l)
7602+#endif
7603 if (*current) {
7604+#if HARDENING_PATCH_LL_PROTECT
7605+ CHECK_LISTELEMENT_CANARY(*current, l)
7606+#endif
7607 *current = (*current)->next;
7608 if (*current) {
7609+#if HARDENING_PATCH_LL_PROTECT
7610+ CHECK_LISTELEMENT_CANARY(*current, l)
7611+#endif
7612 return (*current)->data;
7613 }
7614 }
7615@@ -299,9 +442,19 @@
7616 {
7617 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7618
7619+#if HARDENING_PATCH_LL_PROTECT
7620+ TSRMLS_FETCH();
7621+ CHECK_LIST_CANARY(l)
7622+#endif
7623 if (*current) {
7624+#if HARDENING_PATCH_LL_PROTECT
7625+ CHECK_LISTELEMENT_CANARY(*current, l)
7626+#endif
7627 *current = (*current)->prev;
7628 if (*current) {
7629+#if HARDENING_PATCH_LL_PROTECT
7630+ CHECK_LISTELEMENT_CANARY(*current, l)
7631+#endif
7632 return (*current)->data;
7633 }
7634 }
7635diff -Nura php-5.1.2/Zend/zend_llist.h hardening-patch-5.1.2-0.4.8/Zend/zend_llist.h
7636--- php-5.1.2/Zend/zend_llist.h 2006-01-05 00:53:04.000000000 +0100
7637+++ hardening-patch-5.1.2-0.4.8/Zend/zend_llist.h 2006-01-12 19:50:03.243833624 +0100
7638@@ -23,6 +23,9 @@
7639 #define ZEND_LLIST_H
7640
7641 typedef struct _zend_llist_element {
7642+#if HARDENING_PATCH_LL_PROTECT
7643+ unsigned int canary, padding;
7644+#endif
7645 struct _zend_llist_element *next;
7646 struct _zend_llist_element *prev;
7647 char data[1]; /* Needs to always be last in the struct */
7648@@ -35,6 +38,9 @@
7649 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7650
7651 typedef struct _zend_llist {
7652+#if HARDENING_PATCH_LL_PROTECT
7653+ unsigned int canary_h; /* head */
7654+#endif
7655 zend_llist_element *head;
7656 zend_llist_element *tail;
7657 size_t count;
7658@@ -42,6 +48,9 @@
7659 llist_dtor_func_t dtor;
7660 unsigned char persistent;
7661 zend_llist_element *traverse_ptr;
7662+#if HARDENING_PATCH_LL_PROTECT
7663+ unsigned int canary_t; /* tail */
7664+#endif
7665 } zend_llist;
7666
7667 typedef zend_llist_element* zend_llist_position;
7668diff -Nura php-5.1.2/Zend/zend_modules.h hardening-patch-5.1.2-0.4.8/Zend/zend_modules.h
7669--- php-5.1.2/Zend/zend_modules.h 2006-01-05 00:53:04.000000000 +0100
7670+++ hardening-patch-5.1.2-0.4.8/Zend/zend_modules.h 2006-01-12 19:50:03.244833472 +0100
7671@@ -38,6 +38,7 @@
7672 extern struct _zend_arg_info fourth_arg_force_ref[5];
7673 extern struct _zend_arg_info all_args_by_ref[1];
7674
7675+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002051106
7676 #define ZEND_MODULE_API_NO 20050922
7677 #ifdef ZTS
7678 #define USING_ZTS 1
7679@@ -45,13 +46,13 @@
7680 #define USING_ZTS 0
7681 #endif
7682
7683-#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7684+#define STANDARD_MODULE_HEADER_EX sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7685 #define STANDARD_MODULE_HEADER \
7686 STANDARD_MODULE_HEADER_EX, NULL, NULL
7687 #define ZE2_STANDARD_MODULE_HEADER \
7688 STANDARD_MODULE_HEADER_EX, ini_entries, NULL
7689
7690-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
7691+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
7692
7693 #define STANDARD_MODULE_PROPERTIES \
7694 NULL, STANDARD_MODULE_PROPERTIES_EX
7695@@ -86,6 +87,7 @@
7696 unsigned char type;
7697 void *handle;
7698 int module_number;
7699+ unsigned int real_zend_api;
7700 };
7701
7702 #define MODULE_DEP_REQUIRED 1
7703diff -Nura php-5.1.2/Zend/zend_opcode.c hardening-patch-5.1.2-0.4.8/Zend/zend_opcode.c
7704--- php-5.1.2/Zend/zend_opcode.c 2006-01-05 00:53:04.000000000 +0100
7705+++ hardening-patch-5.1.2-0.4.8/Zend/zend_opcode.c 2006-01-12 19:50:03.244833472 +0100
7706@@ -98,6 +98,9 @@
7707 op_array->uses_this = 0;
7708
7709 op_array->start_op = NULL;
7710+#if HARDENING_PATCH
7711+ op_array->created_by_eval = 0;
7712+#endif
7713
7714 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
7715 }
7716diff -Nura php-5.1.2/Zend/zend_vm_def.h hardening-patch-5.1.2-0.4.8/Zend/zend_vm_def.h
7717--- php-5.1.2/Zend/zend_vm_def.h 2006-01-05 00:53:04.000000000 +0100
7718+++ hardening-patch-5.1.2-0.4.8/Zend/zend_vm_def.h 2006-01-12 19:50:03.247833016 +0100
7719@@ -1760,6 +1760,37 @@
7720 efree(lcname);
7721 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7722 }
7723+#if HARDENING_PATCH
7724+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7725+ if (HG(eval_whitelist) != NULL) {
7726+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7727+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7728+ efree(lcname);
7729+ zend_bailout();
7730+ }
7731+ } else if (HG(eval_blacklist) != NULL) {
7732+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7733+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7734+ efree(lcname);
7735+ zend_bailout();
7736+ }
7737+ }
7738+ }
7739+
7740+ if (HG(func_whitelist) != NULL) {
7741+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7742+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7743+ efree(lcname);
7744+ zend_bailout();
7745+ }
7746+ } else if (HG(func_blacklist) != NULL) {
7747+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7748+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7749+ efree(lcname);
7750+ zend_bailout();
7751+ }
7752+ }
7753+#endif
7754
7755 efree(lcname);
7756 if (OP2_TYPE != IS_CONST) {
7757@@ -1977,6 +2008,34 @@
7758 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
7759 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
7760 }
7761+#if HARDENING_PATCH
7762+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7763+ if (HG(eval_whitelist) != NULL) {
7764+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7765+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
7766+ zend_bailout();
7767+ }
7768+ } else if (HG(eval_blacklist) != NULL) {
7769+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7770+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
7771+ zend_bailout();
7772+ }
7773+ }
7774+ }
7775+
7776+ if (HG(func_whitelist) != NULL) {
7777+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
7778+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
7779+ zend_bailout();
7780+ }
7781+ } else if (HG(func_blacklist) != NULL) {
7782+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
7783+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
7784+ zend_bailout();
7785+ }
7786+ }
7787+#endif
7788+
7789 EX(object) = NULL;
7790
7791 FREE_OP1();
7792@@ -2692,7 +2751,12 @@
7793 int dummy = 1;
7794 zend_file_handle file_handle;
7795
7796- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
7797+#if HARDENING_PATCH_INC_PROTECT
7798+ if (zend_is_valid_include(inc_filename)
7799+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
7800+#else
7801+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
7802+#endif
7803
7804 if (!file_handle.opened_path) {
7805 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
7806@@ -2717,6 +2781,11 @@
7807 break;
7808 case ZEND_INCLUDE:
7809 case ZEND_REQUIRE:
7810+#if HARDENING_PATCH_INC_PROTECT
7811+ if (!zend_is_valid_include(inc_filename)) {
7812+ break;
7813+ }
7814+#endif
7815 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
7816 break;
7817 case ZEND_EVAL: {
7818diff -Nura php-5.1.2/Zend/zend_vm_execute.h hardening-patch-5.1.2-0.4.8/Zend/zend_vm_execute.h
7819--- php-5.1.2/Zend/zend_vm_execute.h 2006-01-05 00:53:04.000000000 +0100
7820+++ hardening-patch-5.1.2-0.4.8/Zend/zend_vm_execute.h 2006-01-12 19:50:03.262830736 +0100
7821@@ -56,6 +56,16 @@
7822 EX(symbol_table) = EG(active_symbol_table);
7823 EX(prev_execute_data) = EG(current_execute_data);
7824 EG(current_execute_data) = &execute_data;
7825+#if HARDENING_PATCH
7826+ EX(execute_depth) = 0;
7827+
7828+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
7829+ EG(in_code_type) = ZEND_EVAL_CODE;
7830+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
7831+ EG(in_code_type) = ZEND_SANDBOX_CODE;
7832+ op_array->type = ZEND_EVAL_CODE;
7833+ }
7834+#endif
7835
7836 EG(in_execution) = 1;
7837 if (op_array->start_op) {
7838@@ -81,6 +91,18 @@
7839 */
7840 EX(function_state).function_symbol_table = NULL;
7841 #endif
7842+#if HARDENING_PATCH
7843+ if (EX(prev_execute_data) == NULL) {
7844+ EX(execute_depth) = 0;
7845+ } else {
7846+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
7847+ }
7848+
7849+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
7850+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
7851+ zend_bailout();
7852+ }
7853+#endif
7854
7855 while (1) {
7856 #ifdef ZEND_WIN32
7857@@ -707,6 +729,37 @@
7858 efree(lcname);
7859 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7860 }
7861+#if HARDENING_PATCH
7862+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7863+ if (HG(eval_whitelist) != NULL) {
7864+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7865+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7866+ efree(lcname);
7867+ zend_bailout();
7868+ }
7869+ } else if (HG(eval_blacklist) != NULL) {
7870+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7871+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7872+ efree(lcname);
7873+ zend_bailout();
7874+ }
7875+ }
7876+ }
7877+
7878+ if (HG(func_whitelist) != NULL) {
7879+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7880+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7881+ efree(lcname);
7882+ zend_bailout();
7883+ }
7884+ } else if (HG(func_blacklist) != NULL) {
7885+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7886+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7887+ efree(lcname);
7888+ zend_bailout();
7889+ }
7890+ }
7891+#endif
7892
7893 efree(lcname);
7894 if (IS_CONST != IS_CONST) {
7895@@ -899,6 +952,37 @@
7896 efree(lcname);
7897 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7898 }
7899+#if HARDENING_PATCH
7900+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7901+ if (HG(eval_whitelist) != NULL) {
7902+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7903+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7904+ efree(lcname);
7905+ zend_bailout();
7906+ }
7907+ } else if (HG(eval_blacklist) != NULL) {
7908+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7909+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7910+ efree(lcname);
7911+ zend_bailout();
7912+ }
7913+ }
7914+ }
7915+
7916+ if (HG(func_whitelist) != NULL) {
7917+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7918+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7919+ efree(lcname);
7920+ zend_bailout();
7921+ }
7922+ } else if (HG(func_blacklist) != NULL) {
7923+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7924+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7925+ efree(lcname);
7926+ zend_bailout();
7927+ }
7928+ }
7929+#endif
7930
7931 efree(lcname);
7932 if (IS_TMP_VAR != IS_CONST) {
7933@@ -1048,6 +1132,37 @@
7934 efree(lcname);
7935 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7936 }
7937+#if HARDENING_PATCH
7938+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7939+ if (HG(eval_whitelist) != NULL) {
7940+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7941+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7942+ efree(lcname);
7943+ zend_bailout();
7944+ }
7945+ } else if (HG(eval_blacklist) != NULL) {
7946+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7947+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7948+ efree(lcname);
7949+ zend_bailout();
7950+ }
7951+ }
7952+ }
7953+
7954+ if (HG(func_whitelist) != NULL) {
7955+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7956+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7957+ efree(lcname);
7958+ zend_bailout();
7959+ }
7960+ } else if (HG(func_blacklist) != NULL) {
7961+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
7962+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
7963+ efree(lcname);
7964+ zend_bailout();
7965+ }
7966+ }
7967+#endif
7968
7969 efree(lcname);
7970 if (IS_VAR != IS_CONST) {
7971@@ -1277,6 +1392,37 @@
7972 efree(lcname);
7973 zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
7974 }
7975+#if HARDENING_PATCH
7976+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
7977+ if (HG(eval_whitelist) != NULL) {
7978+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
7979+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
7980+ efree(lcname);
7981+ zend_bailout();
7982+ }
7983+ } else if (HG(eval_blacklist) != NULL) {
7984+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
7985+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
7986+ efree(lcname);
7987+ zend_bailout();
7988+ }
7989+ }
7990+ }
7991+
7992+ if (HG(func_whitelist) != NULL) {
7993+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
7994+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
7995+ efree(lcname);
7996+ zend_bailout();
7997+ }
7998+ } else if (HG(func_blacklist) != NULL) {
7999+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
8000+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
8001+ efree(lcname);
8002+ zend_bailout();
8003+ }
8004+ }
8005+#endif
8006
8007 efree(lcname);
8008 if (IS_CV != IS_CONST) {
8009@@ -1582,6 +1728,34 @@
8010 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
8011 zend_error_noreturn(E_ERROR, "Unknown function: %s()", fname->value.str.val);
8012 }
8013+#if HARDENING_PATCH
8014+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
8015+ if (HG(eval_whitelist) != NULL) {
8016+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8017+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
8018+ zend_bailout();
8019+ }
8020+ } else if (HG(eval_blacklist) != NULL) {
8021+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8022+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
8023+ zend_bailout();
8024+ }
8025+ }
8026+ }
8027+
8028+ if (HG(func_whitelist) != NULL) {
8029+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
8030+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
8031+ zend_bailout();
8032+ }
8033+ } else if (HG(func_blacklist) != NULL) {
8034+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
8035+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
8036+ zend_bailout();
8037+ }
8038+ }
8039+#endif
8040+
8041 EX(object) = NULL;
8042
8043 return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
8044@@ -1861,7 +2035,12 @@
8045 int dummy = 1;
8046 zend_file_handle file_handle;
8047
8048- if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8049+#if HARDENING_PATCH_INC_PROTECT
8050+ if (zend_is_valid_include(inc_filename)
8051+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
8052+#else
8053+ if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
8054+#endif
8055
8056 if (!file_handle.opened_path) {
8057 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
8058@@ -1886,6 +2065,11 @@
8059 break;
8060 case ZEND_INCLUDE:
8061 case ZEND_REQUIRE:
8062+#if HARDENING_PATCH_INC_PROTECT
8063+ if (!zend_is_valid_include(inc_filename)) {
8064+ break;
8065+ }
8066+#endif
8067 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
8068 break;
8069 case ZEND_EVAL: {
8070diff -Nura php-5.1.2/Zend/zend_vm_execute.skl hardening-patch-5.1.2-0.4.8/Zend/zend_vm_execute.skl
8071--- php-5.1.2/Zend/zend_vm_execute.skl 2005-12-01 13:50:58.000000000 +0100
8072+++ hardening-patch-5.1.2-0.4.8/Zend/zend_vm_execute.skl 2006-01-12 19:50:03.263830584 +0100
8073@@ -27,6 +27,16 @@
8074 EX(symbol_table) = EG(active_symbol_table);
8075 EX(prev_execute_data) = EG(current_execute_data);
8076 EG(current_execute_data) = &execute_data;
8077+#if HARDENING_PATCH
8078+ EX(execute_depth) = 0;
8079+
8080+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
8081+ EG(in_code_type) = ZEND_EVAL_CODE;
8082+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
8083+ EG(in_code_type) = ZEND_SANDBOX_CODE;
8084+ op_array->type = ZEND_EVAL_CODE;
8085+ }
8086+#endif
8087
8088 EG(in_execution) = 1;
8089 if (op_array->start_op) {
8090@@ -52,6 +62,18 @@
8091 */
8092 EX(function_state).function_symbol_table = NULL;
8093 #endif
8094+#if HARDENING_PATCH
8095+ if (EX(prev_execute_data) == NULL) {
8096+ EX(execute_depth) = 0;
8097+ } else {
8098+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
8099+ }
8100+
8101+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
8102+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
8103+ zend_bailout();
8104+ }
8105+#endif
8106
8107 while (1) {
8108 {%ZEND_VM_CONTINUE_LABEL%}