summaryrefslogtreecommitdiff
path: root/0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:35:52 +0200
committerjvoisin2019-10-13 12:35:52 +0200
commit7ce0f98b0be3ad15a664e506dff461cf6d633a69 (patch)
tree1aae4c7d8fa8ac62609824629db9ba46add728cc /0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch
parentd24fe97bf9a1614acf4e7431d17b762a73642e15 (diff)
Add more patches
Diffstat (limited to '0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch')
-rw-r--r--0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch4959
1 files changed, 4959 insertions, 0 deletions
diff --git a/0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch b/0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch
new file mode 100644
index 0000000..3cae163
--- /dev/null
+++ b/0.3.2/hardening-patch-4.4.0RC2-0.3.2.patch
@@ -0,0 +1,4959 @@
1diff -Naur php-4.4.0RC2/acinclude.m4 hardening-patch-4.4.0RC2-0.3.2/acinclude.m4
2--- php-4.4.0RC2/acinclude.m4 2005-04-30 11:31:09.000000000 +0200
3+++ hardening-patch-4.4.0RC2-0.3.2/acinclude.m4 2005-07-09 08:53:20.597607352 +0200
4@@ -1173,6 +1173,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 -Naur php-4.4.0RC2/configure hardening-patch-4.4.0RC2-0.3.2/configure
42--- php-4.4.0RC2/configure 2005-07-01 12:07:55.000000000 +0200
43+++ hardening-patch-4.4.0RC2-0.3.2/configure 2005-07-09 08:53:20.634601728 +0200
44@@ -394,6 +394,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@@ -846,6 +856,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@@ -2682,6 +2694,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@@ -15733,6 +15896,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:15738: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -87305,6 +87524,265 @@
292 fi
293
294
295+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
296+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
297+# Check whether --enable-varfilter or --disable-varfilter was given.
298+if test "${enable_varfilter+set}" = set; then
299+ enableval="$enable_varfilter"
300+ PHP_VARFILTER=$enableval
301+else
302+
303+ PHP_VARFILTER=yes
304+
305+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
306+ PHP_VARFILTER=$PHP_ENABLE_ALL
307+ fi
308+
309+fi
310+
311+
312+
313+ext_output="yes, shared"
314+ext_shared=yes
315+case $PHP_VARFILTER in
316+shared,*)
317+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
318+ ;;
319+shared)
320+ PHP_VARFILTER=yes
321+ ;;
322+no)
323+ ext_output=no
324+ ext_shared=no
325+ ;;
326+*)
327+ ext_output=yes
328+ ext_shared=no
329+ ;;
330+esac
331+
332+
333+
334+echo "$ac_t""$ext_output" 1>&6
335+
336+
337+
338+
339+if test "$PHP_VARFILTER" != "no"; then
340+ cat >> confdefs.h <<\EOF
341+#define HAVE_VARFILTER 1
342+EOF
343+
344+
345+ ext_builddir=ext/varfilter
346+ ext_srcdir=$abs_srcdir/ext/varfilter
347+
348+ ac_extra=
349+
350+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
351+
352+
353+
354+ case ext/varfilter in
355+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
356+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
357+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
358+ esac
359+
360+
361+
362+ b_c_pre=$php_c_pre
363+ b_cxx_pre=$php_cxx_pre
364+ b_c_meta=$php_c_meta
365+ b_cxx_meta=$php_cxx_meta
366+ b_c_post=$php_c_post
367+ b_cxx_post=$php_cxx_post
368+ b_lo=$php_lo
369+
370+
371+ old_IFS=$IFS
372+ for ac_src in varfilter.c; do
373+
374+ IFS=.
375+ set $ac_src
376+ ac_obj=$1
377+ IFS=$old_IFS
378+
379+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
380+
381+ case $ac_src in
382+ *.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" ;;
383+ *.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" ;;
384+ esac
385+
386+ cat >>Makefile.objects<<EOF
387+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
388+ $ac_comp
389+EOF
390+ done
391+
392+
393+ EXT_STATIC="$EXT_STATIC varfilter"
394+ if test "$ext_shared" != "nocli"; then
395+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
396+ fi
397+ else
398+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
399+
400+ case ext/varfilter in
401+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
402+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
403+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
404+ esac
405+
406+
407+
408+ b_c_pre=$shared_c_pre
409+ b_cxx_pre=$shared_cxx_pre
410+ b_c_meta=$shared_c_meta
411+ b_cxx_meta=$shared_cxx_meta
412+ b_c_post=$shared_c_post
413+ b_cxx_post=$shared_cxx_post
414+ b_lo=$shared_lo
415+
416+
417+ old_IFS=$IFS
418+ for ac_src in varfilter.c; do
419+
420+ IFS=.
421+ set $ac_src
422+ ac_obj=$1
423+ IFS=$old_IFS
424+
425+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
426+
427+ case $ac_src in
428+ *.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" ;;
429+ *.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" ;;
430+ esac
431+
432+ cat >>Makefile.objects<<EOF
433+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
434+ $ac_comp
435+EOF
436+ done
437+
438+
439+ install_modules="install-modules"
440+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
441+
442+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
443+
444+ cat >>Makefile.objects<<EOF
445+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
446+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
447+
448+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
449+ \$(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)
450+
451+EOF
452+
453+ cat >> confdefs.h <<EOF
454+#define COMPILE_DL_VARFILTER 1
455+EOF
456+
457+ fi
458+ fi
459+
460+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
461+ if test "$PHP_SAPI" = "cgi"; then
462+
463+
464+ case ext/varfilter in
465+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
466+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
467+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
468+ esac
469+
470+
471+
472+ b_c_pre=$php_c_pre
473+ b_cxx_pre=$php_cxx_pre
474+ b_c_meta=$php_c_meta
475+ b_cxx_meta=$php_cxx_meta
476+ b_c_post=$php_c_post
477+ b_cxx_post=$php_cxx_post
478+ b_lo=$php_lo
479+
480+
481+ old_IFS=$IFS
482+ for ac_src in varfilter.c; do
483+
484+ IFS=.
485+ set $ac_src
486+ ac_obj=$1
487+ IFS=$old_IFS
488+
489+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
490+
491+ case $ac_src in
492+ *.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" ;;
493+ *.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" ;;
494+ esac
495+
496+ cat >>Makefile.objects<<EOF
497+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
498+ $ac_comp
499+EOF
500+ done
501+
502+
503+ EXT_STATIC="$EXT_STATIC varfilter"
504+ else
505+
506+
507+ case ext/varfilter in
508+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
509+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
510+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
511+ esac
512+
513+
514+
515+ b_c_pre=$php_c_pre
516+ b_cxx_pre=$php_cxx_pre
517+ b_c_meta=$php_c_meta
518+ b_cxx_meta=$php_cxx_meta
519+ b_c_post=$php_c_post
520+ b_cxx_post=$php_cxx_post
521+ b_lo=$php_lo
522+
523+
524+ old_IFS=$IFS
525+ for ac_src in varfilter.c; do
526+
527+ IFS=.
528+ set $ac_src
529+ ac_obj=$1
530+ IFS=$old_IFS
531+
532+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
533+
534+ case $ac_src in
535+ *.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" ;;
536+ *.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" ;;
537+ esac
538+
539+ cat >>Makefile.objects<<EOF
540+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
541+ $ac_comp
542+EOF
543+ done
544+
545+
546+ fi
547+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
548+ fi
549+
550+ BUILD_DIR="$BUILD_DIR $ext_builddir"
551+
552+
553+fi
554
555
556 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
557@@ -99988,7 +100466,7 @@
558 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
559 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
560 streams.c network.c php_open_temporary_file.c php_logos.c \
561- output.c memory_streams.c user_streams.c; do
562+ output.c memory_streams.c user_streams.c hardening_patch.c; do
563
564 IFS=.
565 set $ac_src
566@@ -100161,7 +100639,7 @@
567 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
568 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
569 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
570- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
571+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
572
573 IFS=.
574 set $ac_src
575diff -Naur php-4.4.0RC2/configure.in hardening-patch-4.4.0RC2-0.3.2/configure.in
576--- php-4.4.0RC2/configure.in 2005-07-01 11:53:57.000000000 +0200
577+++ hardening-patch-4.4.0RC2-0.3.2/configure.in 2005-07-09 08:53:20.636601424 +0200
578@@ -238,7 +238,7 @@
579 sinclude(Zend/acinclude.m4)
580 sinclude(Zend/Zend.m4)
581 sinclude(TSRM/tsrm.m4)
582-
583+sinclude(main/hardening_patch.m4)
584
585
586 divert(2)
587@@ -612,6 +612,7 @@
588 AC_FUNC_ALLOCA
589 dnl PHP_AC_BROKEN_SPRINTF
590 dnl PHP_AC_BROKEN_SNPRINTF
591+PHP_AC_BROKEN_REALPATH
592 PHP_DECLARED_TIMEZONE
593 PHP_TIME_R_TYPE
594 PHP_READDIR_R_TYPE
595@@ -1241,7 +1242,7 @@
596 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
597 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
598 streams.c network.c php_open_temporary_file.c php_logos.c \
599- output.c memory_streams.c user_streams.c)
600+ output.c memory_streams.c user_streams.c hardening_patch.c)
601 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
602 PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli)
603
604@@ -1254,7 +1255,7 @@
605 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
606 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
607 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
608- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
609+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
610
611 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
612 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
613diff -Naur php-4.4.0RC2/ext/fbsql/php_fbsql.c hardening-patch-4.4.0RC2-0.3.2/ext/fbsql/php_fbsql.c
614--- php-4.4.0RC2/ext/fbsql/php_fbsql.c 2005-02-09 20:33:32.000000000 +0100
615+++ hardening-patch-4.4.0RC2-0.3.2/ext/fbsql/php_fbsql.c 2005-07-09 08:53:20.637601272 +0200
616@@ -1797,8 +1797,24 @@
617 }
618 else if (fbcmdErrorsFound(md))
619 {
620+#if HARDENING_PATCH
621+ char* query_copy;
622+ int i;
623+#endif
624 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
625 char* emg = fbcemdAllErrorMessages(emd);
626+#if HARDENING_PATCH
627+ query_copy=estrdup(query_copy);
628+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
629+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
630+ efree(query_copy);
631+ if (HG(hphp_sql_bailout_on_error)) {
632+ free(emg);
633+ fbcemdRelease(emd);
634+ result = 0;
635+ zend_bailout();
636+ }
637+#endif
638 if (FB_SQL_G(generateWarnings))
639 {
640 if (emg)
641diff -Naur php-4.4.0RC2/ext/mbstring/mbstring.c hardening-patch-4.4.0RC2-0.3.2/ext/mbstring/mbstring.c
642--- php-4.4.0RC2/ext/mbstring/mbstring.c 2005-02-21 09:03:47.000000000 +0100
643+++ hardening-patch-4.4.0RC2-0.3.2/ext/mbstring/mbstring.c 2005-07-09 08:53:20.639600968 +0200
644@@ -1487,6 +1487,7 @@
645 char *strtok_buf = NULL, **val_list;
646 zval *array_ptr = (zval *) arg;
647 int n, num, val_len, *len_list;
648+ unsigned int new_val_len;
649 enum mbfl_no_encoding from_encoding;
650 mbfl_string string, resvar, resval;
651 mbfl_encoding_detector *identd = NULL;
652@@ -1609,8 +1610,14 @@
653 val_len = len_list[n];
654 }
655 n++;
656- /* add variable to symbol table */
657- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
658+ /* we need val to be emalloc()ed */
659+ val = estrndup(val, val_len);
660+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
661+ /* add variable to symbol table */
662+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
663+ }
664+ efree(val);
665+
666 if (convd != NULL){
667 mbfl_string_clear(&resvar);
668 mbfl_string_clear(&resval);
669diff -Naur php-4.4.0RC2/ext/mysql/php_mysql.c hardening-patch-4.4.0RC2-0.3.2/ext/mysql/php_mysql.c
670--- php-4.4.0RC2/ext/mysql/php_mysql.c 2005-04-08 00:23:01.000000000 +0200
671+++ hardening-patch-4.4.0RC2-0.3.2/ext/mysql/php_mysql.c 2005-07-09 08:53:20.641600664 +0200
672@@ -1218,6 +1218,8 @@
673 {
674 php_mysql_conn *mysql;
675 MYSQL_RES *mysql_result;
676+ char *copy_query;
677+ int i;
678
679 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
680
681@@ -1268,6 +1270,13 @@
682 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
683 }
684 }
685+ copy_query = estrdup(Z_STRVAL_PP(query));
686+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
687+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
688+ efree(copy_query);
689+ if (HG(hphp_sql_bailout_on_error)) {
690+ zend_bailout();
691+ }
692 RETURN_FALSE;
693 }
694 #else
695@@ -1275,12 +1284,20 @@
696 /* check possible error */
697 if (MySG(trace_mode)){
698 if (mysql_errno(&mysql->conn)){
699- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
700+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
701 }
702 }
703+ copy_query = estrdup(Z_STRVAL_PP(query));
704+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
705+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
706+ efree(copy_query);
707+ if (HG(hphp_sql_bailout_on_error)) {
708+ zend_bailout();
709+ }
710 RETURN_FALSE;
711 }
712 #endif
713+
714 if(use_store == MYSQL_USE_RESULT) {
715 mysql_result=mysql_use_result(&mysql->conn);
716 } else {
717diff -Naur php-4.4.0RC2/ext/pgsql/pgsql.c hardening-patch-4.4.0RC2-0.3.2/ext/pgsql/pgsql.c
718--- php-4.4.0RC2/ext/pgsql/pgsql.c 2005-05-11 01:15:06.000000000 +0200
719+++ hardening-patch-4.4.0RC2-0.3.2/ext/pgsql/pgsql.c 2005-07-09 08:53:20.643600360 +0200
720@@ -1001,10 +1001,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 -Naur php-4.4.0RC2/ext/standard/array.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/array.c
754--- php-4.4.0RC2/ext/standard/array.c 2005-06-21 14:11:19.000000000 +0200
755+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/array.c 2005-07-09 08:53:20.645600056 +0200
756@@ -1162,6 +1162,32 @@
757 }
758 }
759 }
760+
761+ if (var_name[0] == 'H') {
762+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
763+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
764+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
765+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
766+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
767+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
768+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
769+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
770+ return 0;
771+ }
772+ } else if (var_name[0] == '_') {
773+ if ((strcmp(var_name, "_COOKIE")==0)||
774+ (strcmp(var_name, "_ENV")==0)||
775+ (strcmp(var_name, "_FILES")==0)||
776+ (strcmp(var_name, "_GET")==0)||
777+ (strcmp(var_name, "_POST")==0)||
778+ (strcmp(var_name, "_REQUEST")==0)||
779+ (strcmp(var_name, "_SESSION")==0)||
780+ (strcmp(var_name, "_SERVER")==0)) {
781+ return 0;
782+ }
783+ } else if (strcmp(var_name, "GLOBALS")==0) {
784+ return 0;
785+ }
786
787 return 1;
788 }
789diff -Naur php-4.4.0RC2/ext/standard/basic_functions.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/basic_functions.c
790--- php-4.4.0RC2/ext/standard/basic_functions.c 2005-05-16 10:55:31.000000000 +0200
791+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/basic_functions.c 2005-07-09 08:53:20.646599904 +0200
792@@ -687,7 +687,7 @@
793 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
794
795 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
796- PHP_FE(realpath, NULL)
797+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
798 #endif
799
800 #ifdef HAVE_FNMATCH
801@@ -3044,6 +3044,35 @@
802 memcpy(new_key, prefix, prefix_len);
803 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
804
805+ if (new_key[0] == 'H') {
806+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
807+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
808+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
809+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
810+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
811+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
812+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
813+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
814+ efree(new_key);
815+ return 0;
816+ }
817+ } else if (new_key[0] == '_') {
818+ if ((strcmp(new_key, "_COOKIE")==0)||
819+ (strcmp(new_key, "_ENV")==0)||
820+ (strcmp(new_key, "_FILES")==0)||
821+ (strcmp(new_key, "_GET")==0)||
822+ (strcmp(new_key, "_POST")==0)||
823+ (strcmp(new_key, "_REQUEST")==0)||
824+ (strcmp(new_key, "_SESSION")==0)||
825+ (strcmp(new_key, "_SERVER")==0)) {
826+ efree(new_key);
827+ return 0;
828+ }
829+ } else if (strcmp(new_key, "GLOBALS")==0) {
830+ efree(new_key);
831+ return 0;
832+ }
833+
834 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
835 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
836
837diff -Naur php-4.4.0RC2/ext/standard/file.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/file.c
838--- php-4.4.0RC2/ext/standard/file.c 2005-03-27 17:53:59.000000000 +0200
839+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/file.c 2005-07-09 08:53:20.648599600 +0200
840@@ -2469,7 +2469,7 @@
841 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
842 /* {{{ proto string realpath(string path)
843 Return the resolved path */
844-PHP_FUNCTION(realpath)
845+PHP_FUNCTION(real_path)
846 {
847 zval **path;
848 char resolved_path_buff[MAXPATHLEN];
849diff -Naur php-4.4.0RC2/ext/standard/file.h hardening-patch-4.4.0RC2-0.3.2/ext/standard/file.h
850--- php-4.4.0RC2/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
851+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/file.h 2005-07-09 08:53:20.648599600 +0200
852@@ -64,7 +64,7 @@
853 PHP_FUNCTION(fd_set);
854 PHP_FUNCTION(fd_isset);
855 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
856-PHP_FUNCTION(realpath);
857+PHP_FUNCTION(real_path);
858 #endif
859 #ifdef HAVE_FNMATCH
860 PHP_FUNCTION(fnmatch);
861diff -Naur php-4.4.0RC2/ext/standard/head.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/head.c
862--- php-4.4.0RC2/ext/standard/head.c 2005-01-07 22:14:23.000000000 +0100
863+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/head.c 2005-07-09 08:53:20.649599448 +0200
864@@ -45,10 +45,31 @@
865 {
866 zend_bool rep = 1;
867 sapi_header_line ctr = {0};
868+#if HARDENING_PATCH
869+ int i;
870+#endif
871
872 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
873 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
874 return;
875+
876+#if HARDENING_PATCH
877+ if (!HG(hphp_multiheader)) {
878+ for (i=0; i<ctr.line_len; i++) {
879+ if (ctr.line[i]==0) {
880+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
881+ ctr.line_len=i;
882+ break;
883+ } else if (ctr.line[i]=='\n') {
884+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
885+ continue;
886+ }
887+ php_security_log(S_MISC, "header(): headerline contains more than one header");
888+ ctr.line_len=i;
889+ }
890+ }
891+ }
892+#endif
893
894 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
895 }
896diff -Naur php-4.4.0RC2/ext/standard/info.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/info.c
897--- php-4.4.0RC2/ext/standard/info.c 2005-06-07 15:37:33.000000000 +0200
898+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/info.c 2005-07-09 08:53:20.649599448 +0200
899@@ -397,7 +397,7 @@
900
901 if (flag & PHP_INFO_GENERAL) {
902 char *zend_version = get_zend_version();
903- char temp_api[9];
904+ char temp_api[11];
905
906 php_uname = php_get_uname('a');
907
908@@ -419,11 +419,22 @@
909 }
910 }
911
912+#if HARDENING_PATCH
913+ if (!sapi_module.phpinfo_as_text) {
914+ php_printf("<h1 class=\"p\">PHP Version %s with Hardening-Patch %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
915+ } else {
916+ char temp_ver[40];
917+
918+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
919+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
920+ }
921+#else
922 if (!sapi_module.phpinfo_as_text) {
923 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
924 } else {
925 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
926 }
927+#endif
928 php_info_print_box_end();
929 php_info_print_table_start();
930 php_info_print_table_row(2, "System", php_uname );
931diff -Naur php-4.4.0RC2/ext/standard/syslog.c hardening-patch-4.4.0RC2-0.3.2/ext/standard/syslog.c
932--- php-4.4.0RC2/ext/standard/syslog.c 2004-07-30 16:38:29.000000000 +0200
933+++ hardening-patch-4.4.0RC2-0.3.2/ext/standard/syslog.c 2005-07-09 08:53:20.650599296 +0200
934@@ -42,6 +42,8 @@
935 */
936 PHP_MINIT_FUNCTION(syslog)
937 {
938+
939+#if !HARDENING_PATCH
940 /* error levels */
941 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
942 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
943@@ -97,7 +99,7 @@
944 /* AIX doesn't have LOG_PERROR */
945 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
946 #endif
947-
948+#endif
949 return SUCCESS;
950 }
951 /* }}} */
952diff -Naur php-4.4.0RC2/ext/varfilter/config.m4 hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/config.m4
953--- php-4.4.0RC2/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
954+++ hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/config.m4 2005-07-09 08:53:20.650599296 +0200
955@@ -0,0 +1,11 @@
956+dnl
957+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
958+dnl
959+
960+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
961+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
962+
963+if test "$PHP_VARFILTER" != "no"; then
964+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
965+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
966+fi
967diff -Naur php-4.4.0RC2/ext/varfilter/CREDITS hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/CREDITS
968--- php-4.4.0RC2/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
969+++ hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/CREDITS 2005-07-09 08:53:20.650599296 +0200
970@@ -0,0 +1,2 @@
971+varfilter
972+Stefan Esser
973\ Kein Zeilenumbruch am Dateiende.
974diff -Naur php-4.4.0RC2/ext/varfilter/php_varfilter.h hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/php_varfilter.h
975--- php-4.4.0RC2/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
976+++ hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/php_varfilter.h 2005-07-09 08:53:20.651599144 +0200
977@@ -0,0 +1,111 @@
978+/*
979+ +----------------------------------------------------------------------+
980+ | Hardened-PHP Project's varfilter extension |
981+ +----------------------------------------------------------------------+
982+ | Copyright (c) 2004-2005 Stefan Esser |
983+ +----------------------------------------------------------------------+
984+ | This source file is subject to version 2.02 of the PHP license, |
985+ | that is bundled with this package in the file LICENSE, and is |
986+ | available at through the world-wide-web at |
987+ | http://www.php.net/license/2_02.txt. |
988+ | If you did not receive a copy of the PHP license and are unable to |
989+ | obtain it through the world-wide-web, please send a note to |
990+ | license@php.net so we can mail you a copy immediately. |
991+ +----------------------------------------------------------------------+
992+ | Author: Stefan Esser <sesser@hardened-php.net> |
993+ +----------------------------------------------------------------------+
994+
995+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
996+*/
997+
998+#ifndef PHP_VARFILTER_H
999+#define PHP_VARFILTER_H
1000+
1001+extern zend_module_entry varfilter_module_entry;
1002+#define phpext_varfilter_ptr &varfilter_module_entry
1003+
1004+#ifdef PHP_WIN32
1005+#define PHP_VARFILTER_API __declspec(dllexport)
1006+#else
1007+#define PHP_VARFILTER_API
1008+#endif
1009+
1010+#ifdef ZTS
1011+#include "TSRM.h"
1012+#endif
1013+
1014+#include "SAPI.h"
1015+
1016+#include "php_variables.h"
1017+
1018+
1019+PHP_MINIT_FUNCTION(varfilter);
1020+PHP_MSHUTDOWN_FUNCTION(varfilter);
1021+PHP_RINIT_FUNCTION(varfilter);
1022+PHP_RSHUTDOWN_FUNCTION(varfilter);
1023+PHP_MINFO_FUNCTION(varfilter);
1024+
1025+
1026+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
1027+// request variables
1028+ long max_request_variables;
1029+ long cur_request_variables;
1030+ long max_varname_length;
1031+ long max_totalname_length;
1032+ long max_value_length;
1033+ long max_array_depth;
1034+ long max_array_index_length;
1035+// cookie variables
1036+ long max_cookie_vars;
1037+ long cur_cookie_vars;
1038+ long max_cookie_name_length;
1039+ long max_cookie_totalname_length;
1040+ long max_cookie_value_length;
1041+ long max_cookie_array_depth;
1042+ long max_cookie_array_index_length;
1043+// get variables
1044+ long max_get_vars;
1045+ long cur_get_vars;
1046+ long max_get_name_length;
1047+ long max_get_totalname_length;
1048+ long max_get_value_length;
1049+ long max_get_array_depth;
1050+ long max_get_array_index_length;
1051+// post variables
1052+ long max_post_vars;
1053+ long cur_post_vars;
1054+ long max_post_name_length;
1055+ long max_post_totalname_length;
1056+ long max_post_value_length;
1057+ long max_post_array_depth;
1058+ long max_post_array_index_length;
1059+// fileupload
1060+ long max_uploads;
1061+ long cur_uploads;
1062+ zend_bool disallow_elf_files;
1063+ char *verification_script;
1064+
1065+ZEND_END_MODULE_GLOBALS(varfilter)
1066+
1067+
1068+#ifdef ZTS
1069+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
1070+#else
1071+#define VARFILTER_G(v) (varfilter_globals.v)
1072+#endif
1073+
1074+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
1075+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
1076+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
1077+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
1078+
1079+#endif /* PHP_VARFILTER_H */
1080+
1081+
1082+/*
1083+ * Local variables:
1084+ * tab-width: 4
1085+ * c-basic-offset: 4
1086+ * indent-tabs-mode: t
1087+ * End:
1088+ */
1089diff -Naur php-4.4.0RC2/ext/varfilter/varfilter.c hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/varfilter.c
1090--- php-4.4.0RC2/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
1091+++ hardening-patch-4.4.0RC2-0.3.2/ext/varfilter/varfilter.c 2005-07-09 08:58:18.504318648 +0200
1092@@ -0,0 +1,604 @@
1093+/*
1094+ +----------------------------------------------------------------------+
1095+ | Hardened-PHP Project's varfilter extension |
1096+ +----------------------------------------------------------------------+
1097+ | Copyright (c) 2004-2005 Stefan Esser |
1098+ +----------------------------------------------------------------------+
1099+ | This source file is subject to version 2.02 of the PHP license, |
1100+ | that is bundled with this package in the file LICENSE, and is |
1101+ | available at through the world-wide-web at |
1102+ | http://www.php.net/license/2_02.txt. |
1103+ | If you did not receive a copy of the PHP license and are unable to |
1104+ | obtain it through the world-wide-web, please send a note to |
1105+ | license@php.net so we can mail you a copy immediately. |
1106+ +----------------------------------------------------------------------+
1107+ | Author: Stefan Esser <sesser@hardened-php.net> |
1108+ +----------------------------------------------------------------------+
1109+
1110+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
1111+*/
1112+
1113+#ifdef HAVE_CONFIG_H
1114+#include "config.h"
1115+#endif
1116+
1117+#include "php.h"
1118+#include "php_ini.h"
1119+#include "ext/standard/info.h"
1120+#include "php_varfilter.h"
1121+#include "hardening_patch.h"
1122+
1123+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
1124+
1125+/* True global resources - no need for thread safety here */
1126+static int le_varfilter;
1127+
1128+/* {{{ varfilter_module_entry
1129+ */
1130+zend_module_entry varfilter_module_entry = {
1131+#if ZEND_MODULE_API_NO >= 20010901
1132+ STANDARD_MODULE_HEADER,
1133+#endif
1134+ "varfilter",
1135+ NULL,
1136+ PHP_MINIT(varfilter),
1137+ PHP_MSHUTDOWN(varfilter),
1138+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
1139+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
1140+ PHP_MINFO(varfilter),
1141+#if ZEND_MODULE_API_NO >= 20010901
1142+ "0.3.2", /* Replace with version number for your extension */
1143+#endif
1144+ STANDARD_MODULE_PROPERTIES
1145+};
1146+/* }}} */
1147+
1148+#ifdef COMPILE_DL_VARFILTER
1149+ZEND_GET_MODULE(varfilter)
1150+#endif
1151+
1152+/* {{{ PHP_INI
1153+ */
1154+PHP_INI_BEGIN()
1155+ /* for backward compatibility */
1156+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
1157+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
1158+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
1159+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
1160+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
1161+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
1162+
1163+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
1164+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
1165+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
1166+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
1167+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
1168+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
1169+
1170+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
1171+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
1172+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
1173+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
1174+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
1175+ 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)
1176+
1177+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
1178+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
1179+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
1180+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
1181+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
1182+ 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)
1183+
1184+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
1185+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
1186+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
1187+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
1188+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
1189+ 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)
1190+
1191+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
1192+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
1193+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
1194+
1195+
1196+PHP_INI_END()
1197+/* }}} */
1198+
1199+/* {{{ php_varfilter_init_globals
1200+ */
1201+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
1202+{
1203+ varfilter_globals->max_request_variables = 200;
1204+ varfilter_globals->max_varname_length = 64;
1205+ varfilter_globals->max_value_length = 10000;
1206+ varfilter_globals->max_array_depth = 100;
1207+ varfilter_globals->max_totalname_length = 256;
1208+ varfilter_globals->max_array_index_length = 64;
1209+
1210+ varfilter_globals->max_cookie_vars = 100;
1211+ varfilter_globals->max_cookie_name_length = 64;
1212+ varfilter_globals->max_cookie_totalname_length = 256;
1213+ varfilter_globals->max_cookie_value_length = 10000;
1214+ varfilter_globals->max_cookie_array_depth = 100;
1215+ varfilter_globals->max_cookie_array_index_length = 64;
1216+
1217+ varfilter_globals->max_get_vars = 100;
1218+ varfilter_globals->max_get_name_length = 64;
1219+ varfilter_globals->max_get_totalname_length = 256;
1220+ varfilter_globals->max_get_value_length = 512;
1221+ varfilter_globals->max_get_array_depth = 50;
1222+ varfilter_globals->max_get_array_index_length = 64;
1223+
1224+ varfilter_globals->max_post_vars = 200;
1225+ varfilter_globals->max_post_name_length = 64;
1226+ varfilter_globals->max_post_totalname_length = 256;
1227+ varfilter_globals->max_post_value_length = 65000;
1228+ varfilter_globals->max_post_array_depth = 100;
1229+ varfilter_globals->max_post_array_index_length = 64;
1230+
1231+ varfilter_globals->max_uploads = 25;
1232+ varfilter_globals->disallow_elf_files = 1;
1233+ varfilter_globals->verification_script = NULL;
1234+}
1235+/* }}} */
1236+
1237+/* {{{ PHP_MINIT_FUNCTION
1238+ */
1239+PHP_MINIT_FUNCTION(varfilter)
1240+{
1241+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
1242+ REGISTER_INI_ENTRIES();
1243+
1244+ sapi_register_input_filter(varfilter_input_filter);
1245+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
1246+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
1247+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
1248+
1249+ return SUCCESS;
1250+}
1251+/* }}} */
1252+
1253+/* {{{ PHP_MSHUTDOWN_FUNCTION
1254+ */
1255+PHP_MSHUTDOWN_FUNCTION(varfilter)
1256+{
1257+// zend_hash_apply_with_arguments(&HG(lists.functionlists), (apply_func_args_t) show_stuff, 0);
1258+
1259+ UNREGISTER_INI_ENTRIES();
1260+
1261+ return SUCCESS;
1262+}
1263+/* }}} */
1264+
1265+/* Remove if there's nothing to do at request start */
1266+/* {{{ PHP_RINIT_FUNCTION
1267+ */
1268+PHP_RINIT_FUNCTION(varfilter)
1269+{
1270+ VARFILTER_G(cur_request_variables) = 0;
1271+ VARFILTER_G(cur_get_vars) = 0;
1272+ VARFILTER_G(cur_post_vars) = 0;
1273+ VARFILTER_G(cur_cookie_vars) = 0;
1274+
1275+ VARFILTER_G(cur_uploads) = 0;
1276+
1277+ return SUCCESS;
1278+}
1279+/* }}} */
1280+
1281+/* Remove if there's nothing to do at request end */
1282+/* {{{ PHP_RSHUTDOWN_FUNCTION
1283+ */
1284+PHP_RSHUTDOWN_FUNCTION(varfilter)
1285+{
1286+ return SUCCESS;
1287+}
1288+/* }}} */
1289+
1290+/* {{{ PHP_MINFO_FUNCTION
1291+ */
1292+PHP_MINFO_FUNCTION(varfilter)
1293+{
1294+ php_info_print_table_start();
1295+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
1296+ php_info_print_table_end();
1297+
1298+ DISPLAY_INI_ENTRIES();
1299+}
1300+/* }}} */
1301+
1302+/* {{{ normalize_varname
1303+ */
1304+static void normalize_varname(char *varname)
1305+{
1306+ char *s=varname, *index=NULL, *indexend=NULL, *p;
1307+
1308+ /* overjump leading space */
1309+ while (*s == ' ') {
1310+ s++;
1311+ }
1312+
1313+ /* and remove it */
1314+ if (s != varname) {
1315+ memmove(varname, s, strlen(s)+1);
1316+ }
1317+
1318+ for (p=varname; *p && *p != '['; p++) {
1319+ switch(*p) {
1320+ case ' ':
1321+ case '.':
1322+ *p='_';
1323+ break;
1324+ }
1325+ }
1326+
1327+ /* find index */
1328+ index = strchr(varname, '[');
1329+ if (index) {
1330+ index++;
1331+ s=index;
1332+ } else {
1333+ return;
1334+ }
1335+
1336+ /* done? */
1337+ while (index) {
1338+
1339+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
1340+ index++;
1341+ }
1342+ indexend = strchr(index, ']');
1343+ indexend = indexend ? indexend + 1 : index + strlen(index);
1344+
1345+ if (s != index) {
1346+ memmove(s, index, strlen(index)+1);
1347+ s += indexend-index;
1348+ } else {
1349+ s = indexend;
1350+ }
1351+
1352+ if (*s == '[') {
1353+ s++;
1354+ index = s;
1355+ } else {
1356+ index = NULL;
1357+ }
1358+ }
1359+ *s++='\0';
1360+}
1361+/* }}} */
1362+
1363+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
1364+ */
1365+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
1366+{
1367+ /* Drop this fileupload if the limit is reached */
1368+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
1369+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
1370+ return FAILURE;
1371+ }
1372+
1373+ return SUCCESS;
1374+}
1375+/* }}} */
1376+
1377+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
1378+ */
1379+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
1380+{
1381+
1382+ if (VARFILTER_G(disallow_elf_files)) {
1383+
1384+ if (offset == 0 && buffer_len > 10) {
1385+
1386+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
1387+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
1388+ return FAILURE;
1389+ }
1390+ }
1391+
1392+ }
1393+
1394+ return SUCCESS;
1395+}
1396+/* }}} */
1397+
1398+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
1399+ */
1400+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
1401+{
1402+ int retval = SUCCESS;
1403+
1404+ if (VARFILTER_G(verification_script)) {
1405+ char cmd[8192];
1406+ FILE *in;
1407+ int first=1;
1408+
1409+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
1410+
1411+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
1412+ php_security_log(S_FILES, "unable to execute fileupload verification script - file dropped");
1413+ return FAILURE;
1414+ }
1415+
1416+ retval = FAILURE;
1417+
1418+ /* read and forget the result */
1419+ while (1) {
1420+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
1421+ if (readbytes<=0) {
1422+ break;
1423+ }
1424+ if (first) {
1425+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
1426+ first = 0;
1427+ }
1428+ }
1429+ pclose(in);
1430+ }
1431+
1432+ if (retval != SUCCESS) {
1433+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
1434+ return FAILURE;
1435+ }
1436+
1437+ VARFILTER_G(cur_uploads)++;
1438+ return SUCCESS;
1439+}
1440+/* }}} */
1441+
1442+/* {{{ SAPI_INPUT_FILTER_FUNC
1443+ */
1444+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
1445+{
1446+ char *index, *prev_index = NULL, *copy_var;
1447+ unsigned int var_len, total_len, depth = 0, rv;
1448+
1449+ /* Drop this variable if the limit is reached */
1450+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
1451+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
1452+ return 0;
1453+ }
1454+ switch (arg) {
1455+ case PARSE_GET:
1456+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
1457+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
1458+ return 0;
1459+ }
1460+ break;
1461+ case PARSE_COOKIE:
1462+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
1463+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
1464+ return 0;
1465+ }
1466+ break;
1467+ case PARSE_POST:
1468+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
1469+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
1470+ return 0;
1471+ }
1472+ break;
1473+ }
1474+
1475+
1476+ /* Drop this variable if it exceeds the value length limit */
1477+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
1478+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
1479+ return 0;
1480+ }
1481+ switch (arg) {
1482+ case PARSE_GET:
1483+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
1484+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
1485+ return 0;
1486+ }
1487+ break;
1488+ case PARSE_COOKIE:
1489+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
1490+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
1491+ return 0;
1492+ }
1493+ break;
1494+ case PARSE_POST:
1495+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
1496+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
1497+ return 0;
1498+ }
1499+ break;
1500+ }
1501+
1502+ /* Normalize the variable name */
1503+ normalize_varname(var);
1504+
1505+ /* Find length of variable name */
1506+ index = strchr(var, '[');
1507+ total_len = strlen(var);
1508+ var_len = index ? index-var : total_len;
1509+
1510+ /* Drop this variable if it exceeds the varname/total length limit */
1511+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
1512+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
1513+ return 0;
1514+ }
1515+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
1516+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
1517+ return 0;
1518+ }
1519+ switch (arg) {
1520+ case PARSE_GET:
1521+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
1522+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
1523+ return 0;
1524+ }
1525+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
1526+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
1527+ return 0;
1528+ }
1529+ break;
1530+ case PARSE_COOKIE:
1531+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
1532+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
1533+ return 0;
1534+ }
1535+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
1536+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
1537+ return 0;
1538+ }
1539+ break;
1540+ case PARSE_POST:
1541+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
1542+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
1543+ return 0;
1544+ }
1545+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
1546+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
1547+ return 0;
1548+ }
1549+ break;
1550+ }
1551+
1552+ /* Find out array depth */
1553+ while (index) {
1554+ unsigned int index_length;
1555+
1556+ depth++;
1557+ index = strchr(index+1, '[');
1558+
1559+ if (prev_index) {
1560+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
1561+
1562+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
1563+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
1564+ return 0;
1565+ }
1566+ switch (arg) {
1567+ case PARSE_GET:
1568+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
1569+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
1570+ return 0;
1571+ }
1572+ break;
1573+ case PARSE_COOKIE:
1574+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
1575+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
1576+ return 0;
1577+ }
1578+ break;
1579+ case PARSE_POST:
1580+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
1581+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
1582+ return 0;
1583+ }
1584+ break;
1585+ }
1586+ prev_index = index;
1587+ }
1588+
1589+ }
1590+
1591+ /* Drop this variable if it exceeds the array depth limit */
1592+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
1593+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
1594+ return 0;
1595+ }
1596+ switch (arg) {
1597+ case PARSE_GET:
1598+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
1599+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
1600+ return 0;
1601+ }
1602+ break;
1603+ case PARSE_COOKIE:
1604+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
1605+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
1606+ return 0;
1607+ }
1608+ break;
1609+ case PARSE_POST:
1610+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
1611+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
1612+ return 0;
1613+ }
1614+ break;
1615+ }
1616+
1617+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
1618+ /* This is to protect several silly scripts that do globalizing themself */
1619+
1620+ switch (var_len) {
1621+ case 18:
1622+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
1623+ break;
1624+ case 17:
1625+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
1626+ break;
1627+ case 16:
1628+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
1629+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
1630+ break;
1631+ case 15:
1632+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
1633+ break;
1634+ case 14:
1635+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
1636+ break;
1637+ case 13:
1638+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
1639+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
1640+ break;
1641+ case 8:
1642+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
1643+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
1644+ break;
1645+ case 7:
1646+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
1647+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
1648+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
1649+ break;
1650+ case 6:
1651+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
1652+ break;
1653+ case 5:
1654+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
1655+ break;
1656+ case 4:
1657+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
1658+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
1659+ break;
1660+ }
1661+
1662+ /* Okay let PHP register this variable */
1663+ VARFILTER_G(cur_request_variables)++;
1664+ switch (arg) {
1665+ case PARSE_GET:
1666+ VARFILTER_G(cur_get_vars)++;
1667+ break;
1668+ case PARSE_COOKIE:
1669+ VARFILTER_G(cur_cookie_vars)++;
1670+ break;
1671+ case PARSE_POST:
1672+ VARFILTER_G(cur_post_vars)++;
1673+ break;
1674+ }
1675+
1676+ if (new_val_len) {
1677+ *new_val_len = val_len;
1678+ }
1679+
1680+ return 1;
1681+protected_varname:
1682+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
1683+ return 0;
1684+}
1685+/* }}} */
1686+
1687+/*
1688+ * Local variables:
1689+ * tab-width: 4
1690+ * c-basic-offset: 4
1691+ * End:
1692+ * vim600: noet sw=4 ts=4 fdm=marker
1693+ * vim<600: noet sw=4 ts=4
1694+ */
1695+
1696+
1697diff -Naur php-4.4.0RC2/main/fopen_wrappers.c hardening-patch-4.4.0RC2-0.3.2/main/fopen_wrappers.c
1698--- php-4.4.0RC2/main/fopen_wrappers.c 2005-02-03 00:44:07.000000000 +0100
1699+++ hardening-patch-4.4.0RC2-0.3.2/main/fopen_wrappers.c 2005-07-09 08:53:20.652598992 +0200
1700@@ -166,6 +166,21 @@
1701 char *pathbuf;
1702 char *ptr;
1703 char *end;
1704+ char path_copy[MAXPATHLEN];
1705+ int path_len;
1706+
1707+ /* Special case path ends with a trailing slash */
1708+ path_len = strlen(path);
1709+ if (path_len >= MAXPATHLEN) {
1710+ errno = EPERM; /* we deny permission to open it */
1711+ return -1;
1712+ }
1713+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
1714+ memcpy(path_copy, path, path_len+1);
1715+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
1716+ path_copy[path_len] = '\0';
1717+ path = (const char *)&path_copy;
1718+ }
1719
1720 pathbuf = estrdup(PG(open_basedir));
1721
1722diff -Naur php-4.4.0RC2/main/hardened_globals.h hardening-patch-4.4.0RC2-0.3.2/main/hardened_globals.h
1723--- php-4.4.0RC2/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
1724+++ hardening-patch-4.4.0RC2-0.3.2/main/hardened_globals.h 2005-07-09 08:53:20.653598840 +0200
1725@@ -0,0 +1,56 @@
1726+/*
1727+ +----------------------------------------------------------------------+
1728+ | Hardening-Patch for PHP |
1729+ +----------------------------------------------------------------------+
1730+ | Copyright (c) 2004-2005 Stefan Esser |
1731+ +----------------------------------------------------------------------+
1732+ | This source file is subject to version 2.02 of the PHP license, |
1733+ | that is bundled with this package in the file LICENSE, and is |
1734+ | available at through the world-wide-web at |
1735+ | http://www.php.net/license/2_02.txt. |
1736+ | If you did not receive a copy of the PHP license and are unable to |
1737+ | obtain it through the world-wide-web, please send a note to |
1738+ | license@php.net so we can mail you a copy immediately. |
1739+ +----------------------------------------------------------------------+
1740+ | Author: Stefan Esser <sesser@hardened-php.net> |
1741+ +----------------------------------------------------------------------+
1742+ */
1743+
1744+#ifndef HARDENED_GLOBALS_H
1745+#define HARDENED_GLOBALS_H
1746+
1747+typedef struct _hardened_globals hardened_globals_struct;
1748+
1749+#ifdef ZTS
1750+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
1751+extern int hardened_globals_id;
1752+#else
1753+# define HG(v) (hardened_globals.v)
1754+extern struct _hardened_globals hardened_globals;
1755+#endif
1756+
1757+
1758+struct _hardened_globals {
1759+#if HARDENING_PATCH_MM_PROTECT
1760+ unsigned int canary_1;
1761+ unsigned int canary_2;
1762+#endif
1763+#if HARDENING_PATCH_LL_PROTECT
1764+ unsigned int canary_3;
1765+ unsigned int canary_4;
1766+ unsigned int ll_canary_inited;
1767+#endif
1768+ zend_bool hphp_sql_bailout_on_error;
1769+ zend_bool hphp_multiheader;
1770+ unsigned int dummy;
1771+};
1772+
1773+
1774+#endif /* HARDENED_GLOBALS_H */
1775+
1776+/*
1777+ * Local variables:
1778+ * tab-width: 4
1779+ * c-basic-offset: 4
1780+ * End:
1781+ */
1782diff -Naur php-4.4.0RC2/main/hardening_patch.c hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.c
1783--- php-4.4.0RC2/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
1784+++ hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.c 2005-07-09 08:53:20.653598840 +0200
1785@@ -0,0 +1,322 @@
1786+/*
1787+ +----------------------------------------------------------------------+
1788+ | Hardening Patch for PHP |
1789+ +----------------------------------------------------------------------+
1790+ | Copyright (c) 2004-2005 Stefan Esser |
1791+ +----------------------------------------------------------------------+
1792+ | This source file is subject to version 2.02 of the PHP license, |
1793+ | that is bundled with this package in the file LICENSE, and is |
1794+ | available at through the world-wide-web at |
1795+ | http://www.php.net/license/2_02.txt. |
1796+ | If you did not receive a copy of the PHP license and are unable to |
1797+ | obtain it through the world-wide-web, please send a note to |
1798+ | license@php.net so we can mail you a copy immediately. |
1799+ +----------------------------------------------------------------------+
1800+ | Author: Stefan Esser <sesser@hardened-php.net> |
1801+ +----------------------------------------------------------------------+
1802+ */
1803+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
1804+
1805+#include "php.h"
1806+
1807+#include <stdio.h>
1808+#include <stdlib.h>
1809+
1810+#if HAVE_UNISTD_H
1811+#include <unistd.h>
1812+#endif
1813+#include "SAPI.h"
1814+#include "php_globals.h"
1815+
1816+#if HARDENING_PATCH
1817+
1818+#ifdef HAVE_SYS_SOCKET_H
1819+#include <sys/socket.h>
1820+#endif
1821+
1822+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
1823+#undef AF_UNIX
1824+#endif
1825+
1826+#if defined(AF_UNIX)
1827+#include <sys/un.h>
1828+#endif
1829+
1830+#define SYSLOG_PATH "/dev/log"
1831+
1832+#include "snprintf.h"
1833+
1834+#include "hardening_patch.h"
1835+
1836+#ifdef ZTS
1837+#include "hardened_globals.h"
1838+int hardened_globals_id;
1839+#else
1840+struct _hardened_globals hardened_globals;
1841+#endif
1842+
1843+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
1844+{
1845+ memset(hardened_globals, 0, sizeof(*hardened_globals));
1846+}
1847+
1848+
1849+PHPAPI void hardened_startup()
1850+{
1851+#ifdef ZTS
1852+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
1853+#else
1854+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
1855+#endif
1856+}
1857+
1858+char *loglevel2string(int loglevel)
1859+{
1860+ switch (loglevel) {
1861+ case S_FILES:
1862+ return "FILES";
1863+ case S_INCLUDE:
1864+ return "INCLUDE";
1865+ case S_MEMORY:
1866+ return "MEMORY";
1867+ case S_MISC:
1868+ return "MISC";
1869+ case S_SQL:
1870+ return "SQL";
1871+ case S_EXECUTOR:
1872+ return "EXECUTOR";
1873+ case S_VARS:
1874+ return "VARS";
1875+ default:
1876+ return "UNKNOWN";
1877+ }
1878+}
1879+
1880+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
1881+{
1882+#if defined(AF_UNIX)
1883+ int s, r, i=0;
1884+ struct sockaddr_un saun;
1885+ char buf[4096+64];
1886+ char error[4096+100];
1887+ char *ip_address;
1888+ char *fname;
1889+ int lineno;
1890+ va_list ap;
1891+ TSRMLS_FETCH();
1892+
1893+ if (EG(hphp_log_use_x_forwarded_for)) {
1894+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
1895+ if (ip_address == NULL) {
1896+ ip_address = "X-FORWARDED-FOR not set";
1897+ }
1898+ } else {
1899+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
1900+ if (ip_address == NULL) {
1901+ ip_address = "REMOTE_ADDR not set";
1902+ }
1903+ }
1904+
1905+
1906+ va_start(ap, fmt);
1907+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
1908+ va_end(ap);
1909+ while (error[i]) {
1910+ if (error[i] < 32) error[i] = '.';
1911+ i++;
1912+ }
1913+
1914+ if (zend_is_executing(TSRMLS_C)) {
1915+ lineno = zend_get_executed_lineno(TSRMLS_C);
1916+ fname = zend_get_executed_filename(TSRMLS_C);
1917+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
1918+ } else {
1919+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
1920+ if (fname==NULL) {
1921+ fname = "unknown";
1922+ }
1923+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
1924+ }
1925+
1926+ /* Syslog-Logging disabled? */
1927+ if ((EG(hphp_log_syslog) & loglevel)==0) {
1928+ goto log_sapi;
1929+ }
1930+
1931+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
1932+
1933+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
1934+ if (s == -1) {
1935+ goto log_sapi;
1936+ }
1937+
1938+ memset(&saun, 0, sizeof(saun));
1939+ saun.sun_family = AF_UNIX;
1940+ strcpy(saun.sun_path, SYSLOG_PATH);
1941+ /*saun.sun_len = sizeof(saun);*/
1942+
1943+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
1944+ if (r) {
1945+ close(s);
1946+ s = socket(AF_UNIX, SOCK_STREAM, 0);
1947+ if (s == -1) {
1948+ goto log_sapi;
1949+ }
1950+
1951+ memset(&saun, 0, sizeof(saun));
1952+ saun.sun_family = AF_UNIX;
1953+ strcpy(saun.sun_path, SYSLOG_PATH);
1954+ /*saun.sun_len = sizeof(saun);*/
1955+
1956+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
1957+ if (r) {
1958+ close(s);
1959+ goto log_sapi;
1960+ }
1961+ }
1962+ send(s, error, strlen(error), 0);
1963+
1964+ close(s);
1965+
1966+log_sapi:
1967+ /* SAPI Logging activated? */
1968+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
1969+ sapi_module.log_message(buf);
1970+ }
1971+
1972+log_script:
1973+ /* script logging activaed? */
1974+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
1975+ char cmd[8192], *cmdpos, *bufpos;
1976+ FILE *in;
1977+ int space;
1978+
1979+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
1980+ space = sizeof(cmd) - strlen(cmd);
1981+ cmdpos = cmd + strlen(cmd);
1982+ bufpos = buf;
1983+ if (space <= 1) return;
1984+ while (space > 2 && *bufpos) {
1985+ if (*bufpos == '\'') {
1986+ if (space<=5) break;
1987+ *cmdpos++ = '\'';
1988+ *cmdpos++ = '\\';
1989+ *cmdpos++ = '\'';
1990+ *cmdpos++ = '\'';
1991+ bufpos++;
1992+ space-=4;
1993+ } else {
1994+ *cmdpos++ = *bufpos++;
1995+ space--;
1996+ }
1997+ }
1998+ *cmdpos++ = '\'';
1999+ *cmdpos = 0;
2000+
2001+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
2002+ return;
2003+ }
2004+ /* read and forget the result */
2005+ while (1) {
2006+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
2007+ if (readbytes<=0) {
2008+ break;
2009+ }
2010+ }
2011+ pclose(in);
2012+ }
2013+
2014+#endif
2015+}
2016+#endif
2017+
2018+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
2019+
2020+/* will be replaced later with more compatible method */
2021+PHPAPI unsigned int php_canary()
2022+{
2023+ time_t t;
2024+ unsigned int canary;
2025+ int fd;
2026+
2027+ fd = open("/dev/urandom", 0);
2028+ if (fd != -1) {
2029+ int r = read(fd, &canary, sizeof(canary));
2030+ close(fd);
2031+ if (r == sizeof(canary)) {
2032+ return (canary);
2033+ }
2034+ }
2035+ /* not good but we never want to do this */
2036+ time(&t);
2037+ canary = *(unsigned int *)&t + getpid() << 16;
2038+ return (canary);
2039+}
2040+#endif
2041+
2042+#if HARDENING_PATCH_INC_PROTECT
2043+
2044+PHPAPI int php_is_valid_include(zval *z)
2045+{
2046+ char *filename;
2047+ int len, i;
2048+ TSRMLS_FETCH();
2049+
2050+ /* must be of type string */
2051+ if (z->type != IS_STRING || z->value.str.val == NULL) {
2052+ return (0);
2053+ }
2054+
2055+ /* short cut */
2056+ filename = z->value.str.val;
2057+ len = z->value.str.len;
2058+
2059+ /* 1. must be shorter than MAXPATHLEN */
2060+ if (len > MAXPATHLEN) {
2061+ char *fname = estrndup(filename, len);
2062+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
2063+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
2064+ efree(fname);
2065+ return (0);
2066+ }
2067+
2068+ /* 2. must not be cutted */
2069+ if (len != strlen(filename)) {
2070+ char *fname = estrndup(filename, len);
2071+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
2072+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
2073+ efree(fname);
2074+ return (0);
2075+ }
2076+
2077+ /* 3. must not be a URL */
2078+ if (strstr(filename, "://")) {
2079+ char *fname = estrndup(filename, len);
2080+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
2081+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
2082+ efree(fname);
2083+ return (0);
2084+ }
2085+
2086+ /* 4. must not be an uploaded file */
2087+ if (SG(rfc1867_uploaded_files)) {
2088+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
2089+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
2090+ return (0);
2091+ }
2092+ }
2093+
2094+ /* passed all tests */
2095+ return (1);
2096+}
2097+
2098+#endif
2099+
2100+/*
2101+ * Local variables:
2102+ * tab-width: 4
2103+ * c-basic-offset: 4
2104+ * End:
2105+ * vim600: sw=4 ts=4 fdm=marker
2106+ * vim<600: sw=4 ts=4
2107+ */
2108diff -Naur php-4.4.0RC2/main/hardening_patch.h hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.h
2109--- php-4.4.0RC2/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
2110+++ hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.h 2005-07-09 08:58:18.505318496 +0200
2111@@ -0,0 +1,46 @@
2112+/*
2113+ +----------------------------------------------------------------------+
2114+ | Hardening Patch for PHP |
2115+ +----------------------------------------------------------------------+
2116+ | Copyright (c) 2004-2005 Stefan Esser |
2117+ +----------------------------------------------------------------------+
2118+ | This source file is subject to version 2.02 of the PHP license, |
2119+ | that is bundled with this package in the file LICENSE, and is |
2120+ | available at through the world-wide-web at |
2121+ | http://www.php.net/license/2_02.txt. |
2122+ | If you did not receive a copy of the PHP license and are unable to |
2123+ | obtain it through the world-wide-web, please send a note to |
2124+ | license@php.net so we can mail you a copy immediately. |
2125+ +----------------------------------------------------------------------+
2126+ | Author: Stefan Esser <sesser@hardened-php.net> |
2127+ +----------------------------------------------------------------------+
2128+ */
2129+
2130+#ifndef HARDENING_PATCH_H
2131+#define HARDENING_PATCH_H
2132+
2133+#include "zend.h"
2134+
2135+#if HARDENING_PATCH
2136+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
2137+PHPAPI void hardened_startup();
2138+#define HARDENING_PATCH_VERSION "0.3.2"
2139+
2140+#endif
2141+
2142+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
2143+PHPAPI unsigned int php_canary();
2144+#endif
2145+
2146+#if HARDENING_PATCH_INC_PROTECT
2147+PHPAPI int php_is_valid_include(zval *z);
2148+#endif
2149+
2150+#endif /* HARDENING_PATCH_H */
2151+
2152+/*
2153+ * Local variables:
2154+ * tab-width: 4
2155+ * c-basic-offset: 4
2156+ * End:
2157+ */
2158diff -Naur php-4.4.0RC2/main/hardening_patch.m4 hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.m4
2159--- php-4.4.0RC2/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
2160+++ hardening-patch-4.4.0RC2-0.3.2/main/hardening_patch.m4 2005-07-09 08:53:20.654598688 +0200
2161@@ -0,0 +1,95 @@
2162+dnl
2163+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
2164+dnl
2165+dnl This file contains Hardening Patch for PHP specific autoconf functions.
2166+dnl
2167+
2168+AC_ARG_ENABLE(hardening-patch-mm-protect,
2169+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
2170+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
2171+],[
2172+ DO_HARDENING_PATCH_MM_PROTECT=yes
2173+])
2174+
2175+AC_ARG_ENABLE(hardening-patch-ll-protect,
2176+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
2177+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
2178+],[
2179+ DO_HARDENING_PATCH_LL_PROTECT=yes
2180+])
2181+
2182+AC_ARG_ENABLE(hardening-patch-inc-protect,
2183+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
2184+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
2185+],[
2186+ DO_HARDENING_PATCH_INC_PROTECT=yes
2187+])
2188+
2189+AC_ARG_ENABLE(hardening-patch-fmt-protect,
2190+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
2191+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
2192+],[
2193+ DO_HARDENING_PATCH_FMT_PROTECT=yes
2194+])
2195+
2196+AC_ARG_ENABLE(hardening-patch-hash-protect,
2197+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
2198+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
2199+],[
2200+ DO_HARDENING_PATCH_HASH_PROTECT=yes
2201+])
2202+
2203+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
2204+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
2205+
2206+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
2207+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
2208+
2209+AC_MSG_CHECKING(whether to protect include/require statements)
2210+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
2211+
2212+AC_MSG_CHECKING(whether to protect PHP Format String functions)
2213+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
2214+
2215+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
2216+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
2217+
2218+
2219+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2220+
2221+
2222+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
2223+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2224+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
2225+else
2226+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
2227+fi
2228+
2229+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
2230+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2231+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
2232+else
2233+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
2234+fi
2235+
2236+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
2237+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2238+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
2239+else
2240+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
2241+fi
2242+
2243+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
2244+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2245+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
2246+else
2247+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
2248+fi
2249+
2250+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
2251+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
2252+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
2253+else
2254+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
2255+fi
2256+
2257diff -Naur php-4.4.0RC2/main/main.c hardening-patch-4.4.0RC2-0.3.2/main/main.c
2258--- php-4.4.0RC2/main/main.c 2005-06-20 21:59:43.000000000 +0200
2259+++ hardening-patch-4.4.0RC2-0.3.2/main/main.c 2005-07-09 08:53:20.655598536 +0200
2260@@ -100,6 +100,10 @@
2261 PHPAPI int core_globals_id;
2262 #endif
2263
2264+#if HARDENING_PATCH
2265+#include "hardened_globals.h"
2266+#endif
2267+
2268 #define ERROR_BUF_LEN 1024
2269
2270 typedef struct {
2271@@ -150,10 +154,33 @@
2272 */
2273 static PHP_INI_MH(OnChangeMemoryLimit)
2274 {
2275+#if HARDENING_PATCH
2276+ long orig_memory_limit;
2277+
2278+ if (entry->modified) {
2279+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
2280+ } else {
2281+ orig_memory_limit = 1<<30;
2282+ }
2283+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
2284+ orig_memory_limit = 1<<30;
2285+ }
2286+#endif
2287 if (new_value) {
2288 PG(memory_limit) = zend_atoi(new_value, new_value_length);
2289+#if HARDENING_PATCH
2290+ if (PG(memory_limit) > orig_memory_limit) {
2291+ PG(memory_limit) = orig_memory_limit;
2292+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
2293+ return FAILURE;
2294+ }
2295+#endif
2296 } else {
2297+#if HARDENING_PATCH
2298+ PG(memory_limit) = orig_memory_limit;
2299+#else
2300 PG(memory_limit) = 1<<30; /* effectively, no limit */
2301+#endif
2302 }
2303 return zend_set_memory_limit(PG(memory_limit));
2304 }
2305@@ -1096,6 +1123,10 @@
2306 tsrm_ls = ts_resource(0);
2307 #endif
2308
2309+#if HARDENING_PATCH
2310+ hardened_startup();
2311+#endif
2312+
2313 sapi_initialize_empty_request(TSRMLS_C);
2314 sapi_activate(TSRMLS_C);
2315
2316@@ -1108,6 +1139,12 @@
2317 php_output_startup();
2318 php_output_activate(TSRMLS_C);
2319
2320+#if HARDENING_PATCH_INC_PROTECT
2321+ zuf.is_valid_include = php_is_valid_include;
2322+#endif
2323+#if HARDENING_PATCH
2324+ zuf.security_log_function = php_security_log;
2325+#endif
2326 zuf.error_function = php_error_cb;
2327 zuf.printf_function = php_printf;
2328 zuf.write_function = php_body_write_wrapper;
2329@@ -1209,6 +1246,10 @@
2330 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
2331 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);
2332 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
2333+#if HARDENING_PATCH
2334+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
2335+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
2336+#endif
2337 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
2338 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
2339 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
2340@@ -1316,7 +1357,7 @@
2341 */
2342 static inline void php_register_server_variables(TSRMLS_D)
2343 {
2344- zval *array_ptr=NULL;
2345+ zval *array_ptr=NULL, *vptr;
2346
2347 ALLOC_ZVAL(array_ptr);
2348 array_init(array_ptr);
2349@@ -1326,6 +1367,16 @@
2350 /* Server variables */
2351 if (sapi_module.register_server_variables) {
2352 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
2353+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
2354+ char *str;
2355+ if (vptr->type != IS_STRING) {
2356+ str = "Array";
2357+ } else {
2358+ str = vptr->value.str.val;
2359+ }
2360+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
2361+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
2362+ }
2363 }
2364
2365 /* PHP Authentication support */
2366diff -Naur php-4.4.0RC2/main/php_config.h.in hardening-patch-4.4.0RC2-0.3.2/main/php_config.h.in
2367--- php-4.4.0RC2/main/php_config.h.in 2005-07-01 12:08:17.000000000 +0200
2368+++ hardening-patch-4.4.0RC2-0.3.2/main/php_config.h.in 2005-07-09 08:53:20.656598384 +0200
2369@@ -860,6 +860,39 @@
2370 /* Enabling BIND8 compatibility for Panther */
2371 #undef BIND_8_COMPAT
2372
2373+/* Hardening-Patch */
2374+#undef HARDENING_PATCH
2375+
2376+/* Memory Manager Protection */
2377+#undef HARDENING_PATCH_MM_PROTECT
2378+
2379+/* Memory Manager Protection */
2380+#undef HARDENING_PATCH_MM_PROTECT
2381+
2382+/* Linked List Protection */
2383+#undef HARDENING_PATCH_LL_PROTECT
2384+
2385+/* Linked List Protection */
2386+#undef HARDENING_PATCH_LL_PROTECT
2387+
2388+/* Include/Require Protection */
2389+#undef HARDENING_PATCH_INC_PROTECT
2390+
2391+/* Include/Require Protection */
2392+#undef HARDENING_PATCH_INC_PROTECT
2393+
2394+/* Fmt String Protection */
2395+#undef HARDENING_PATCH_FMT_PROTECT
2396+
2397+/* Fmt String Protection */
2398+#undef HARDENING_PATCH_FMT_PROTECT
2399+
2400+/* HashTable DTOR Protection */
2401+#undef HARDENING_PATCH_HASH_PROTECT
2402+
2403+/* HashTable DTOR Protection */
2404+#undef HARDENING_PATCH_HASH_PROTECT
2405+
2406 /* Whether you have AOLserver */
2407 #undef HAVE_AOLSERVER
2408
2409@@ -1143,6 +1176,12 @@
2410 /* Define if you have the getaddrinfo function */
2411 #undef HAVE_GETADDRINFO
2412
2413+/* Whether realpath is broken */
2414+#undef PHP_BROKEN_REALPATH
2415+
2416+/* Whether realpath is broken */
2417+#undef PHP_BROKEN_REALPATH
2418+
2419 /* Whether system headers declare timezone */
2420 #undef HAVE_DECLARED_TIMEZONE
2421
2422diff -Naur php-4.4.0RC2/main/php_content_types.c hardening-patch-4.4.0RC2-0.3.2/main/php_content_types.c
2423--- php-4.4.0RC2/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
2424+++ hardening-patch-4.4.0RC2-0.3.2/main/php_content_types.c 2005-07-09 08:53:20.657598232 +0200
2425@@ -77,6 +77,7 @@
2426 sapi_register_post_entries(php_post_entries);
2427 sapi_register_default_post_reader(php_default_post_reader);
2428 sapi_register_treat_data(php_default_treat_data);
2429+ sapi_register_input_filter(php_default_input_filter);
2430 return SUCCESS;
2431 }
2432 /* }}} */
2433diff -Naur php-4.4.0RC2/main/php.h hardening-patch-4.4.0RC2-0.3.2/main/php.h
2434--- php-4.4.0RC2/main/php.h 2005-04-17 15:37:29.000000000 +0200
2435+++ hardening-patch-4.4.0RC2-0.3.2/main/php.h 2005-07-09 08:53:20.657598232 +0200
2436@@ -26,7 +26,7 @@
2437 #include <dmalloc.h>
2438 #endif
2439
2440-#define PHP_API_VERSION 20020918
2441+#define PHP_API_VERSION 1020050626
2442 #define PHP_HAVE_STREAMS
2443 #define YYDEBUG 0
2444
2445@@ -35,11 +35,19 @@
2446 #include "zend_qsort.h"
2447 #include "php_compat.h"
2448
2449+
2450 #include "zend_API.h"
2451
2452 #undef sprintf
2453 #define sprintf php_sprintf
2454
2455+#if HARDENING_PATCH
2456+#if HAVE_REALPATH
2457+#undef realpath
2458+#define realpath php_realpath
2459+#endif
2460+#endif
2461+
2462 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
2463 #undef PHP_DEBUG
2464 #define PHP_DEBUG ZEND_DEBUG
2465@@ -435,6 +443,10 @@
2466 #endif
2467 #endif /* !XtOffsetOf */
2468
2469+#if HARDENING_PATCH
2470+#include "hardening_patch.h"
2471+#endif
2472+
2473 #endif
2474
2475 /*
2476diff -Naur php-4.4.0RC2/main/php_variables.c hardening-patch-4.4.0RC2-0.3.2/main/php_variables.c
2477--- php-4.4.0RC2/main/php_variables.c 2005-05-17 20:42:35.000000000 +0200
2478+++ hardening-patch-4.4.0RC2-0.3.2/main/php_variables.c 2005-07-09 08:53:20.658598080 +0200
2479@@ -225,17 +225,28 @@
2480 while (var) {
2481 val = strchr(var, '=');
2482 if (val) { /* have a value */
2483- int val_len;
2484+ unsigned int val_len, new_val_len;
2485
2486 *val++ = '\0';
2487 php_url_decode(var, strlen(var));
2488 val_len = php_url_decode(val, strlen(val));
2489- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
2490+ val = estrndup(val, val_len);
2491+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
2492+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
2493+ }
2494+ efree(val);
2495 }
2496 var = php_strtok_r(NULL, "&", &strtok_buf);
2497 }
2498 }
2499
2500+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
2501+{
2502+ /* TODO: check .ini setting here and apply user-defined input filter */
2503+ *new_val_len = val_len;
2504+ return 1;
2505+}
2506+
2507 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
2508 {
2509 char *res = NULL, *var, *val, *separator=NULL;
2510@@ -313,15 +324,26 @@
2511 while (var) {
2512 val = strchr(var, '=');
2513 if (val) { /* have a value */
2514- int val_len;
2515+ unsigned int val_len, new_val_len;
2516
2517 *val++ = '\0';
2518 php_url_decode(var, strlen(var));
2519 val_len = php_url_decode(val, strlen(val));
2520- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
2521+ val = estrndup(val, val_len);
2522+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
2523+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
2524+ }
2525+ efree(val);
2526 } else {
2527+ unsigned int val_len, new_val_len;
2528+
2529 php_url_decode(var, strlen(var));
2530- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
2531+ val_len = 0;
2532+ val = estrndup("", 0);
2533+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
2534+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
2535+ }
2536+ efree(val);
2537 }
2538 var = php_strtok_r(NULL, separator, &strtok_buf);
2539 }
2540diff -Naur php-4.4.0RC2/main/rfc1867.c hardening-patch-4.4.0RC2-0.3.2/main/rfc1867.c
2541--- php-4.4.0RC2/main/rfc1867.c 2005-04-04 16:59:58.000000000 +0200
2542+++ hardening-patch-4.4.0RC2-0.3.2/main/rfc1867.c 2005-07-09 08:53:20.659597928 +0200
2543@@ -127,6 +127,7 @@
2544 #define UPLOAD_ERROR_C 3 /* Partially uploaded */
2545 #define UPLOAD_ERROR_D 4 /* No file uploaded */
2546 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
2547+#define UPLOAD_ERROR_F 7 /* Filter forbids upload */
2548
2549 void php_rfc1867_register_constants(TSRMLS_D)
2550 {
2551@@ -136,6 +137,7 @@
2552 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_PARTIAL", UPLOAD_ERROR_C, CONST_CS | CONST_PERSISTENT);
2553 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
2554 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
2555+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
2556 }
2557
2558 static void normalize_protected_variable(char *varname TSRMLS_DC)
2559@@ -844,6 +846,7 @@
2560 char buff[FILLUNIT];
2561 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
2562 int blen=0, wlen=0;
2563+ unsigned long offset;
2564
2565 zend_llist_clean(&header);
2566
2567@@ -891,21 +894,24 @@
2568 if (!filename && param) {
2569
2570 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
2571+ unsigned int new_val_len; /* Dummy variable */
2572
2573 if (!value) {
2574 value = estrdup("");
2575 }
2576
2577+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
2578 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
2579- if (php_mb_encoding_translation(TSRMLS_C)) {
2580- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
2581- &num_vars, &num_vars_max TSRMLS_CC);
2582- } else {
2583- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
2584- }
2585+ if (php_mb_encoding_translation(TSRMLS_C)) {
2586+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
2587+ &num_vars, &num_vars_max TSRMLS_CC);
2588+ } else {
2589+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
2590+ }
2591 #else
2592- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
2593+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
2594 #endif
2595+ }
2596 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
2597 max_file_size = atol(value);
2598 }
2599@@ -981,6 +987,11 @@
2600 cancel_upload = UPLOAD_ERROR_D;
2601 }
2602
2603+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
2604+ cancel_upload = UPLOAD_ERROR_F;
2605+ }
2606+
2607+ offset = 0;
2608 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff) TSRMLS_CC)))
2609 {
2610 if (PG(upload_max_filesize) > 0 && total_bytes > PG(upload_max_filesize)) {
2611@@ -990,6 +1001,11 @@
2612 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
2613 cancel_upload = UPLOAD_ERROR_B;
2614 } else if (blen > 0) {
2615+
2616+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
2617+ cancel_upload = UPLOAD_ERROR_F;
2618+ }
2619+
2620 wlen = write(fd, buff, blen);
2621
2622 if (wlen < blen) {
2623@@ -997,6 +1013,7 @@
2624 cancel_upload = UPLOAD_ERROR_C;
2625 } else {
2626 total_bytes += wlen;
2627+ offset += wlen;
2628 }
2629 }
2630 }
2631@@ -1011,6 +1028,10 @@
2632 }
2633 #endif
2634
2635+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
2636+ cancel_upload = UPLOAD_ERROR_F;
2637+ }
2638+
2639 if (cancel_upload) {
2640 if (temp_filename) {
2641 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
2642diff -Naur php-4.4.0RC2/main/SAPI.c hardening-patch-4.4.0RC2-0.3.2/main/SAPI.c
2643--- php-4.4.0RC2/main/SAPI.c 2005-02-22 15:46:24.000000000 +0100
2644+++ hardening-patch-4.4.0RC2-0.3.2/main/SAPI.c 2005-07-09 08:53:20.659597928 +0200
2645@@ -831,6 +831,31 @@
2646 return SUCCESS;
2647 }
2648
2649+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))
2650+{
2651+ sapi_module.input_filter = input_filter;
2652+ return SUCCESS;
2653+}
2654+
2655+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
2656+{
2657+ sapi_module.pre_upload_filter = pre_upload_filter;
2658+ return SUCCESS;
2659+}
2660+
2661+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))
2662+{
2663+ sapi_module.upload_content_filter = upload_content_filter;
2664+ return SUCCESS;
2665+}
2666+
2667+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
2668+{
2669+ sapi_module.post_upload_filter = post_upload_filter;
2670+ return SUCCESS;
2671+}
2672+
2673+
2674
2675 SAPI_API int sapi_flush(TSRMLS_D)
2676 {
2677diff -Naur php-4.4.0RC2/main/SAPI.h hardening-patch-4.4.0RC2-0.3.2/main/SAPI.h
2678--- php-4.4.0RC2/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
2679+++ hardening-patch-4.4.0RC2-0.3.2/main/SAPI.h 2005-07-09 08:53:20.660597776 +0200
2680@@ -101,9 +101,10 @@
2681 char *current_user;
2682 int current_user_length;
2683
2684- /* this is necessary for CLI module */
2685- int argc;
2686- char **argv;
2687+ /* this is necessary for CLI module */
2688+ int argc;
2689+ char **argv;
2690+
2691 } sapi_request_info;
2692
2693
2694@@ -177,6 +178,10 @@
2695 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
2696 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
2697 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
2698+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));
2699+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
2700+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));
2701+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
2702
2703 SAPI_API int sapi_flush(TSRMLS_D);
2704 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
2705@@ -238,8 +243,15 @@
2706 int (*get_target_uid)(uid_t * TSRMLS_DC);
2707 int (*get_target_gid)(gid_t * TSRMLS_DC);
2708
2709+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
2710+
2711+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
2712+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
2713+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
2714+
2715 void (*ini_defaults)(HashTable *configuration_hash);
2716 int phpinfo_as_text;
2717+
2718 };
2719
2720
2721@@ -262,16 +274,26 @@
2722
2723 #define SAPI_DEFAULT_MIMETYPE "text/html"
2724 #define SAPI_DEFAULT_CHARSET ""
2725+
2726+#if HARDENING_PATCH
2727+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
2728+#else
2729 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
2730+#endif
2731
2732 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
2733 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
2734
2735 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
2736+#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)
2737+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
2738+#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)
2739+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
2740
2741 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
2742 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
2743 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
2744+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
2745
2746 #define STANDARD_SAPI_MODULE_PROPERTIES
2747
2748diff -Naur php-4.4.0RC2/main/snprintf.c hardening-patch-4.4.0RC2-0.3.2/main/snprintf.c
2749--- php-4.4.0RC2/main/snprintf.c 2005-04-08 07:44:53.000000000 +0200
2750+++ hardening-patch-4.4.0RC2-0.3.2/main/snprintf.c 2005-07-09 08:53:20.661597624 +0200
2751@@ -1013,7 +1013,11 @@
2752
2753
2754 case 'n':
2755+#if HARDENING_PATCH_FMT_PROTECT
2756+ php_security_log(S_MISC, "'n' specifier within format string");
2757+#else
2758 *(va_arg(ap, int *)) = cc;
2759+#endif
2760 break;
2761
2762 /*
2763diff -Naur php-4.4.0RC2/main/spprintf.c hardening-patch-4.4.0RC2-0.3.2/main/spprintf.c
2764--- php-4.4.0RC2/main/spprintf.c 2005-04-08 07:44:53.000000000 +0200
2765+++ hardening-patch-4.4.0RC2-0.3.2/main/spprintf.c 2005-07-09 08:53:20.661597624 +0200
2766@@ -630,7 +630,11 @@
2767
2768
2769 case 'n':
2770+#if HARDENING_PATCH_FMT_PROTECT
2771+ php_security_log(S_MISC, "'n' specifier within format string");
2772+#else
2773 *(va_arg(ap, int *)) = xbuf->len;
2774+#endif
2775 break;
2776
2777 /*
2778diff -Naur php-4.4.0RC2/php.ini-dist hardening-patch-4.4.0RC2-0.3.2/php.ini-dist
2779--- php-4.4.0RC2/php.ini-dist 2005-04-28 15:14:45.000000000 +0200
2780+++ hardening-patch-4.4.0RC2-0.3.2/php.ini-dist 2005-07-09 08:53:20.662597472 +0200
2781@@ -1112,6 +1112,177 @@
2782 ;exif.decode_jis_motorola = JIS
2783 ;exif.decode_jis_intel = JIS
2784
2785+[hardening-patch]
2786+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2787+; Hardening-Patch's logging ;
2788+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2789+
2790+;
2791+; hphp.log.syslog - Configures level for alerts reported through syslog
2792+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
2793+; hphp.log.script - Configures level for alerts reported through external script
2794+;
2795+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
2796+; Or each number up to get desired Hardening-Patch's reporting level
2797+;
2798+; S_ALL - All alerts
2799+; S_MEMORY - All canary violations and the safe unlink protection use this class
2800+; S_VARS - All variable filters trigger this class
2801+; S_FILES - All violation of uploaded files filter use this class
2802+; S_INCLUDE - The protection against malicious include filenames use this class
2803+; S_SQL - Failed SQL queries in MySQL are logged with this class
2804+; S_EXECUTOR - The execution depth protection uses this logging class
2805+; S_MISC - All other log messages (f.e. format string protection) use this class
2806+;
2807+; Example:
2808+;
2809+; - Report all alerts (except memory alerts) to the SAPI errorlog,
2810+; memory alerts through syslog and SQL+Include alerts fo the script
2811+;
2812+;hphp.log.syslog = S_MEMORY
2813+;hphp.log.sapi = S_ALL & ~S_MEMORY
2814+;hphp.log.script = S_INCLUDE | S_SQL
2815+;
2816+; Syslog logging:
2817+;
2818+; - Facility configuration: one of the following facilities
2819+;
2820+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
2821+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
2822+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
2823+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
2824+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
2825+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
2826+; LOG_PERROR
2827+;
2828+; - Priority configuration: one of the followinf priorities
2829+;
2830+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
2831+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
2832+;
2833+hphp.log.syslog.priority = LOG_ALERT
2834+hphp.log.syslog.facility = LOG_USER
2835+;
2836+; Script logging:
2837+;
2838+;hphp.log.script.name = /home/hphp/log_script
2839+;
2840+; Alert configuration:
2841+;
2842+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
2843+;
2844+;hphp.log.use-x-forwarded-for = On
2845+;
2846+
2847+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2848+; Hardening-Patch's logging ;
2849+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2850+
2851+; Execution depth limit
2852+;hphp.executor.max_depth = 8000
2853+
2854+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2855+; Hardening-Patch's REQUEST variable filters ;
2856+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2857+
2858+; Limits the number of REQUEST variables
2859+hphp.request.max_vars = 200
2860+
2861+; Limits the length of variable names (without indices)
2862+hphp.request.max_varname_length = 64
2863+
2864+; Limits the length of complete variable names (with indices)
2865+hphp.request.max_totalname_length = 256
2866+
2867+; Limits the length of array indices
2868+hphp.request.max_array_index_length = 64
2869+
2870+; Limits the depth of arrays
2871+hphp.request.max_array_depth = 100
2872+
2873+; Limits the length of variable values
2874+hphp.request.max_value_length = 65000
2875+
2876+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2877+; Hardening-Patch's COOKIE variable filters ;
2878+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2879+
2880+; Limits the number of COOKIE variables
2881+hphp.cookie.max_vars = 100
2882+
2883+; Limits the length of variable names (without indices)
2884+hphp.cookie.max_name_length = 64
2885+
2886+; Limits the length of complete variable names (with indices)
2887+hphp.cookie.max_totalname_length = 256
2888+
2889+; Limits the length of array indices
2890+hphp.cookie.max_array_index_length = 64
2891+
2892+; Limits the depth of arrays
2893+hphp.cookie.max_array_depth = 100
2894+
2895+; Limits the length of variable values
2896+hphp.cookie.max_value_length = 10000
2897+
2898+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2899+; Hardening-Patch's GET variable filters ;
2900+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2901+
2902+; Limits the number of COOKIE variables
2903+hphp.get.max_vars = 100
2904+
2905+; Limits the length of variable names (without indices)
2906+hphp.get.max_name_length = 64
2907+
2908+; Limits the length of complete variable names (with indices)
2909+hphp.get.max_totalname_length = 256
2910+
2911+; Limits the length of array indices
2912+hphp.get.max_array_index_length = 64
2913+
2914+; Limits the depth of arrays
2915+hphp.get.max_array_depth = 50
2916+
2917+; Limits the length of variable values
2918+hphp.get.max_value_length = 512
2919+
2920+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2921+; Hardening-Patch's POST variable filters ;
2922+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2923+
2924+; Limits the number of POST variables
2925+hphp.post.max_vars = 200
2926+
2927+; Limits the length of variable names (without indices)
2928+hphp.post.max_name_length = 64
2929+
2930+; Limits the length of complete variable names (with indices)
2931+hphp.post.max_totalname_length = 256
2932+
2933+; Limits the length of array indices
2934+hphp.post.max_array_index_length = 64
2935+
2936+; Limits the depth of arrays
2937+hphp.post.max_array_depth = 100
2938+
2939+; Limits the length of variable values
2940+hphp.post.max_value_length = 65000
2941+
2942+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2943+; Hardening-Patch's fileupload variable filters ;
2944+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2945+
2946+; Limits the number of uploadable files
2947+hphp.upload.max_uploads = 25
2948+
2949+; Filter out the upload of ELF executables
2950+hphp.upload.disallow_elf_files = On
2951+
2952+; External filterscript for upload verification
2953+;hphp.upload.verification_script = /home/hphp/verify_script
2954+
2955+
2956 ; Local Variables:
2957 ; tab-width: 4
2958 ; End:
2959diff -Naur php-4.4.0RC2/php.ini-recommended hardening-patch-4.4.0RC2-0.3.2/php.ini-recommended
2960--- php-4.4.0RC2/php.ini-recommended 2005-04-28 15:14:46.000000000 +0200
2961+++ hardening-patch-4.4.0RC2-0.3.2/php.ini-recommended 2005-07-09 08:53:20.663597320 +0200
2962@@ -1110,6 +1110,177 @@
2963 ;exif.decode_jis_motorola = JIS
2964 ;exif.decode_jis_intel = JIS
2965
2966+[hardening-patch]
2967+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2968+; Hardening-Patch's logging ;
2969+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2970+
2971+;
2972+; hphp.log.syslog - Configures level for alerts reported through syslog
2973+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
2974+; hphp.log.script - Configures level for alerts reported through external script
2975+;
2976+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
2977+; Or each number up to get desired Hardening-Patch's reporting level
2978+;
2979+; S_ALL - All alerts
2980+; S_MEMORY - All canary violations and the safe unlink protection use this class
2981+; S_VARS - All variable filters trigger this class
2982+; S_FILES - All violation of uploaded files filter use this class
2983+; S_INCLUDE - The protection against malicious include filenames use this class
2984+; S_SQL - Failed SQL queries in MySQL are logged with this class
2985+; S_EXECUTOR - The execution depth protection uses this logging class
2986+; S_MISC - All other log messages (f.e. format string protection) use this class
2987+;
2988+; Example:
2989+;
2990+; - Report all alerts (except memory alerts) to the SAPI errorlog,
2991+; memory alerts through syslog and SQL+Include alerts fo the script
2992+;
2993+;hphp.log.syslog = S_MEMORY
2994+;hphp.log.sapi = S_ALL & ~S_MEMORY
2995+;hphp.log.script = S_INCLUDE | S_SQL
2996+;
2997+; Syslog logging:
2998+;
2999+; - Facility configuration: one of the following facilities
3000+;
3001+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
3002+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
3003+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
3004+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
3005+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
3006+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
3007+; LOG_PERROR
3008+;
3009+; - Priority configuration: one of the followinf priorities
3010+;
3011+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
3012+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
3013+;
3014+hphp.log.syslog.priority = LOG_ALERT
3015+hphp.log.syslog.facility = LOG_USER
3016+;
3017+; Script logging:
3018+;
3019+;hphp.log.script.name = /home/hphp/log_script
3020+;
3021+; Alert configuration:
3022+;
3023+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
3024+;
3025+;hphp.log.use-x-forwarded-for = On
3026+;
3027+
3028+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3029+; Hardening-Patch's logging ;
3030+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3031+
3032+; Execution depth limit
3033+;hphp.executor.max_depth = 8000
3034+
3035+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3036+; Hardening-Patch's REQUEST variable filters ;
3037+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3038+
3039+; Limits the number of REQUEST variables
3040+hphp.request.max_vars = 200
3041+
3042+; Limits the length of variable names (without indices)
3043+hphp.request.max_varname_length = 64
3044+
3045+; Limits the length of complete variable names (with indices)
3046+hphp.request.max_totalname_length = 256
3047+
3048+; Limits the length of array indices
3049+hphp.request.max_array_index_length = 64
3050+
3051+; Limits the depth of arrays
3052+hphp.request.max_array_depth = 100
3053+
3054+; Limits the length of variable values
3055+hphp.request.max_value_length = 65000
3056+
3057+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3058+; Hardening-Patch's COOKIE variable filters ;
3059+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3060+
3061+; Limits the number of COOKIE variables
3062+hphp.cookie.max_vars = 100
3063+
3064+; Limits the length of variable names (without indices)
3065+hphp.cookie.max_name_length = 64
3066+
3067+; Limits the length of complete variable names (with indices)
3068+hphp.cookie.max_totalname_length = 256
3069+
3070+; Limits the length of array indices
3071+hphp.cookie.max_array_index_length = 64
3072+
3073+; Limits the depth of arrays
3074+hphp.cookie.max_array_depth = 100
3075+
3076+; Limits the length of variable values
3077+hphp.cookie.max_value_length = 10000
3078+
3079+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3080+; Hardening-Patch's GET variable filters ;
3081+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3082+
3083+; Limits the number of COOKIE variables
3084+hphp.get.max_vars = 100
3085+
3086+; Limits the length of variable names (without indices)
3087+hphp.get.max_name_length = 64
3088+
3089+; Limits the length of complete variable names (with indices)
3090+hphp.get.max_totalname_length = 256
3091+
3092+; Limits the length of array indices
3093+hphp.get.max_array_index_length = 64
3094+
3095+; Limits the depth of arrays
3096+hphp.get.max_array_depth = 50
3097+
3098+; Limits the length of variable values
3099+hphp.get.max_value_length = 512
3100+
3101+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3102+; Hardening-Patch's POST variable filters ;
3103+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3104+
3105+; Limits the number of POST variables
3106+hphp.post.max_vars = 200
3107+
3108+; Limits the length of variable names (without indices)
3109+hphp.post.max_name_length = 64
3110+
3111+; Limits the length of complete variable names (with indices)
3112+hphp.post.max_totalname_length = 256
3113+
3114+; Limits the length of array indices
3115+hphp.post.max_array_index_length = 64
3116+
3117+; Limits the depth of arrays
3118+hphp.post.max_array_depth = 100
3119+
3120+; Limits the length of variable values
3121+hphp.post.max_value_length = 65000
3122+
3123+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3124+; Hardening-Patch's fileupload variable filters ;
3125+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3126+
3127+; Limits the number of uploadable files
3128+hphp.upload.max_uploads = 25
3129+
3130+; Filter out the upload of ELF executables
3131+hphp.upload.disallow_elf_files = On
3132+
3133+; External filterscript for upload verification
3134+;hphp.upload.verification_script = /home/hphp/verify_script
3135+
3136+
3137 ; Local Variables:
3138 ; tab-width: 4
3139 ; End:
3140diff -Naur php-4.4.0RC2/README.input_filter hardening-patch-4.4.0RC2-0.3.2/README.input_filter
3141--- php-4.4.0RC2/README.input_filter 1970-01-01 01:00:00.000000000 +0100
3142+++ hardening-patch-4.4.0RC2-0.3.2/README.input_filter 2005-07-09 08:53:20.664597168 +0200
3143@@ -0,0 +1,193 @@
3144+Input Filter Support ported from PHP 5
3145+--------------------------------------
3146+
3147+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
3148+and can be quite difficult to prevent. Whenever you accept user data
3149+and somehow display this data back to users, you are likely vulnerable
3150+to XSS hacks.
3151+
3152+The Input Filter support in PHP 5 is aimed at providing the framework
3153+through which a company-wide or site-wide security policy can be
3154+enforced. It is implemented as a SAPI hook and is called from the
3155+treat_data and post handler functions. To implement your own security
3156+policy you will need to write a standard PHP extension.
3157+
3158+A simple implementation might look like the following. This stores the
3159+original raw user data and adds a my_get_raw() function while the normal
3160+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
3161+data. In this simple example all I am doing is calling strip_tags() on
3162+the data. If register_globals is turned on, the default globals that
3163+are created will be stripped ($foo) while a $RAW_foo is created with the
3164+original user input.
3165+
3166+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
3167+ zval *post_array;
3168+ zval *get_array;
3169+ zval *cookie_array;
3170+ZEND_END_MODULE_GLOBALS(my_input_filter)
3171+
3172+#ifdef ZTS
3173+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
3174+#else
3175+#define IF_G(v) (my_input_filter_globals.v)
3176+#endif
3177+
3178+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
3179+
3180+function_entry my_input_filter_functions[] = {
3181+ PHP_FE(my_get_raw, NULL)
3182+ {NULL, NULL, NULL}
3183+};
3184+
3185+zend_module_entry my_input_filter_module_entry = {
3186+ STANDARD_MODULE_HEADER,
3187+ "my_input_filter",
3188+ my_input_filter_functions,
3189+ PHP_MINIT(my_input_filter),
3190+ PHP_MSHUTDOWN(my_input_filter),
3191+ NULL,
3192+ PHP_RSHUTDOWN(my_input_filter),
3193+ PHP_MINFO(my_input_filter),
3194+ "0.1",
3195+ STANDARD_MODULE_PROPERTIES
3196+};
3197+
3198+PHP_MINIT_FUNCTION(my_input_filter)
3199+{
3200+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
3201+
3202+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
3203+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
3204+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
3205+
3206+ sapi_register_input_filter(my_sapi_input_filter);
3207+ return SUCCESS;
3208+}
3209+
3210+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
3211+{
3212+ if(IF_G(get_array)) {
3213+ zval_ptr_dtor(&IF_G(get_array));
3214+ IF_G(get_array) = NULL;
3215+ }
3216+ if(IF_G(post_array)) {
3217+ zval_ptr_dtor(&IF_G(post_array));
3218+ IF_G(post_array) = NULL;
3219+ }
3220+ if(IF_G(cookie_array)) {
3221+ zval_ptr_dtor(&IF_G(cookie_array));
3222+ IF_G(cookie_array) = NULL;
3223+ }
3224+ return SUCCESS;
3225+}
3226+
3227+PHP_MINFO_FUNCTION(my_input_filter)
3228+{
3229+ php_info_print_table_start();
3230+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
3231+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
3232+ php_info_print_table_end();
3233+}
3234+
3235+/* The filter handler. If you return 1 from it, then PHP also registers the
3236+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
3237+ * you can use this if your filter already registers the variable under a
3238+ * different name, or if you just don't want the variable registered at all. */
3239+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
3240+{
3241+ zval new_var;
3242+ zval *array_ptr = NULL;
3243+ char *raw_var;
3244+ int var_len;
3245+
3246+ assert(*val != NULL);
3247+
3248+ switch(arg) {
3249+ case PARSE_GET:
3250+ if(!IF_G(get_array)) {
3251+ ALLOC_ZVAL(array_ptr);
3252+ array_init(array_ptr);
3253+ INIT_PZVAL(array_ptr);
3254+ }
3255+ IF_G(get_array) = array_ptr;
3256+ break;
3257+ case PARSE_POST:
3258+ if(!IF_G(post_array)) {
3259+ ALLOC_ZVAL(array_ptr);
3260+ array_init(array_ptr);
3261+ INIT_PZVAL(array_ptr);
3262+ }
3263+ IF_G(post_array) = array_ptr;
3264+ break;
3265+ case PARSE_COOKIE:
3266+ if(!IF_G(cookie_array)) {
3267+ ALLOC_ZVAL(array_ptr);
3268+ array_init(array_ptr);
3269+ INIT_PZVAL(array_ptr);
3270+ }
3271+ IF_G(cookie_array) = array_ptr;
3272+ break;
3273+ }
3274+ Z_STRLEN(new_var) = val_len;
3275+ Z_STRVAL(new_var) = estrndup(*val, val_len);
3276+ Z_TYPE(new_var) = IS_STRING;
3277+
3278+ var_len = strlen(var);
3279+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
3280+ strcpy(raw_var, "RAW_");
3281+ strlcat(raw_var,var,var_len+5);
3282+
3283+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
3284+
3285+ php_strip_tags(*val, val_len, NULL, NULL, 0);
3286+
3287+ *new_val_len = strlen(*val);
3288+ return 1;
3289+}
3290+
3291+PHP_FUNCTION(my_get_raw)
3292+{
3293+ long arg;
3294+ char *var;
3295+ int var_len;
3296+ zval **tmp;
3297+ zval *array_ptr = NULL;
3298+ HashTable *hash_ptr;
3299+ char *raw_var;
3300+
3301+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
3302+ return;
3303+ }
3304+
3305+ switch(arg) {
3306+ case PARSE_GET:
3307+ array_ptr = IF_G(get_array);
3308+ break;
3309+ case PARSE_POST:
3310+ array_ptr = IF_G(post_array);
3311+ break;
3312+ case PARSE_COOKIE:
3313+ array_ptr = IF_G(post_array);
3314+ break;
3315+ }
3316+
3317+ if(!array_ptr) RETURN_FALSE;
3318+
3319+ /*
3320+ * I'm changing the variable name here because when running with register_globals on,
3321+ * the variable will end up in the global symbol table
3322+ */
3323+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
3324+ strcpy(raw_var, "RAW_");
3325+ strlcat(raw_var,var,var_len+5);
3326+ hash_ptr = HASH_OF(array_ptr);
3327+
3328+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
3329+ *return_value = **tmp;
3330+ zval_copy_ctor(return_value);
3331+ } else {
3332+ RETVAL_FALSE;
3333+ }
3334+ efree(raw_var);
3335+}
3336+
3337diff -Naur php-4.4.0RC2/sapi/apache/mod_php4.c hardening-patch-4.4.0RC2-0.3.2/sapi/apache/mod_php4.c
3338--- php-4.4.0RC2/sapi/apache/mod_php4.c 2005-05-19 18:14:46.000000000 +0200
3339+++ hardening-patch-4.4.0RC2-0.3.2/sapi/apache/mod_php4.c 2005-07-09 08:53:20.665597016 +0200
3340@@ -452,7 +452,7 @@
3341 sapi_apache_get_fd,
3342 sapi_apache_force_http_10,
3343 sapi_apache_get_target_uid,
3344- sapi_apache_get_target_gid
3345+ sapi_apache_get_target_gid,
3346 };
3347 /* }}} */
3348
3349@@ -898,7 +898,11 @@
3350 {
3351 TSRMLS_FETCH();
3352 if (PG(expose_php)) {
3353+#if HARDENING_PATCH
3354+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
3355+#else
3356 ap_add_version_component("PHP/" PHP_VERSION);
3357+#endif
3358 }
3359 }
3360 #endif
3361diff -Naur php-4.4.0RC2/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.0RC2-0.3.2/sapi/apache2filter/sapi_apache2.c
3362--- php-4.4.0RC2/sapi/apache2filter/sapi_apache2.c 2005-04-08 22:35:02.000000000 +0200
3363+++ hardening-patch-4.4.0RC2-0.3.2/sapi/apache2filter/sapi_apache2.c 2005-07-09 08:53:20.665597016 +0200
3364@@ -556,7 +556,11 @@
3365 {
3366 TSRMLS_FETCH();
3367 if (PG(expose_php)) {
3368+#if HARDENING_PATCH
3369+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
3370+#else
3371 ap_add_version_component(p, "PHP/" PHP_VERSION);
3372+#endif
3373 }
3374 }
3375
3376diff -Naur php-4.4.0RC2/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.0RC2-0.3.2/sapi/apache2handler/sapi_apache2.c
3377--- php-4.4.0RC2/sapi/apache2handler/sapi_apache2.c 2005-04-08 22:35:02.000000000 +0200
3378+++ hardening-patch-4.4.0RC2-0.3.2/sapi/apache2handler/sapi_apache2.c 2005-07-09 08:53:20.666596864 +0200
3379@@ -340,7 +340,11 @@
3380 {
3381 TSRMLS_FETCH();
3382 if (PG(expose_php)) {
3383+#if HARDENING_PATCH
3384+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
3385+#else
3386 ap_add_version_component(p, "PHP/" PHP_VERSION);
3387+#endif
3388 }
3389 }
3390
3391diff -Naur php-4.4.0RC2/sapi/cgi/cgi_main.c hardening-patch-4.4.0RC2-0.3.2/sapi/cgi/cgi_main.c
3392--- php-4.4.0RC2/sapi/cgi/cgi_main.c 2005-04-28 16:24:47.000000000 +0200
3393+++ hardening-patch-4.4.0RC2-0.3.2/sapi/cgi/cgi_main.c 2005-07-09 08:53:20.667596712 +0200
3394@@ -1440,11 +1440,19 @@
3395 SG(headers_sent) = 1;
3396 SG(request_info).no_headers = 1;
3397 }
3398+#if HARDENING_PATCH
3399+#if ZEND_DEBUG
3400+ 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());
3401+#else
3402+ 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());
3403+#endif
3404+#else
3405 #if ZEND_DEBUG
3406 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());
3407 #else
3408 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());
3409 #endif
3410+#endif
3411 php_end_ob_buffers(1 TSRMLS_CC);
3412 exit(1);
3413 break;
3414diff -Naur php-4.4.0RC2/sapi/cli/php_cli.c hardening-patch-4.4.0RC2-0.3.2/sapi/cli/php_cli.c
3415--- php-4.4.0RC2/sapi/cli/php_cli.c 2005-03-22 16:09:36.000000000 +0100
3416+++ hardening-patch-4.4.0RC2-0.3.2/sapi/cli/php_cli.c 2005-07-09 08:53:20.667596712 +0200
3417@@ -652,11 +652,19 @@
3418 if (php_request_startup(TSRMLS_C)==FAILURE) {
3419 goto err;
3420 }
3421+#if HARDENING_PATCH
3422+#if ZEND_DEBUG
3423+ 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());
3424+#else
3425+ 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());
3426+#endif
3427+#else
3428 #if ZEND_DEBUG
3429 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());
3430 #else
3431 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());
3432 #endif
3433+#endif
3434 php_end_ob_buffers(1 TSRMLS_CC);
3435 exit_status=1;
3436 goto out;
3437diff -Naur php-4.4.0RC2/TSRM/TSRM.h hardening-patch-4.4.0RC2-0.3.2/TSRM/TSRM.h
3438--- php-4.4.0RC2/TSRM/TSRM.h 2005-02-11 04:34:04.000000000 +0100
3439+++ hardening-patch-4.4.0RC2-0.3.2/TSRM/TSRM.h 2005-07-09 08:53:20.668596560 +0200
3440@@ -33,6 +33,13 @@
3441 # define TSRM_API
3442 #endif
3443
3444+#if HARDENING_PATCH
3445+# if HAVE_REALPATH
3446+# undef realpath
3447+# define realpath php_realpath
3448+# endif
3449+#endif
3450+
3451 /* Only compile multi-threading functions if we're in ZTS mode */
3452 #ifdef ZTS
3453
3454@@ -90,6 +97,7 @@
3455
3456 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
3457
3458+
3459 #ifdef __cplusplus
3460 extern "C" {
3461 #endif
3462diff -Naur php-4.4.0RC2/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.0RC2-0.3.2/TSRM/tsrm_virtual_cwd.c
3463--- php-4.4.0RC2/TSRM/tsrm_virtual_cwd.c 2005-02-11 04:34:04.000000000 +0100
3464+++ hardening-patch-4.4.0RC2-0.3.2/TSRM/tsrm_virtual_cwd.c 2005-07-09 08:53:20.669596408 +0200
3465@@ -192,6 +192,165 @@
3466 return p;
3467 }
3468
3469+#if HARDENING_PATCH
3470+CWD_API char *php_realpath(const char *path, char *resolved)
3471+{
3472+ struct stat sb;
3473+ char *p, *q, *s;
3474+ size_t left_len, resolved_len;
3475+ unsigned symlinks;
3476+ int serrno, slen;
3477+ int is_dir = 1;
3478+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
3479+
3480+ serrno = errno;
3481+ symlinks = 0;
3482+ if (path[0] == '/') {
3483+ resolved[0] = '/';
3484+ resolved[1] = '\0';
3485+ if (path[1] == '\0')
3486+ return (resolved);
3487+ resolved_len = 1;
3488+ left_len = strlcpy(left, path + 1, sizeof(left));
3489+ } else {
3490+ if (getcwd(resolved, PATH_MAX) == NULL) {
3491+ strlcpy(resolved, ".", PATH_MAX);
3492+ return (NULL);
3493+ }
3494+ resolved_len = strlen(resolved);
3495+ left_len = strlcpy(left, path, sizeof(left));
3496+ }
3497+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
3498+ errno = ENAMETOOLONG;
3499+ return (NULL);
3500+ }
3501+
3502+ /*
3503+ * Iterate over path components in `left'.
3504+ */
3505+ while (left_len != 0) {
3506+ /*
3507+ * Extract the next path component and adjust `left'
3508+ * and its length.
3509+ */
3510+ p = strchr(left, '/');
3511+ s = p ? p : left + left_len;
3512+ if (s - left >= sizeof(next_token)) {
3513+ errno = ENAMETOOLONG;
3514+ return (NULL);
3515+ }
3516+ memcpy(next_token, left, s - left);
3517+ next_token[s - left] = '\0';
3518+ left_len -= s - left;
3519+ if (p != NULL)
3520+ memmove(left, s + 1, left_len + 1);
3521+ if (resolved[resolved_len - 1] != '/') {
3522+ if (resolved_len + 1 >= PATH_MAX) {
3523+ errno = ENAMETOOLONG;
3524+ return (NULL);
3525+ }
3526+ resolved[resolved_len++] = '/';
3527+ resolved[resolved_len] = '\0';
3528+ }
3529+ if (next_token[0] == '\0')
3530+ continue;
3531+ else if (strcmp(next_token, ".") == 0)
3532+ continue;
3533+ else if (strcmp(next_token, "..") == 0) {
3534+ /*
3535+ * Strip the last path component except when we have
3536+ * single "/"
3537+ */
3538+ if (!is_dir) {
3539+ errno = ENOENT;
3540+ return (NULL);
3541+ }
3542+ if (resolved_len > 1) {
3543+ resolved[resolved_len - 1] = '\0';
3544+ q = strrchr(resolved, '/');
3545+ *q = '\0';
3546+ resolved_len = q - resolved;
3547+ }
3548+ continue;
3549+ }
3550+
3551+ /*
3552+ * Append the next path component and lstat() it. If
3553+ * lstat() fails we still can return successfully if
3554+ * there are no more path components left.
3555+ */
3556+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
3557+ if (resolved_len >= PATH_MAX) {
3558+ errno = ENAMETOOLONG;
3559+ return (NULL);
3560+ }
3561+ if (lstat(resolved, &sb) != 0) {
3562+ if (errno == ENOENT && p == NULL) {
3563+ errno = serrno;
3564+ return (resolved);
3565+ }
3566+ return (NULL);
3567+ }
3568+ if (S_ISLNK(sb.st_mode)) {
3569+ if (symlinks++ > MAXSYMLINKS) {
3570+ errno = ELOOP;
3571+ return (NULL);
3572+ }
3573+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
3574+ if (slen < 0)
3575+ return (NULL);
3576+ symlink[slen] = '\0';
3577+ if (symlink[0] == '/') {
3578+ resolved[1] = 0;
3579+ resolved_len = 1;
3580+ } else if (resolved_len > 1) {
3581+ /* Strip the last path component. */
3582+ resolved[resolved_len - 1] = '\0';
3583+ q = strrchr(resolved, '/');
3584+ *q = '\0';
3585+ resolved_len = q - resolved;
3586+ }
3587+
3588+ /*
3589+ * If there are any path components left, then
3590+ * append them to symlink. The result is placed
3591+ * in `left'.
3592+ */
3593+ if (p != NULL) {
3594+ if (symlink[slen - 1] != '/') {
3595+ if (slen + 1 >= sizeof(symlink)) {
3596+ errno = ENAMETOOLONG;
3597+ return (NULL);
3598+ }
3599+ symlink[slen] = '/';
3600+ symlink[slen + 1] = 0;
3601+ }
3602+ left_len = strlcat(symlink, left, sizeof(left));
3603+ if (left_len >= sizeof(left)) {
3604+ errno = ENAMETOOLONG;
3605+ return (NULL);
3606+ }
3607+ }
3608+ left_len = strlcpy(left, symlink, sizeof(left));
3609+ } else {
3610+ if (S_ISDIR(sb.st_mode)) {
3611+ is_dir = 1;
3612+ } else {
3613+ is_dir = 0;
3614+ }
3615+ }
3616+ }
3617+
3618+ /*
3619+ * Remove trailing slash except when the resolved pathname
3620+ * is a single "/".
3621+ */
3622+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
3623+ resolved[resolved_len - 1] = '\0';
3624+ return (resolved);
3625+}
3626+#endif
3627+
3628 CWD_API void virtual_cwd_startup(void)
3629 {
3630 char cwd[MAXPATHLEN];
3631@@ -314,8 +473,7 @@
3632 path = resolved_path;
3633 path_length = strlen(path);
3634 } else {
3635- /* disable for now
3636- return 1; */
3637+ return 1;
3638 }
3639 }
3640 } else { /* Concat current directory with relative path and then run realpath() on it */
3641@@ -341,9 +499,8 @@
3642 path = resolved_path;
3643 path_length = strlen(path);
3644 } else {
3645- /* disable for now
3646 free(tmp);
3647- return 1; */
3648+ return 1;
3649 }
3650 }
3651 free(tmp);
3652diff -Naur php-4.4.0RC2/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.0RC2-0.3.2/TSRM/tsrm_virtual_cwd.h
3653--- php-4.4.0RC2/TSRM/tsrm_virtual_cwd.h 2005-02-11 04:34:04.000000000 +0100
3654+++ hardening-patch-4.4.0RC2-0.3.2/TSRM/tsrm_virtual_cwd.h 2005-07-09 08:53:20.669596408 +0200
3655@@ -128,6 +128,22 @@
3656
3657 typedef int (*verify_path_func)(const cwd_state *);
3658
3659+#ifndef HAVE_STRLCPY
3660+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
3661+#undef strlcpy
3662+#define strlcpy php_strlcpy
3663+#endif
3664+
3665+#ifndef HAVE_STRLCAT
3666+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
3667+#undef strlcat
3668+#define strlcat php_strlcat
3669+#endif
3670+
3671+
3672+#if HARDENING_PATCH
3673+CWD_API char *php_realpath(const char *path, char *resolved);
3674+#endif
3675 CWD_API void virtual_cwd_startup(void);
3676 CWD_API void virtual_cwd_shutdown(void);
3677 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
3678diff -Naur php-4.4.0RC2/Zend/zend_alloc.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_alloc.c
3679--- php-4.4.0RC2/Zend/zend_alloc.c 2005-04-07 22:54:33.000000000 +0200
3680+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_alloc.c 2005-07-09 08:53:20.670596256 +0200
3681@@ -56,6 +56,11 @@
3682 # define END_MAGIC_SIZE 0
3683 #endif
3684
3685+#if HARDENING_PATCH_MM_PROTECT
3686+# define CANARY_SIZE sizeof(unsigned int)
3687+#else
3688+# define CANARY_SIZE 0
3689+#endif
3690
3691 # if MEMORY_LIMIT
3692 # if ZEND_DEBUG
3693@@ -95,9 +100,17 @@
3694 if (p==AG(head)) { \
3695 AG(head) = p->pNext; \
3696 } else { \
3697+ if (p != p->pLast->pNext) { \
3698+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
3699+ exit(1); \
3700+ } \
3701 p->pLast->pNext = p->pNext; \
3702 } \
3703 if (p->pNext) { \
3704+ if (p != p->pNext->pLast) { \
3705+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
3706+ exit(1); \
3707+ } \
3708 p->pNext->pLast = p->pLast; \
3709 }
3710
3711@@ -129,6 +142,12 @@
3712 DECLARE_CACHE_VARS();
3713 TSRMLS_FETCH();
3714
3715+#if HARDENING_PATCH_MM_PROTECT
3716+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
3717+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
3718+ exit(1);
3719+ }
3720+#endif
3721 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
3722
3723 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
3724@@ -146,6 +165,10 @@
3725 AG(cache_stats)[CACHE_INDEX][1]++;
3726 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
3727 #endif
3728+#if HARDENING_PATCH_MM_PROTECT
3729+ p->canary = HG(canary_1);
3730+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
3731+#endif
3732 p->cached = 0;
3733 p->size = size;
3734 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
3735@@ -161,7 +184,7 @@
3736 AG(allocated_memory_peak) = AG(allocated_memory);
3737 }
3738 #endif
3739- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
3740+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
3741 }
3742
3743 HANDLE_BLOCK_INTERRUPTIONS();
3744@@ -191,7 +214,10 @@
3745 # endif
3746 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
3747 #endif
3748-
3749+#if HARDENING_PATCH_MM_PROTECT
3750+ p->canary = HG(canary_1);
3751+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
3752+#endif
3753 HANDLE_UNBLOCK_INTERRUPTIONS();
3754 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
3755 }
3756@@ -218,17 +244,33 @@
3757 return emalloc_rel(lval + offset);
3758 }
3759 }
3760-
3761+
3762+#if HARDENING_PATCH
3763+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
3764+#endif
3765 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
3766 return 0;
3767 }
3768
3769 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
3770 {
3771+#if HARDENING_PATCH_MM_PROTECT
3772+ unsigned int *canary_2;
3773+#endif
3774 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
3775 DECLARE_CACHE_VARS();
3776 TSRMLS_FETCH();
3777
3778+#if HARDENING_PATCH_MM_PROTECT
3779+ canary_2 = (unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
3780+ if (p->canary != HG(canary_1) || *canary_2 != HG(canary_2)) {
3781+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
3782+ exit(1);
3783+ }
3784+ /* to catch double efree()s */
3785+ *canary_2 = p->canary = 0;
3786+#endif
3787+
3788 #if defined(ZTS) && TSRM_DEBUG
3789 if (p->thread_id != tsrm_thread_id()) {
3790 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
3791@@ -273,6 +315,9 @@
3792 size_t _size = nmemb * size;
3793
3794 if (nmemb && (_size/nmemb!=size)) {
3795+#if HARDENING_PATCH
3796+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
3797+#endif
3798 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
3799 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
3800 kill(getpid(), SIGSEGV);
3801@@ -292,6 +337,9 @@
3802
3803 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
3804 {
3805+#if HARDENING_PATCH_MM_PROTECT
3806+ unsigned int canary_2;
3807+#endif
3808 zend_mem_header *p;
3809 zend_mem_header *orig;
3810 DECLARE_CACHE_VARS();
3811@@ -303,6 +351,14 @@
3812
3813 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
3814
3815+#if HARDENING_PATCH_MM_PROTECT
3816+ canary_2 = *(unsigned int *)(((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE);
3817+ if (p->canary != HG(canary_1) || canary_2 != HG(canary_2)) {
3818+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
3819+ exit(1);
3820+ }
3821+#endif
3822+
3823 #if defined(ZTS) && TSRM_DEBUG
3824 if (p->thread_id != tsrm_thread_id()) {
3825 void *new_p;
3826@@ -326,7 +382,7 @@
3827 }
3828 #endif
3829 REMOVE_POINTER_FROM_LIST(p);
3830- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
3831+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
3832 if (!p) {
3833 if (!allow_failure) {
3834 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
3835@@ -348,6 +404,9 @@
3836 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
3837 #endif
3838
3839+#if HARDENING_PATCH_MM_PROTECT
3840+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
3841+#endif
3842 p->size = size;
3843
3844 HANDLE_UNBLOCK_INTERRUPTIONS();
3845@@ -422,6 +481,10 @@
3846 {
3847 AG(head) = NULL;
3848
3849+#if HARDENING_PATCH_MM_PROTECT
3850+ HG(canary_1) = zend_canary();
3851+ HG(canary_2) = zend_canary();
3852+#endif
3853 #if MEMORY_LIMIT
3854 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
3855 AG(allocated_memory) = 0;
3856diff -Naur php-4.4.0RC2/Zend/zend_alloc.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_alloc.h
3857--- php-4.4.0RC2/Zend/zend_alloc.h 2005-06-07 15:37:33.000000000 +0200
3858+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_alloc.h 2005-07-09 08:53:20.671596104 +0200
3859@@ -32,6 +32,9 @@
3860 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
3861
3862 typedef struct _zend_mem_header {
3863+#if HARDENING_PATCH_MM_PROTECT
3864+ unsigned int canary;
3865+#endif
3866 #if ZEND_DEBUG
3867 long magic;
3868 char *filename;
3869diff -Naur php-4.4.0RC2/Zend/zend_builtin_functions.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_builtin_functions.c
3870--- php-4.4.0RC2/Zend/zend_builtin_functions.c 2005-06-23 14:20:47.000000000 +0200
3871+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_builtin_functions.c 2005-07-09 08:53:20.671596104 +0200
3872@@ -49,6 +49,9 @@
3873 static ZEND_FUNCTION(crash);
3874 #endif
3875 #endif
3876+#if HARDENING_PATCH_MM_PROTECT_DEBUG
3877+static ZEND_FUNCTION(heap_overflow);
3878+#endif
3879 static ZEND_FUNCTION(get_included_files);
3880 static ZEND_FUNCTION(is_subclass_of);
3881 static ZEND_FUNCTION(is_a);
3882@@ -101,6 +104,9 @@
3883 ZEND_FE(crash, NULL)
3884 #endif
3885 #endif
3886+#if HARDENING_PATCH_MM_PROTECT_DEBUG
3887+ ZEND_FE(heap_overflow, NULL)
3888+#endif
3889 ZEND_FE(get_included_files, NULL)
3890 ZEND_FALIAS(get_required_files, get_included_files, NULL)
3891 ZEND_FE(is_subclass_of, NULL)
3892@@ -805,6 +811,19 @@
3893
3894 #endif /* ZEND_DEBUG */
3895
3896+
3897+#if HARDENING_PATCH_MM_PROTECT_DEBUG
3898+ZEND_FUNCTION(heap_overflow)
3899+{
3900+ char *nowhere = emalloc(10);
3901+
3902+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
3903+
3904+ efree(nowhere);
3905+}
3906+#endif
3907+
3908+
3909 /* {{{ proto array get_included_files(void)
3910 Returns an array with the file names that were include_once()'d */
3911 ZEND_FUNCTION(get_included_files)
3912diff -Naur php-4.4.0RC2/Zend/zend.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend.c
3913--- php-4.4.0RC2/Zend/zend.c 2005-06-09 12:14:25.000000000 +0200
3914+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend.c 2005-07-09 08:53:20.672595952 +0200
3915@@ -53,6 +53,12 @@
3916 ZEND_API void (*zend_unblock_interruptions)(void);
3917 ZEND_API void (*zend_ticks_function)(int ticks);
3918 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
3919+#if HARDENING_PATCH
3920+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
3921+#endif
3922+#if HARDENING_PATCH_INC_PROTECT
3923+ZEND_API int (*zend_is_valid_include)(zval *z);
3924+#endif
3925
3926 void (*zend_on_timeout)(int seconds TSRMLS_DC);
3927
3928@@ -70,9 +76,80 @@
3929 return SUCCESS;
3930 }
3931
3932+#if HARDENING_PATCH
3933+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
3934+{
3935+ if (!new_value) {
3936+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY;
3937+ } else {
3938+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY;
3939+ }
3940+ return SUCCESS;
3941+}
3942+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
3943+{
3944+ if (!new_value) {
3945+ EG(hphp_log_syslog_facility) = LOG_USER;
3946+ } else {
3947+ EG(hphp_log_syslog_facility) = atoi(new_value);
3948+ }
3949+ return SUCCESS;
3950+}
3951+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
3952+{
3953+ if (!new_value) {
3954+ EG(hphp_log_syslog_priority) = LOG_ALERT;
3955+ } else {
3956+ EG(hphp_log_syslog_priority) = atoi(new_value);
3957+ }
3958+ return SUCCESS;
3959+}
3960+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
3961+{
3962+ if (!new_value) {
3963+ EG(hphp_log_sapi) = S_ALL & ~S_SQL;
3964+ } else {
3965+ EG(hphp_log_sapi) = atoi(new_value);
3966+ }
3967+ return SUCCESS;
3968+}
3969+static ZEND_INI_MH(OnUpdateHPHP_log_script)
3970+{
3971+ if (!new_value) {
3972+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
3973+ } else {
3974+ EG(hphp_log_script) = atoi(new_value) & ~S_MEMORY;
3975+ }
3976+ return SUCCESS;
3977+}
3978+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
3979+{
3980+ if (!new_value) {
3981+ EG(hphp_log_scriptname) = NULL;
3982+ } else {
3983+ if (EG(hphp_log_scriptname)) {
3984+ pefree(EG(hphp_log_scriptname),1);
3985+ }
3986+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
3987+ }
3988+ return SUCCESS;
3989+}
3990+#endif
3991
3992 ZEND_INI_BEGIN()
3993 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
3994+#if HARDENING_PATCH
3995+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
3996+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
3997+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
3998+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
3999+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
4000+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
4001+ 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)
4002+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
4003+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
4004+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
4005+#endif
4006 ZEND_INI_END()
4007
4008
4009@@ -354,6 +431,7 @@
4010 zend_init_rsrc_plist(TSRMLS_C);
4011 EG(lambda_count)=0;
4012 EG(user_error_handler) = NULL;
4013+ EG(in_code_type) = 0;
4014 EG(in_execution) = 0;
4015 EG(current_execute_data) = NULL;
4016 }
4017@@ -420,6 +498,14 @@
4018 extern zend_scanner_globals language_scanner_globals;
4019 #endif
4020
4021+ /* Set up Hardening-Patch utility functions first */
4022+#if HARDENING_PATCH
4023+ zend_security_log = utility_functions->security_log_function;
4024+#endif
4025+#if HARDENING_PATCH_INC_PROTECT
4026+ zend_is_valid_include = utility_functions->is_valid_include;
4027+#endif
4028+
4029 #ifdef ZTS
4030 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
4031 #else
4032@@ -623,6 +709,7 @@
4033 }
4034 CG(unclean_shutdown) = 1;
4035 CG(in_compilation) = EG(in_execution) = 0;
4036+ EG(in_code_type) = 0;
4037 EG(current_execute_data) = NULL;
4038 longjmp(EG(bailout), FAILURE);
4039 }
4040diff -Naur php-4.4.0RC2/Zend/zend_canary.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_canary.c
4041--- php-4.4.0RC2/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
4042+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_canary.c 2005-07-09 08:53:20.673595800 +0200
4043@@ -0,0 +1,58 @@
4044+/*
4045+ +----------------------------------------------------------------------+
4046+ | Hardening-Patch for PHP |
4047+ +----------------------------------------------------------------------+
4048+ | Copyright (c) 2004-2005 Stefan Esser |
4049+ +----------------------------------------------------------------------+
4050+ | This source file is subject to version 2.02 of the PHP license, |
4051+ | that is bundled with this package in the file LICENSE, and is |
4052+ | available at through the world-wide-web at |
4053+ | http://www.php.net/license/2_02.txt. |
4054+ | If you did not receive a copy of the PHP license and are unable to |
4055+ | obtain it through the world-wide-web, please send a note to |
4056+ | license@php.net so we can mail you a copy immediately. |
4057+ +----------------------------------------------------------------------+
4058+ | Author: Stefan Esser <sesser@hardened-php.net> |
4059+ +----------------------------------------------------------------------+
4060+ */
4061+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
4062+
4063+#include "zend.h"
4064+
4065+#include <stdio.h>
4066+#include <stdlib.h>
4067+
4068+
4069+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4070+
4071+/* will be replaced later with more compatible method */
4072+ZEND_API unsigned int zend_canary()
4073+{
4074+ time_t t;
4075+ unsigned int canary;
4076+ int fd;
4077+
4078+ fd = open("/dev/urandom", 0);
4079+ if (fd != -1) {
4080+ int r = read(fd, &canary, sizeof(canary));
4081+ close(fd);
4082+ if (r == sizeof(canary)) {
4083+ return (canary);
4084+ }
4085+ }
4086+ /* not good but we never want to do this */
4087+ time(&t);
4088+ canary = *(unsigned int *)&t + getpid() << 16;
4089+ return (canary);
4090+}
4091+#endif
4092+
4093+
4094+/*
4095+ * Local variables:
4096+ * tab-width: 4
4097+ * c-basic-offset: 4
4098+ * End:
4099+ * vim600: sw=4 ts=4 fdm=marker
4100+ * vim<600: sw=4 ts=4
4101+ */
4102diff -Naur php-4.4.0RC2/Zend/zend_compile.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_compile.h
4103--- php-4.4.0RC2/Zend/zend_compile.h 2005-06-06 11:30:09.000000000 +0200
4104+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_compile.h 2005-07-09 08:53:20.673595800 +0200
4105@@ -549,6 +549,7 @@
4106 #define ZEND_USER_FUNCTION 2
4107 #define ZEND_OVERLOADED_FUNCTION 3
4108 #define ZEND_EVAL_CODE 4
4109+#define ZEND_SANDBOX_CODE 6
4110
4111 #define ZEND_INTERNAL_CLASS 1
4112 #define ZEND_USER_CLASS 2
4113diff -Naur php-4.4.0RC2/Zend/zend_constants.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_constants.c
4114--- php-4.4.0RC2/Zend/zend_constants.c 2004-07-13 21:29:45.000000000 +0200
4115+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_constants.c 2005-07-09 08:53:20.674595648 +0200
4116@@ -111,6 +111,72 @@
4117 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
4118
4119 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
4120+#if HARDENING_PATCH
4121+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
4122+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
4123+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_VARS, CONST_PERSISTENT | CONST_CS);
4124+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
4125+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
4126+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
4127+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
4128+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
4129+
4130+ /* error levels */
4131+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
4132+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
4133+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
4134+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
4135+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
4136+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
4137+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
4138+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
4139+ /* facility: type of program logging the message */
4140+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
4141+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
4142+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
4143+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
4144+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
4145+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
4146+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
4147+#ifdef LOG_NEWS
4148+ /* No LOG_NEWS on HP-UX */
4149+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
4150+#endif
4151+#ifdef LOG_UUCP
4152+ /* No LOG_UUCP on HP-UX */
4153+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
4154+#endif
4155+#ifdef LOG_CRON
4156+ /* apparently some systems don't have this one */
4157+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
4158+#endif
4159+#ifdef LOG_AUTHPRIV
4160+ /* AIX doesn't have LOG_AUTHPRIV */
4161+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
4162+#endif
4163+#if !defined(PHP_WIN32) && !defined(NETWARE)
4164+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
4165+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
4166+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
4167+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
4168+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
4169+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
4170+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
4171+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
4172+#endif
4173+ /* options */
4174+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
4175+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
4176+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
4177+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
4178+#ifdef LOG_NOWAIT
4179+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
4180+#endif
4181+#ifdef LOG_PERROR
4182+ /* AIX doesn't have LOG_PERROR */
4183+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
4184+#endif
4185+#endif
4186
4187 /* true/false constants */
4188 {
4189diff -Naur php-4.4.0RC2/Zend/zend_errors.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_errors.h
4190--- php-4.4.0RC2/Zend/zend_errors.h 2002-12-31 17:22:59.000000000 +0100
4191+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_errors.h 2005-07-09 08:53:20.674595648 +0200
4192@@ -36,5 +36,16 @@
4193 #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)
4194 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
4195
4196+#if HARDENING_PATCH
4197+#define S_MEMORY (1<<0L)
4198+#define S_VARS (1<<1L)
4199+#define S_FILES (1<<2L)
4200+#define S_INCLUDE (1<<3L)
4201+#define S_SQL (1<<4L)
4202+#define S_EXECUTOR (1<<5L)
4203+#define S_MISC (1<<30L)
4204+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
4205+#endif
4206+
4207 #endif /* ZEND_ERRORS_H */
4208
4209diff -Naur php-4.4.0RC2/Zend/zend_execute_API.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute_API.c
4210--- php-4.4.0RC2/Zend/zend_execute_API.c 2005-05-18 19:58:09.000000000 +0200
4211+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute_API.c 2005-07-09 08:53:20.675595496 +0200
4212@@ -142,6 +142,7 @@
4213 EG(class_table) = CG(class_table);
4214
4215 EG(in_execution) = 0;
4216+ EG(in_code_type) = 0;
4217
4218 zend_ptr_stack_init(&EG(argument_stack));
4219
4220@@ -431,12 +432,14 @@
4221 zend_execute_data execute_data;
4222
4223 /* Initialize execute_data */
4224+ memset(&execute_data, 0, sizeof(execute_data));
4225 EX(fbc) = NULL;
4226 EX(object).ptr = NULL;
4227 EX(ce) = NULL;
4228 EX(Ts) = NULL;
4229 EX(op_array) = NULL;
4230 EX(opline) = NULL;
4231+ EX(execute_depth) = 0;
4232
4233 *retval_ptr_ptr = NULL;
4234
4235@@ -606,8 +609,7 @@
4236 return SUCCESS;
4237 }
4238
4239-
4240-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
4241+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
4242 {
4243 zval pv;
4244 zend_op_array *new_op_array;
4245@@ -640,6 +642,7 @@
4246 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
4247 zend_op **original_opline_ptr = EG(opline_ptr);
4248
4249+ new_op_array->type = type;
4250 EG(return_value_ptr_ptr) = &local_retval_ptr;
4251 EG(active_op_array) = new_op_array;
4252 EG(no_extensions)=1;
4253@@ -673,6 +676,10 @@
4254 return retval;
4255 }
4256
4257+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
4258+{
4259+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
4260+}
4261
4262 void execute_new_code(TSRMLS_D)
4263 {
4264diff -Naur php-4.4.0RC2/Zend/zend_execute.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute.c
4265--- php-4.4.0RC2/Zend/zend_execute.c 2005-06-27 08:15:48.000000000 +0200
4266+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute.c 2005-07-09 08:53:20.676595344 +0200
4267@@ -1042,6 +1042,7 @@
4268 zend_execute_data execute_data;
4269
4270 /* Initialize execute_data */
4271+ memset(&execute_data, 0, sizeof(execute_data));
4272 EX(fbc) = NULL;
4273 EX(ce) = NULL;
4274 EX(object).ptr = NULL;
4275@@ -1053,9 +1054,21 @@
4276 }
4277 EX(prev_execute_data) = EG(current_execute_data);
4278 EX(original_in_execution)=EG(in_execution);
4279+ EX(original_in_code_type)=EG(in_code_type);
4280
4281 EG(current_execute_data) = &execute_data;
4282
4283+#if HARDENING_PATCH
4284+ EX(execute_depth) = 0;
4285+
4286+ if (op_array->type == ZEND_EVAL_CODE && EG(in_code_type) != ZEND_SANDBOX_CODE) {
4287+ EG(in_code_type) = ZEND_EVAL_CODE;
4288+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
4289+ EG(in_code_type) = ZEND_SANDBOX_CODE;
4290+ op_array->type = ZEND_EVAL_CODE;
4291+ }
4292+#endif
4293+
4294 EG(in_execution) = 1;
4295 if (op_array->start_op) {
4296 EX(opline) = op_array->start_op;
4297@@ -1087,6 +1100,19 @@
4298 }
4299 }
4300
4301+#if HARDENING_PATCH
4302+ if (EX(prev_execute_data) == NULL) {
4303+ EX(execute_depth) = 0;
4304+ } else {
4305+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
4306+ }
4307+
4308+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
4309+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
4310+ zend_bailout();
4311+ }
4312+#endif
4313+
4314 while (1) {
4315 #ifdef ZEND_WIN32
4316 if (EG(timed_out)) {
4317@@ -1816,6 +1842,7 @@
4318 efree(EX(Ts));
4319 }
4320 EG(in_execution) = EX(original_in_execution);
4321+ EG(in_code_type) = EX(original_in_code_type);
4322 EG(current_execute_data) = EX(prev_execute_data);
4323 return;
4324 }
4325@@ -2195,7 +2222,12 @@
4326 int dummy = 1;
4327 zend_file_handle file_handle = {0};
4328
4329+#if HARDENING_PATCH_INC_PROTECT
4330+ if (zend_is_valid_include(inc_filename)
4331+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
4332+#else
4333 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
4334+#endif
4335 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
4336
4337 file_handle.filename = inc_filename->value.str.val;
4338@@ -2224,6 +2256,11 @@
4339 break;
4340 case ZEND_INCLUDE:
4341 case ZEND_REQUIRE:
4342+#if HARDENING_PATCH_INC_PROTECT
4343+ if (!zend_is_valid_include(inc_filename)) {
4344+ break;
4345+ }
4346+#endif
4347 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
4348 break;
4349 case ZEND_EVAL: {
4350diff -Naur php-4.4.0RC2/Zend/zend_execute_globals.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute_globals.h
4351--- php-4.4.0RC2/Zend/zend_execute_globals.h 2005-06-06 11:30:09.000000000 +0200
4352+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_execute_globals.h 2005-07-09 08:53:20.677595192 +0200
4353@@ -60,6 +60,8 @@
4354 object_info object;
4355 temp_variable *Ts;
4356 zend_bool original_in_execution;
4357+ zend_uint original_in_code_type;
4358+ zend_uint execute_depth;
4359 zend_op_array *op_array;
4360 struct _zend_execute_data *prev_execute_data;
4361 } zend_execute_data;
4362diff -Naur php-4.4.0RC2/Zend/zend_extensions.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_extensions.h
4363--- php-4.4.0RC2/Zend/zend_extensions.h 2005-06-06 11:44:59.000000000 +0200
4364+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_extensions.h 2005-07-09 08:53:20.677595192 +0200
4365@@ -23,7 +23,9 @@
4366
4367 #include "zend_compile.h"
4368
4369-#define ZEND_EXTENSION_API_NO 20050606
4370+/* Create own API version number for Hardening-Patch */
4371+
4372+#define ZEND_EXTENSION_API_NO 1020050705
4373
4374 typedef struct _zend_extension_version_info {
4375 int zend_extension_api_no;
4376diff -Naur php-4.4.0RC2/Zend/zend_globals.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_globals.h
4377--- php-4.4.0RC2/Zend/zend_globals.h 2004-11-04 00:15:05.000000000 +0100
4378+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_globals.h 2005-07-09 08:53:20.678595040 +0200
4379@@ -163,6 +163,16 @@
4380
4381 int error_reporting;
4382 int orig_error_reporting;
4383+#if HARDENING_PATCH
4384+ int hphp_log_syslog;
4385+ int hphp_log_syslog_facility;
4386+ int hphp_log_syslog_priority;
4387+ int hphp_log_sapi;
4388+ int hphp_log_script;
4389+ char *hphp_log_scriptname;
4390+ zend_bool hphp_log_use_x_forwarded_for;
4391+ long hphp_executor_max_depth;
4392+#endif
4393 int exit_status;
4394
4395 zend_op_array *active_op_array;
4396@@ -176,6 +186,7 @@
4397 int ticks_count;
4398
4399 zend_bool in_execution;
4400+ zend_uint in_code_type;
4401 zend_bool bailout_set;
4402 zend_bool full_tables_cleanup;
4403
4404diff -Naur php-4.4.0RC2/Zend/zend.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend.h
4405--- php-4.4.0RC2/Zend/zend.h 2005-01-25 14:08:41.000000000 +0100
4406+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend.h 2005-07-09 08:53:20.678595040 +0200
4407@@ -275,9 +275,10 @@
4408 struct _zval_struct {
4409 /* Variable information */
4410 zvalue_value value; /* value */
4411+ zend_uint refcount;
4412+ zend_ushort flags;
4413 zend_uchar type; /* active type */
4414 zend_uchar is_ref;
4415- zend_ushort refcount;
4416 };
4417
4418
4419@@ -338,6 +339,12 @@
4420 void (*ticks_function)(int ticks);
4421 void (*on_timeout)(int seconds TSRMLS_DC);
4422 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
4423+#if HARDENING_PATCH
4424+ void (*security_log_function)(int loglevel, char *fmt, ...);
4425+#endif
4426+#if HARDENING_PATCH_INC_PROTECT
4427+ int (*is_valid_include)(zval *z);
4428+#endif
4429 } zend_utility_functions;
4430
4431
4432@@ -469,7 +476,16 @@
4433 extern ZEND_API void (*zend_ticks_function)(int ticks);
4434 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);
4435 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
4436+#if HARDENING_PATCH
4437+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
4438+#endif
4439+#if HARDENING_PATCH_INC_PROTECT
4440+extern ZEND_API int (*zend_is_valid_include)(zval *z);
4441+#endif
4442
4443+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4444+ZEND_API unsigned int zend_canary(void);
4445+#endif
4446
4447 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
4448
4449@@ -576,6 +592,11 @@
4450
4451 #define ZEND_MAX_RESERVED_RESOURCES 4
4452
4453+#if HARDENING_PATCH
4454+#include "hardened_globals.h"
4455+#include "php_syslog.h"
4456+#endif
4457+
4458 #endif /* ZEND_H */
4459
4460 /*
4461diff -Naur php-4.4.0RC2/Zend/zend_hash.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_hash.c
4462--- php-4.4.0RC2/Zend/zend_hash.c 2005-04-28 09:34:32.000000000 +0200
4463+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_hash.c 2005-07-09 08:53:20.679594888 +0200
4464@@ -26,6 +26,17 @@
4465 # include <stdlib.h>
4466 #endif
4467
4468+#if HARDENING_PATCH_HASH_PROTECT
4469+ unsigned int zend_hash_canary = 0x1234567;
4470+ zend_bool zend_hash_canary_inited = 0;
4471+#endif
4472+
4473+#define CHECK_HASH_CANARY(hash) \
4474+ if (zend_hash_canary != (hash)->canary) { \
4475+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
4476+ exit(1); \
4477+ }
4478+
4479 #define HANDLE_NUMERIC(key, length, func) { \
4480 register char *tmp=key; \
4481 \
4482@@ -175,6 +186,9 @@
4483 {
4484 uint i = 3;
4485 Bucket **tmp;
4486+#if HARDENING_PATCH_HASH_PROTECT
4487+ TSRMLS_FETCH();
4488+#endif
4489
4490 SET_INCONSISTENT(HT_OK);
4491
4492@@ -184,6 +198,13 @@
4493
4494 ht->nTableSize = 1 << i;
4495 ht->nTableMask = ht->nTableSize - 1;
4496+#if HARDENING_PATCH_HASH_PROTECT
4497+ if (zend_hash_canary_inited==0) {
4498+ zend_hash_canary = zend_canary();
4499+ zend_hash_canary_inited = 1;
4500+ }
4501+ ht->canary = zend_hash_canary;
4502+#endif
4503 ht->pDestructor = pDestructor;
4504 ht->pListHead = NULL;
4505 ht->pListTail = NULL;
4506@@ -259,6 +280,9 @@
4507 }
4508 #endif
4509 if (ht->pDestructor) {
4510+#if HARDENING_PATCH_HASH_PROTECT
4511+ CHECK_HASH_CANARY(ht);
4512+#endif
4513 ht->pDestructor(p->pData);
4514 }
4515 UPDATE_DATA(ht, p, pData, nDataSize);
4516@@ -327,6 +351,9 @@
4517 }
4518 #endif
4519 if (ht->pDestructor) {
4520+#if HARDENING_PATCH_HASH_PROTECT
4521+ CHECK_HASH_CANARY(ht);
4522+#endif
4523 ht->pDestructor(p->pData);
4524 }
4525 UPDATE_DATA(ht, p, pData, nDataSize);
4526@@ -402,6 +429,9 @@
4527 }
4528 #endif
4529 if (ht->pDestructor) {
4530+#if HARDENING_PATCH_HASH_PROTECT
4531+ CHECK_HASH_CANARY(ht);
4532+#endif
4533 ht->pDestructor(p->pData);
4534 }
4535 UPDATE_DATA(ht, p, pData, nDataSize);
4536@@ -450,7 +480,7 @@
4537 IS_CONSISTENT(ht);
4538
4539 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
4540- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
4541+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
4542 if (t) {
4543 HANDLE_BLOCK_INTERRUPTIONS();
4544 ht->arBuckets = t;
4545@@ -460,6 +490,7 @@
4546 HANDLE_UNBLOCK_INTERRUPTIONS();
4547 return SUCCESS;
4548 }
4549+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
4550 return FAILURE;
4551 }
4552 return SUCCESS;
4553@@ -524,6 +555,9 @@
4554 ht->pInternalPointer = p->pListNext;
4555 }
4556 if (ht->pDestructor) {
4557+#if HARDENING_PATCH_HASH_PROTECT
4558+ CHECK_HASH_CANARY(ht);
4559+#endif
4560 ht->pDestructor(p->pData);
4561 }
4562 if (!p->pDataPtr) {
4563@@ -553,6 +587,9 @@
4564 q = p;
4565 p = p->pListNext;
4566 if (ht->pDestructor) {
4567+#if HARDENING_PATCH_HASH_PROTECT
4568+ CHECK_HASH_CANARY(ht);
4569+#endif
4570 ht->pDestructor(q->pData);
4571 }
4572 if (!q->pDataPtr && q->pData) {
4573@@ -579,6 +616,9 @@
4574 q = p;
4575 p = p->pListNext;
4576 if (ht->pDestructor) {
4577+#if HARDENING_PATCH_HASH_PROTECT
4578+ CHECK_HASH_CANARY(ht);
4579+#endif
4580 ht->pDestructor(q->pData);
4581 }
4582 if (!q->pDataPtr && q->pData) {
4583@@ -608,6 +648,9 @@
4584 HANDLE_BLOCK_INTERRUPTIONS();
4585
4586 if (ht->pDestructor) {
4587+#if HARDENING_PATCH_HASH_PROTECT
4588+ CHECK_HASH_CANARY(ht);
4589+#endif
4590 ht->pDestructor(p->pData);
4591 }
4592 if (!p->pDataPtr) {
4593diff -Naur php-4.4.0RC2/Zend/zend_hash.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_hash.h
4594--- php-4.4.0RC2/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
4595+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_hash.h 2005-07-09 08:53:20.680594736 +0200
4596@@ -54,6 +54,9 @@
4597 } Bucket;
4598
4599 typedef struct _hashtable {
4600+#if HARDENING_PATCH_HASH_PROTECT
4601+ unsigned int canary;
4602+#endif
4603 uint nTableSize;
4604 uint nTableMask;
4605 uint nNumOfElements;
4606diff -Naur php-4.4.0RC2/Zend/zend_ini.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_ini.h
4607--- php-4.4.0RC2/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
4608+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_ini.h 2005-07-09 08:53:20.680594736 +0200
4609@@ -174,6 +174,7 @@
4610 /* Standard message handlers */
4611 BEGIN_EXTERN_C()
4612 ZEND_API ZEND_INI_MH(OnUpdateBool);
4613+#define OnUpdateLong OnUpdateInt
4614 ZEND_API ZEND_INI_MH(OnUpdateInt);
4615 ZEND_API ZEND_INI_MH(OnUpdateReal);
4616 ZEND_API ZEND_INI_MH(OnUpdateString);
4617diff -Naur php-4.4.0RC2/Zend/zend_llist.c hardening-patch-4.4.0RC2-0.3.2/Zend/zend_llist.c
4618--- php-4.4.0RC2/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
4619+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_llist.c 2005-07-09 08:53:20.681594584 +0200
4620@@ -21,9 +21,34 @@
4621 #include "zend.h"
4622 #include "zend_llist.h"
4623 #include "zend_qsort.h"
4624+#include "zend_globals.h"
4625+
4626+#define CHECK_LIST_CANARY(list) \
4627+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
4628+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
4629+ exit(1); \
4630+ }
4631+
4632+#define CHECK_LISTELEMENT_CANARY(elem) \
4633+ if (HG(canary_3) != (elem)->canary) { \
4634+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
4635+ exit(1); \
4636+ }
4637+
4638
4639 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
4640 {
4641+#if HARDENING_PATCH_LL_PROTECT
4642+ TSRMLS_FETCH();
4643+
4644+ if (!HG(ll_canary_inited)) {
4645+ HG(canary_3) = zend_canary();
4646+ HG(canary_4) = zend_canary();
4647+ HG(ll_canary_inited) = 1;
4648+ }
4649+ l->canary_h = HG(canary_3);
4650+ l->canary_t = HG(canary_4);
4651+#endif
4652 l->head = NULL;
4653 l->tail = NULL;
4654 l->count = 0;
4655@@ -37,6 +62,11 @@
4656 {
4657 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
4658
4659+#if HARDENING_PATCH_LL_PROTECT
4660+ TSRMLS_FETCH();
4661+ CHECK_LIST_CANARY(l)
4662+ tmp->canary = HG(canary_3);
4663+#endif
4664 tmp->prev = l->tail;
4665 tmp->next = NULL;
4666 if (l->tail) {
4667@@ -55,6 +85,11 @@
4668 {
4669 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
4670
4671+#if HARDENING_PATCH_LL_PROTECT
4672+ TSRMLS_FETCH();
4673+ CHECK_LIST_CANARY(l)
4674+ tmp->canary = HG(canary_3);
4675+#endif
4676 tmp->next = l->head;
4677 tmp->prev = NULL;
4678 if (l->head) {
4679@@ -91,10 +126,20 @@
4680 zend_llist_element *current=l->head;
4681 zend_llist_element *next;
4682
4683+#if HARDENING_PATCH_LL_PROTECT
4684+ TSRMLS_FETCH();
4685+ CHECK_LIST_CANARY(l)
4686+#endif
4687 while (current) {
4688+#if HARDENING_PATCH_LL_PROTECT
4689+ CHECK_LISTELEMENT_CANARY(current)
4690+#endif
4691 next = current->next;
4692 if (compare(current->data, element)) {
4693 DEL_LLIST_ELEMENT(current, l);
4694+#if HARDENING_PATCH_LL_PROTECT
4695+ current->canary = 0;
4696+#endif
4697 break;
4698 }
4699 current = next;
4700@@ -106,7 +151,14 @@
4701 {
4702 zend_llist_element *current=l->head, *next;
4703
4704+#if HARDENING_PATCH_LL_PROTECT
4705+ TSRMLS_FETCH();
4706+ CHECK_LIST_CANARY(l)
4707+#endif
4708 while (current) {
4709+#if HARDENING_PATCH_LL_PROTECT
4710+ CHECK_LISTELEMENT_CANARY(current)
4711+#endif
4712 next = current->next;
4713 if (l->dtor) {
4714 l->dtor(current->data);
4715@@ -131,7 +183,14 @@
4716 zend_llist_element *old_tail;
4717 void *data;
4718
4719+#if HARDENING_PATCH_LL_PROTECT
4720+ TSRMLS_FETCH();
4721+ CHECK_LIST_CANARY(l)
4722+#endif
4723 if ((old_tail = l->tail)) {
4724+#if HARDENING_PATCH_LL_PROTECT
4725+ CHECK_LISTELEMENT_CANARY(old_tail)
4726+#endif
4727 if (l->tail->prev) {
4728 l->tail->prev->next = NULL;
4729 }
4730@@ -157,9 +216,16 @@
4731 {
4732 zend_llist_element *ptr;
4733
4734+#if HARDENING_PATCH_LL_PROTECT
4735+ TSRMLS_FETCH();
4736+ CHECK_LIST_CANARY(src)
4737+#endif
4738 zend_llist_init(dst, src->size, src->dtor, src->persistent);
4739 ptr = src->head;
4740 while (ptr) {
4741+#if HARDENING_PATCH_LL_PROTECT
4742+ CHECK_LISTELEMENT_CANARY(ptr)
4743+#endif
4744 zend_llist_add_element(dst, ptr->data);
4745 ptr = ptr->next;
4746 }
4747@@ -170,11 +236,21 @@
4748 {
4749 zend_llist_element *element, *next;
4750
4751+#if HARDENING_PATCH_LL_PROTECT
4752+ TSRMLS_FETCH();
4753+ CHECK_LIST_CANARY(l)
4754+#endif
4755 element=l->head;
4756 while (element) {
4757+#if HARDENING_PATCH_LL_PROTECT
4758+ CHECK_LISTELEMENT_CANARY(element)
4759+#endif
4760 next = element->next;
4761 if (func(element->data)) {
4762 DEL_LLIST_ELEMENT(element, l);
4763+#if HARDENING_PATCH_LL_PROTECT
4764+ element->canary = 0;
4765+#endif
4766 }
4767 element = next;
4768 }
4769@@ -185,7 +261,13 @@
4770 {
4771 zend_llist_element *element;
4772
4773+#if HARDENING_PATCH_LL_PROTECT
4774+ CHECK_LIST_CANARY(l)
4775+#endif
4776 for (element=l->head; element; element=element->next) {
4777+#if HARDENING_PATCH_LL_PROTECT
4778+ CHECK_LISTELEMENT_CANARY(element)
4779+#endif
4780 func(element->data TSRMLS_CC);
4781 }
4782 }
4783@@ -197,6 +279,9 @@
4784 zend_llist_element **elements;
4785 zend_llist_element *element, **ptr;
4786
4787+#if HARDENING_PATCH_LL_PROTECT
4788+ CHECK_LIST_CANARY(l)
4789+#endif
4790 if (l->count <= 0) {
4791 return;
4792 }
4793@@ -206,6 +291,9 @@
4794 ptr = &elements[0];
4795
4796 for (element=l->head; element; element=element->next) {
4797+#if HARDENING_PATCH_LL_PROTECT
4798+ CHECK_LISTELEMENT_CANARY(element)
4799+#endif
4800 *ptr++ = element;
4801 }
4802
4803@@ -228,7 +316,13 @@
4804 {
4805 zend_llist_element *element;
4806
4807+#if HARDENING_PATCH_LL_PROTECT
4808+ CHECK_LIST_CANARY(l)
4809+#endif
4810 for (element=l->head; element; element=element->next) {
4811+#if HARDENING_PATCH_LL_PROTECT
4812+ CHECK_LISTELEMENT_CANARY(element)
4813+#endif
4814 func(element->data, arg TSRMLS_CC);
4815 }
4816 }
4817@@ -239,8 +333,14 @@
4818 zend_llist_element *element;
4819 va_list args;
4820
4821+#if HARDENING_PATCH_LL_PROTECT
4822+ CHECK_LIST_CANARY(l)
4823+#endif
4824 va_start(args, num_args);
4825 for (element=l->head; element; element=element->next) {
4826+#if HARDENING_PATCH_LL_PROTECT
4827+ CHECK_LISTELEMENT_CANARY(element)
4828+#endif
4829 func(element->data, num_args, args TSRMLS_CC);
4830 }
4831 va_end(args);
4832@@ -249,6 +349,10 @@
4833
4834 ZEND_API int zend_llist_count(zend_llist *l)
4835 {
4836+#if HARDENING_PATCH_LL_PROTECT
4837+ TSRMLS_FETCH();
4838+ CHECK_LIST_CANARY(l)
4839+#endif
4840 return l->count;
4841 }
4842
4843@@ -256,8 +360,15 @@
4844 {
4845 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
4846
4847+#if HARDENING_PATCH_LL_PROTECT
4848+ TSRMLS_FETCH();
4849+ CHECK_LIST_CANARY(l)
4850+#endif
4851 *current = l->head;
4852 if (*current) {
4853+#if HARDENING_PATCH_LL_PROTECT
4854+ CHECK_LISTELEMENT_CANARY(*current)
4855+#endif
4856 return (*current)->data;
4857 } else {
4858 return NULL;
4859@@ -269,8 +380,15 @@
4860 {
4861 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
4862
4863+#if HARDENING_PATCH_LL_PROTECT
4864+ TSRMLS_FETCH();
4865+ CHECK_LIST_CANARY(l)
4866+#endif
4867 *current = l->tail;
4868 if (*current) {
4869+#if HARDENING_PATCH_LL_PROTECT
4870+ CHECK_LISTELEMENT_CANARY(*current)
4871+#endif
4872 return (*current)->data;
4873 } else {
4874 return NULL;
4875@@ -282,9 +400,19 @@
4876 {
4877 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
4878
4879+#if HARDENING_PATCH_LL_PROTECT
4880+ TSRMLS_FETCH();
4881+ CHECK_LIST_CANARY(l)
4882+#endif
4883 if (*current) {
4884+#if HARDENING_PATCH_LL_PROTECT
4885+ CHECK_LISTELEMENT_CANARY(*current)
4886+#endif
4887 *current = (*current)->next;
4888 if (*current) {
4889+#if HARDENING_PATCH_LL_PROTECT
4890+ CHECK_LISTELEMENT_CANARY(*current)
4891+#endif
4892 return (*current)->data;
4893 }
4894 }
4895@@ -296,9 +424,19 @@
4896 {
4897 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
4898
4899+#if HARDENING_PATCH_LL_PROTECT
4900+ TSRMLS_FETCH();
4901+ CHECK_LIST_CANARY(l)
4902+#endif
4903 if (*current) {
4904+#if HARDENING_PATCH_LL_PROTECT
4905+ CHECK_LISTELEMENT_CANARY(*current)
4906+#endif
4907 *current = (*current)->prev;
4908 if (*current) {
4909+#if HARDENING_PATCH_LL_PROTECT
4910+ CHECK_LISTELEMENT_CANARY(*current)
4911+#endif
4912 return (*current)->data;
4913 }
4914 }
4915diff -Naur php-4.4.0RC2/Zend/zend_llist.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_llist.h
4916--- php-4.4.0RC2/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
4917+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_llist.h 2005-07-09 08:53:20.681594584 +0200
4918@@ -24,6 +24,9 @@
4919 #include <stdlib.h>
4920
4921 typedef struct _zend_llist_element {
4922+#if HARDENING_PATCH_LL_PROTECT
4923+ unsigned int canary;
4924+#endif
4925 struct _zend_llist_element *next;
4926 struct _zend_llist_element *prev;
4927 char data[1]; /* Needs to always be last in the struct */
4928@@ -36,6 +39,9 @@
4929 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
4930
4931 typedef struct _zend_llist {
4932+#if HARDENING_PATCH_LL_PROTECT
4933+ unsigned int canary_h; /* head */
4934+#endif
4935 zend_llist_element *head;
4936 zend_llist_element *tail;
4937 size_t size;
4938@@ -43,6 +49,9 @@
4939 llist_dtor_func_t dtor;
4940 unsigned char persistent;
4941 zend_llist_element *traverse_ptr;
4942+#if HARDENING_PATCH_LL_PROTECT
4943+ unsigned int canary_t; /* tail */
4944+#endif
4945 } zend_llist;
4946
4947 typedef zend_llist_element* zend_llist_position;
4948diff -Naur php-4.4.0RC2/Zend/zend_modules.h hardening-patch-4.4.0RC2-0.3.2/Zend/zend_modules.h
4949--- php-4.4.0RC2/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
4950+++ hardening-patch-4.4.0RC2-0.3.2/Zend/zend_modules.h 2005-07-09 08:53:20.682594432 +0200
4951@@ -34,7 +34,7 @@
4952 ZEND_API extern unsigned char second_arg_force_ref[];
4953 ZEND_API extern unsigned char third_arg_force_ref[];
4954
4955-#define ZEND_MODULE_API_NO 20020429
4956+#define ZEND_MODULE_API_NO 1020050626
4957 #ifdef ZTS
4958 #define USING_ZTS 1
4959 #else