summaryrefslogtreecommitdiff
path: root/0.4.5
diff options
context:
space:
mode:
authorjvoisin2019-10-13 12:42:55 +0200
committerjvoisin2019-10-13 12:42:55 +0200
commit6113feef6838633df32f91f96c98318a6de605fe (patch)
tree8644f4a7e1cc032693f373154e91da68bf90ed44 /0.4.5
parent7ce0f98b0be3ad15a664e506dff461cf6d633a69 (diff)
Add more patches
Diffstat (limited to '0.4.5')
-rw-r--r--0.4.5/hardening-patch-4.4.1-0.4.5.patch7501
-rw-r--r--0.4.5/hardening-patch-5.0.5-0.4.5.patch7316
2 files changed, 14817 insertions, 0 deletions
diff --git a/0.4.5/hardening-patch-4.4.1-0.4.5.patch b/0.4.5/hardening-patch-4.4.1-0.4.5.patch
new file mode 100644
index 0000000..2f5fc48
--- /dev/null
+++ b/0.4.5/hardening-patch-4.4.1-0.4.5.patch
@@ -0,0 +1,7501 @@
1diff -Nura php-4.4.1/acinclude.m4 hardening-patch-4.4.1-0.4.5/acinclude.m4
2--- php-4.4.1/acinclude.m4 2005-09-23 11:20:22.000000000 +0200
3+++ hardening-patch-4.4.1-0.4.5/acinclude.m4 2005-10-30 17:12:13.000000000 +0100
4@@ -1182,6 +1182,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-4.4.1/configure hardening-patch-4.4.1-0.4.5/configure
42--- php-4.4.1/configure 2005-10-30 12:06:37.000000000 +0100
43+++ hardening-patch-4.4.1-0.4.5/configure 2005-10-30 17:12:13.000000000 +0100
44@@ -395,6 +395,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@@ -847,6 +857,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@@ -2828,6 +2840,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@@ -15903,6 +16066,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:15908: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -86368,7 +86587,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -87070,7 +87289,7 @@
301 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
302 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
303 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
304- var_unserializer.c ftok.c aggregation.c sha1.c ; do
305+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -87125,7 +87344,7 @@
310 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
311 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
312 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
313- var_unserializer.c ftok.c aggregation.c sha1.c ; do
314+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -87251,7 +87470,7 @@
319 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
320 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
321 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
322- var_unserializer.c ftok.c aggregation.c sha1.c ; do
323+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -87303,7 +87522,7 @@
328 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
329 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
330 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
331- var_unserializer.c ftok.c aggregation.c sha1.c ; do
332+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -90774,6 +90993,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
428+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
474+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
538+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
581+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -103822,7 +104300,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 streams.c network.c php_open_temporary_file.c php_logos.c \
606- output.c memory_streams.c user_streams.c; do
607+ output.c memory_streams.c user_streams.c hardening_patch.c; do
608
609 IFS=.
610 set $ac_src
611@@ -104007,7 +104485,7 @@
612 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
613 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
614 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
615- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c; do
616+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-4.4.1/configure.in hardening-patch-4.4.1-0.4.5/configure.in
621--- php-4.4.1/configure.in 2005-10-26 09:58:22.000000000 +0200
622+++ hardening-patch-4.4.1-0.4.5/configure.in 2005-10-30 17:12:13.000000000 +0100
623@@ -247,7 +247,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -621,6 +621,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1260,7 +1261,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 streams.c network.c php_open_temporary_file.c php_logos.c \
644- output.c memory_streams.c user_streams.c)
645+ output.c memory_streams.c user_streams.c hardening_patch.c)
646 PHP_ADD_SOURCES(/main, internal_functions.c,, sapi)
647 case $host_alias in
648 *netware*)
649@@ -1281,7 +1282,7 @@
650 zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
651 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
652 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
653- zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c)
654+ zend_ini.c zend_qsort.c zend_multibyte.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c)
658diff -Nura php-4.4.1/ext/curl/curl.c hardening-patch-4.4.1-0.4.5/ext/curl/curl.c
659--- php-4.4.1/ext/curl/curl.c 2005-10-17 04:42:51.000000000 +0200
660+++ hardening-patch-4.4.1-0.4.5/ext/curl/curl.c 2005-11-01 13:41:04.000000000 +0100
661@@ -76,7 +76,7 @@
662 RETURN_FALSE; \
663 } \
664 \
665- if (tmp_url->query || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
666+ if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
667 (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
668 ) { \
669 php_url_free(tmp_url); \
670diff -Nura php-4.4.1/ext/fbsql/php_fbsql.c hardening-patch-4.4.1-0.4.5/ext/fbsql/php_fbsql.c
671--- php-4.4.1/ext/fbsql/php_fbsql.c 2005-02-09 20:33:32.000000000 +0100
672+++ hardening-patch-4.4.1-0.4.5/ext/fbsql/php_fbsql.c 2005-10-30 17:12:13.000000000 +0100
673@@ -1797,8 +1797,24 @@
674 }
675 else if (fbcmdErrorsFound(md))
676 {
677+#if HARDENING_PATCH
678+ char* query_copy;
679+ int i;
680+#endif
681 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
682 char* emg = fbcemdAllErrorMessages(emd);
683+#if HARDENING_PATCH
684+ query_copy=estrdup(query_copy);
685+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
686+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
687+ efree(query_copy);
688+ if (HG(hphp_sql_bailout_on_error)) {
689+ free(emg);
690+ fbcemdRelease(emd);
691+ result = 0;
692+ zend_bailout();
693+ }
694+#endif
695 if (FB_SQL_G(generateWarnings))
696 {
697 if (emg)
698diff -Nura php-4.4.1/ext/gd/gd.c hardening-patch-4.4.1-0.4.5/ext/gd/gd.c
699--- php-4.4.1/ext/gd/gd.c 2005-10-06 22:44:52.000000000 +0200
700+++ hardening-patch-4.4.1-0.4.5/ext/gd/gd.c 2005-11-01 15:04:05.000000000 +0100
701@@ -3742,13 +3742,13 @@
702 }
703
704 /* Check origin file */
705- if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC)) {
706+ if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_org, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
707 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid origin filename '%s'", fn_org);
708 RETURN_FALSE;
709 }
710
711 /* Check destination file */
712- if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC)) {
713+ if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_dest, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
714 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid destination filename '%s'", fn_dest);
715 RETURN_FALSE;
716 }
717diff -Nura php-4.4.1/ext/mbstring/mbstring.c hardening-patch-4.4.1-0.4.5/ext/mbstring/mbstring.c
718--- php-4.4.1/ext/mbstring/mbstring.c 2005-09-21 15:19:19.000000000 +0200
719+++ hardening-patch-4.4.1-0.4.5/ext/mbstring/mbstring.c 2005-10-30 17:12:13.000000000 +0100
720@@ -1488,6 +1488,7 @@
721 char *strtok_buf = NULL, **val_list;
722 zval *array_ptr = (zval *) arg;
723 int n, num, val_len, *len_list;
724+ unsigned int new_val_len;
725 enum mbfl_no_encoding from_encoding;
726 mbfl_string string, resvar, resval;
727 mbfl_encoding_detector *identd = NULL;
728@@ -1610,8 +1611,14 @@
729 val_len = len_list[n];
730 }
731 n++;
732- /* add variable to symbol table */
733- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
734+ /* we need val to be emalloc()ed */
735+ val = estrndup(val, val_len);
736+ if (sapi_module.input_filter(info->data_type, var, &val, val_len, &new_val_len TSRMLS_CC)) {
737+ /* add variable to symbol table */
738+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
739+ }
740+ efree(val);
741+
742 if (convd != NULL){
743 mbfl_string_clear(&resvar);
744 mbfl_string_clear(&resval);
745diff -Nura php-4.4.1/ext/mysql/php_mysql.c hardening-patch-4.4.1-0.4.5/ext/mysql/php_mysql.c
746--- php-4.4.1/ext/mysql/php_mysql.c 2005-04-08 00:23:01.000000000 +0200
747+++ hardening-patch-4.4.1-0.4.5/ext/mysql/php_mysql.c 2005-10-30 17:12:13.000000000 +0100
748@@ -1218,6 +1218,8 @@
749 {
750 php_mysql_conn *mysql;
751 MYSQL_RES *mysql_result;
752+ char *copy_query;
753+ int i;
754
755 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
756
757@@ -1268,6 +1270,13 @@
758 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
759 }
760 }
761+ copy_query = estrdup(Z_STRVAL_PP(query));
762+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
763+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
764+ efree(copy_query);
765+ if (HG(hphp_sql_bailout_on_error)) {
766+ zend_bailout();
767+ }
768 RETURN_FALSE;
769 }
770 #else
771@@ -1275,12 +1284,20 @@
772 /* check possible error */
773 if (MySG(trace_mode)){
774 if (mysql_errno(&mysql->conn)){
775- php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, mysql_error(&mysql->conn));
776+ php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
777 }
778 }
779+ copy_query = estrdup(Z_STRVAL_PP(query));
780+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
781+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
782+ efree(copy_query);
783+ if (HG(hphp_sql_bailout_on_error)) {
784+ zend_bailout();
785+ }
786 RETURN_FALSE;
787 }
788 #endif
789+
790 if(use_store == MYSQL_USE_RESULT) {
791 mysql_result=mysql_use_result(&mysql->conn);
792 } else {
793diff -Nura php-4.4.1/ext/pgsql/pgsql.c hardening-patch-4.4.1-0.4.5/ext/pgsql/pgsql.c
794--- php-4.4.1/ext/pgsql/pgsql.c 2005-07-05 14:50:03.000000000 +0200
795+++ hardening-patch-4.4.1-0.4.5/ext/pgsql/pgsql.c 2005-10-30 17:12:13.000000000 +0100
796@@ -1001,10 +1001,28 @@
797 case PGRES_EMPTY_QUERY:
798 case PGRES_BAD_RESPONSE:
799 case PGRES_NONFATAL_ERROR:
800- case PGRES_FATAL_ERROR:
801- PHP_PQ_ERROR("Query failed: %s", pgsql);
802- PQclear(pgsql_result);
803- RETURN_FALSE;
804+ case PGRES_FATAL_ERROR:
805+ {
806+#if HARDENING_PATCH
807+ int i;
808+ char *query_copy;
809+#endif
810+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
811+ PQclear(pgsql_result);
812+#if HARDENING_PATCH
813+ query_copy = estrdup(Z_STRVAL_PP(query));
814+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
815+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
816+ efree(query_copy);
817+ if (HG(hphp_sql_bailout_on_error)) {
818+ efree(msgbuf);
819+ zend_bailout();
820+ }
821+#endif
822+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
823+ efree(msgbuf);
824+ RETURN_FALSE;
825+ }
826 break;
827 case PGRES_COMMAND_OK: /* successful command that did not return rows */
828 default:
829diff -Nura php-4.4.1/ext/standard/array.c hardening-patch-4.4.1-0.4.5/ext/standard/array.c
830--- php-4.4.1/ext/standard/array.c 2005-10-03 16:05:07.000000000 +0200
831+++ hardening-patch-4.4.1-0.4.5/ext/standard/array.c 2005-10-30 17:12:13.000000000 +0100
832@@ -1162,6 +1162,32 @@
833 }
834 }
835 }
836+
837+ if (var_name[0] == 'H') {
838+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
839+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
840+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
841+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
842+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
843+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
844+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
845+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
846+ return 0;
847+ }
848+ } else if (var_name[0] == '_') {
849+ if ((strcmp(var_name, "_COOKIE")==0)||
850+ (strcmp(var_name, "_ENV")==0)||
851+ (strcmp(var_name, "_FILES")==0)||
852+ (strcmp(var_name, "_GET")==0)||
853+ (strcmp(var_name, "_POST")==0)||
854+ (strcmp(var_name, "_REQUEST")==0)||
855+ (strcmp(var_name, "_SESSION")==0)||
856+ (strcmp(var_name, "_SERVER")==0)) {
857+ return 0;
858+ }
859+ } else if (strcmp(var_name, "GLOBALS")==0) {
860+ return 0;
861+ }
862
863 return 1;
864 }
865diff -Nura php-4.4.1/ext/standard/basic_functions.c hardening-patch-4.4.1-0.4.5/ext/standard/basic_functions.c
866--- php-4.4.1/ext/standard/basic_functions.c 2005-09-29 18:31:48.000000000 +0200
867+++ hardening-patch-4.4.1-0.4.5/ext/standard/basic_functions.c 2005-10-30 17:12:13.000000000 +0100
868@@ -107,12 +107,14 @@
869 typedef struct _php_shutdown_function_entry {
870 zval **arguments;
871 int arg_count;
872+ zend_bool created_by_eval;
873 } php_shutdown_function_entry;
874
875 typedef struct _user_tick_function_entry {
876 zval **arguments;
877 int arg_count;
878 int calling;
879+ zend_bool created_by_eval;
880 } user_tick_function_entry;
881
882 /* some prototypes for local functions */
883@@ -295,6 +297,8 @@
884 PHP_FE(get_html_translation_table, NULL)
885 PHP_FE(sha1, NULL)
886 PHP_FE(sha1_file, NULL)
887+ PHP_FE(sha256, NULL)
888+ PHP_FE(sha256_file, NULL)
889 PHP_NAMED_FE(md5,php_if_md5, NULL)
890 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
891 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
892@@ -676,7 +680,7 @@
893 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
894
895 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
896- PHP_FE(realpath, NULL)
897+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
898 #endif
899
900 #ifdef HAVE_FNMATCH
901@@ -2093,6 +2097,13 @@
902 {
903 zval retval;
904 char *function_name = NULL;
905+#if HARDENING_PATCH
906+ zend_uint orig_code_type = EG(in_code_type);
907+
908+ if (shutdown_function_entry->created_by_eval) {
909+ EG(in_code_type) = ZEND_EVAL_CODE;
910+ }
911+#endif
912
913 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
914 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
915@@ -2108,6 +2119,9 @@
916 if (function_name) {
917 efree(function_name);
918 }
919+#if HARDENING_PATCH
920+ EG(in_code_type) = orig_code_type;
921+#endif
922 return 0;
923 }
924
925@@ -2115,6 +2129,13 @@
926 {
927 zval retval;
928 zval *function = tick_fe->arguments[0];
929+#if HARDENING_PATCH
930+ zend_uint orig_code_type = EG(in_code_type);
931+
932+ if (tick_fe->created_by_eval) {
933+ EG(in_code_type) = ZEND_EVAL_CODE;
934+ }
935+#endif
936
937 /* Prevent reentrant calls to the same user ticks function */
938 if (! tick_fe->calling) {
939@@ -2146,6 +2167,9 @@
940
941 tick_fe->calling = 0;
942 }
943+#if HARDENING_PATCH
944+ EG(in_code_type) = orig_code_type;
945+#endif
946 }
947
948 static void run_user_tick_functions(int tick_count)
949@@ -2213,6 +2237,13 @@
950 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
951 RETURN_FALSE;
952 }
953+#if HARDENING_PATCH
954+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
955+ shutdown_function_entry.created_by_eval = 1;
956+ } else {
957+ shutdown_function_entry.created_by_eval = 0;
958+ }
959+#endif
960
961 /* Prevent entering of anything but valid callback (syntax check only!) */
962 if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) {
963@@ -2750,6 +2781,13 @@
964 }
965
966 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
967+#if HARDENING_PATCH
968+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
969+ tick_fe.created_by_eval = 1;
970+ } else {
971+ tick_fe.created_by_eval = 0;
972+ }
973+#endif
974
975 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
976 RETURN_FALSE;
977@@ -3047,6 +3085,35 @@
978 new_key_len = spprintf(&new_key, 0, "%s%ld", prefix, hash_key->h);
979 }
980
981+ if (new_key[0] == 'H') {
982+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
983+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
984+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
985+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
986+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
987+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
988+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
989+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
990+ efree(new_key);
991+ return 0;
992+ }
993+ } else if (new_key[0] == '_') {
994+ if ((strcmp(new_key, "_COOKIE")==0)||
995+ (strcmp(new_key, "_ENV")==0)||
996+ (strcmp(new_key, "_FILES")==0)||
997+ (strcmp(new_key, "_GET")==0)||
998+ (strcmp(new_key, "_POST")==0)||
999+ (strcmp(new_key, "_REQUEST")==0)||
1000+ (strcmp(new_key, "_SESSION")==0)||
1001+ (strcmp(new_key, "_SERVER")==0)) {
1002+ efree(new_key);
1003+ return 0;
1004+ }
1005+ } else if (strcmp(new_key, "GLOBALS")==0) {
1006+ efree(new_key);
1007+ return 0;
1008+ }
1009+
1010 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1011 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1012
1013diff -Nura php-4.4.1/ext/standard/config.m4 hardening-patch-4.4.1-0.4.5/ext/standard/config.m4
1014--- php-4.4.1/ext/standard/config.m4 2004-12-30 08:02:18.000000000 +0100
1015+++ hardening-patch-4.4.1-0.4.5/ext/standard/config.m4 2005-10-30 17:12:13.000000000 +0100
1016@@ -203,7 +203,7 @@
1017 if test "$ac_cv_crypt_blowfish" = "yes"; then
1018 ac_result=1
1019 else
1020- ac_result=0
1021+ ac_result=1
1022 fi
1023 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1024 ])
1025@@ -419,6 +419,6 @@
1026 url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \
1027 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1028 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1029- var_unserializer.c ftok.c aggregation.c sha1.c )
1030+ var_unserializer.c ftok.c aggregation.c sha1.c sha256.c crypt_blowfish.c )
1031
1032 PHP_ADD_MAKEFILE_FRAGMENT
1033diff -Nura php-4.4.1/ext/standard/crypt_blowfish.c hardening-patch-4.4.1-0.4.5/ext/standard/crypt_blowfish.c
1034--- php-4.4.1/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1035+++ hardening-patch-4.4.1-0.4.5/ext/standard/crypt_blowfish.c 2005-10-30 17:12:13.000000000 +0100
1036@@ -0,0 +1,748 @@
1037+/*
1038+ * This code comes from John the Ripper password cracker, with reentrant
1039+ * and crypt(3) interfaces added, but optimizations specific to password
1040+ * cracking removed.
1041+ *
1042+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1043+ * placed in the public domain.
1044+ *
1045+ * There's absolutely no warranty.
1046+ *
1047+ * It is my intent that you should be able to use this on your system,
1048+ * as a part of a software package, or anywhere else to improve security,
1049+ * ensure compatibility, or for any other purpose. I would appreciate
1050+ * it if you give credit where it is due and keep your modifications in
1051+ * the public domain as well, but I don't require that in order to let
1052+ * you place this code and any modifications you make under a license
1053+ * of your choice.
1054+ *
1055+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1056+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1057+ * ideas. The password hashing algorithm was designed by David Mazieres
1058+ * <dm at lcs.mit.edu>.
1059+ *
1060+ * There's a paper on the algorithm that explains its design decisions:
1061+ *
1062+ * http://www.usenix.org/events/usenix99/provos.html
1063+ *
1064+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1065+ * Blowfish library (I can't be sure if I would think of something if I
1066+ * hadn't seen his code).
1067+ */
1068+
1069+#include <string.h>
1070+
1071+#include <errno.h>
1072+#ifndef __set_errno
1073+#define __set_errno(val) errno = (val)
1074+#endif
1075+
1076+#undef __CONST
1077+#ifdef __GNUC__
1078+#define __CONST __const
1079+#else
1080+#define __CONST
1081+#endif
1082+
1083+#ifdef __i386__
1084+#define BF_ASM 0
1085+#define BF_SCALE 1
1086+#elif defined(__alpha__) || defined(__hppa__)
1087+#define BF_ASM 0
1088+#define BF_SCALE 1
1089+#else
1090+#define BF_ASM 0
1091+#define BF_SCALE 0
1092+#endif
1093+
1094+typedef unsigned int BF_word;
1095+
1096+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1097+#define BF_N 16
1098+
1099+typedef BF_word BF_key[BF_N + 2];
1100+
1101+typedef struct {
1102+ BF_word S[4][0x100];
1103+ BF_key P;
1104+} BF_ctx;
1105+
1106+/*
1107+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1108+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1109+ */
1110+static BF_word BF_magic_w[6] = {
1111+ 0x4F727068, 0x65616E42, 0x65686F6C,
1112+ 0x64657253, 0x63727944, 0x6F756274
1113+};
1114+
1115+/*
1116+ * P-box and S-box tables initialized with digits of Pi.
1117+ */
1118+static BF_ctx BF_init_state = {
1119+ {
1120+ {
1121+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1122+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1123+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1124+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1125+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1126+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1127+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1128+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1129+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1130+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1131+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1132+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1133+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1134+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1135+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1136+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1137+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1138+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1139+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1140+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1141+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1142+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1143+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1144+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1145+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1146+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1147+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1148+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1149+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1150+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1151+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1152+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1153+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1154+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1155+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1156+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1157+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1158+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1159+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1160+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1161+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1162+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1163+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1164+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1165+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1166+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1167+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1168+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1169+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1170+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1171+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1172+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1173+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1174+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1175+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1176+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1177+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1178+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1179+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1180+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1181+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1182+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1183+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1184+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1185+ }, {
1186+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1187+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1188+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1189+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1190+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1191+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1192+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1193+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1194+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1195+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1196+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1197+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1198+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1199+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1200+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1201+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1202+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1203+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1204+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1205+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1206+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1207+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1208+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1209+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1210+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1211+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1212+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1213+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1214+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1215+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1216+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1217+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1218+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1219+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1220+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1221+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1222+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1223+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1224+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1225+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1226+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1227+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1228+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1229+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1230+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1231+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1232+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1233+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1234+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1235+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1236+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1237+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1238+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1239+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1240+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1241+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1242+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1243+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1244+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1245+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1246+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1247+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1248+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1249+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1250+ }, {
1251+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1252+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1253+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1254+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1255+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1256+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1257+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1258+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1259+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1260+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1261+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1262+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1263+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1264+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1265+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1266+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1267+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1268+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1269+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1270+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1271+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1272+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1273+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1274+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1275+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1276+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1277+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1278+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1279+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1280+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1281+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1282+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1283+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1284+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1285+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1286+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1287+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1288+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1289+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1290+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1291+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1292+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1293+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1294+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1295+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1296+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1297+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1298+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1299+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1300+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1301+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1302+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1303+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1304+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1305+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1306+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1307+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1308+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1309+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1310+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1311+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1312+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1313+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1314+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1315+ }, {
1316+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1317+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1318+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1319+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1320+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1321+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1322+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1323+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1324+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1325+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1326+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1327+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1328+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1329+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1330+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1331+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1332+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1333+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1334+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1335+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1336+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1337+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1338+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1339+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1340+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1341+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1342+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1343+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1344+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1345+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1346+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1347+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1348+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1349+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1350+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1351+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1352+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1353+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1354+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1355+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1356+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1357+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1358+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1359+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1360+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1361+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1362+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1363+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1364+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1365+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1366+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1367+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1368+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1369+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1370+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1371+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1372+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1373+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1374+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1375+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1376+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1377+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1378+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1379+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1380+ }
1381+ }, {
1382+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1383+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1384+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1385+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1386+ 0x9216d5d9, 0x8979fb1b
1387+ }
1388+};
1389+
1390+static unsigned char BF_itoa64[64 + 1] =
1391+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1392+
1393+static unsigned char BF_atoi64[0x60] = {
1394+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1395+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1396+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1397+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1398+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1399+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1400+};
1401+
1402+/*
1403+ * This may be optimized out if built with function inlining and no BF_ASM.
1404+ */
1405+static void clean(void *data, int size)
1406+{
1407+#if BF_ASM
1408+ extern void _BF_clean(void *data);
1409+#endif
1410+ memset(data, 0, size);
1411+#if BF_ASM
1412+ _BF_clean(data);
1413+#endif
1414+}
1415+
1416+#define BF_safe_atoi64(dst, src) \
1417+{ \
1418+ tmp = (unsigned char)(src); \
1419+ if (tmp == '$') break; \
1420+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1421+ tmp = BF_atoi64[tmp]; \
1422+ if (tmp > 63) return -1; \
1423+ (dst) = tmp; \
1424+}
1425+
1426+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1427+{
1428+ unsigned char *dptr = (unsigned char *)dst;
1429+ unsigned char *end = dptr + size;
1430+ unsigned char *sptr = (unsigned char *)src;
1431+ unsigned int tmp, c1, c2, c3, c4;
1432+
1433+ do {
1434+ BF_safe_atoi64(c1, *sptr++);
1435+ BF_safe_atoi64(c2, *sptr++);
1436+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1437+ if (dptr >= end) break;
1438+
1439+ BF_safe_atoi64(c3, *sptr++);
1440+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1441+ if (dptr >= end) break;
1442+
1443+ BF_safe_atoi64(c4, *sptr++);
1444+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1445+ } while (dptr < end);
1446+
1447+ while (dptr < end)
1448+ *dptr++ = 0;
1449+
1450+ return 0;
1451+}
1452+
1453+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1454+{
1455+ unsigned char *sptr = (unsigned char *)src;
1456+ unsigned char *end = sptr + size;
1457+ unsigned char *dptr = (unsigned char *)dst;
1458+ unsigned int c1, c2;
1459+
1460+ do {
1461+ c1 = *sptr++;
1462+ *dptr++ = BF_itoa64[c1 >> 2];
1463+ c1 = (c1 & 0x03) << 4;
1464+ if (sptr >= end) {
1465+ *dptr++ = BF_itoa64[c1];
1466+ break;
1467+ }
1468+
1469+ c2 = *sptr++;
1470+ c1 |= c2 >> 4;
1471+ *dptr++ = BF_itoa64[c1];
1472+ c1 = (c2 & 0x0f) << 2;
1473+ if (sptr >= end) {
1474+ *dptr++ = BF_itoa64[c1];
1475+ break;
1476+ }
1477+
1478+ c2 = *sptr++;
1479+ c1 |= c2 >> 6;
1480+ *dptr++ = BF_itoa64[c1];
1481+ *dptr++ = BF_itoa64[c2 & 0x3f];
1482+ } while (sptr < end);
1483+}
1484+
1485+static void BF_swap(BF_word *x, int count)
1486+{
1487+ static int endianness_check = 1;
1488+ char *is_little_endian = (char *)&endianness_check;
1489+ BF_word tmp;
1490+
1491+ if (*is_little_endian)
1492+ do {
1493+ tmp = *x;
1494+ tmp = (tmp << 16) | (tmp >> 16);
1495+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1496+ } while (--count);
1497+}
1498+
1499+#if BF_SCALE
1500+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1501+#define BF_ROUND(L, R, N) \
1502+ tmp1 = L & 0xFF; \
1503+ tmp2 = L >> 8; \
1504+ tmp2 &= 0xFF; \
1505+ tmp3 = L >> 16; \
1506+ tmp3 &= 0xFF; \
1507+ tmp4 = L >> 24; \
1508+ tmp1 = data.ctx.S[3][tmp1]; \
1509+ tmp2 = data.ctx.S[2][tmp2]; \
1510+ tmp3 = data.ctx.S[1][tmp3]; \
1511+ tmp3 += data.ctx.S[0][tmp4]; \
1512+ tmp3 ^= tmp2; \
1513+ R ^= data.ctx.P[N + 1]; \
1514+ tmp3 += tmp1; \
1515+ R ^= tmp3;
1516+#else
1517+/* Architectures with no complicated addressing modes supported */
1518+#define BF_INDEX(S, i) \
1519+ (*((BF_word *)(((unsigned char *)S) + (i))))
1520+#define BF_ROUND(L, R, N) \
1521+ tmp1 = L & 0xFF; \
1522+ tmp1 <<= 2; \
1523+ tmp2 = L >> 6; \
1524+ tmp2 &= 0x3FC; \
1525+ tmp3 = L >> 14; \
1526+ tmp3 &= 0x3FC; \
1527+ tmp4 = L >> 22; \
1528+ tmp4 &= 0x3FC; \
1529+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1530+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1531+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1532+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1533+ tmp3 ^= tmp2; \
1534+ R ^= data.ctx.P[N + 1]; \
1535+ tmp3 += tmp1; \
1536+ R ^= tmp3;
1537+#endif
1538+
1539+/*
1540+ * Encrypt one block, BF_N is hardcoded here.
1541+ */
1542+#define BF_ENCRYPT \
1543+ L ^= data.ctx.P[0]; \
1544+ BF_ROUND(L, R, 0); \
1545+ BF_ROUND(R, L, 1); \
1546+ BF_ROUND(L, R, 2); \
1547+ BF_ROUND(R, L, 3); \
1548+ BF_ROUND(L, R, 4); \
1549+ BF_ROUND(R, L, 5); \
1550+ BF_ROUND(L, R, 6); \
1551+ BF_ROUND(R, L, 7); \
1552+ BF_ROUND(L, R, 8); \
1553+ BF_ROUND(R, L, 9); \
1554+ BF_ROUND(L, R, 10); \
1555+ BF_ROUND(R, L, 11); \
1556+ BF_ROUND(L, R, 12); \
1557+ BF_ROUND(R, L, 13); \
1558+ BF_ROUND(L, R, 14); \
1559+ BF_ROUND(R, L, 15); \
1560+ tmp4 = R; \
1561+ R = L; \
1562+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1563+
1564+#if BF_ASM
1565+#define BF_body() \
1566+ _BF_body_r(&data.ctx);
1567+#else
1568+#define BF_body() \
1569+ L = R = 0; \
1570+ ptr = data.ctx.P; \
1571+ do { \
1572+ ptr += 2; \
1573+ BF_ENCRYPT; \
1574+ *(ptr - 2) = L; \
1575+ *(ptr - 1) = R; \
1576+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1577+\
1578+ ptr = data.ctx.S[0]; \
1579+ do { \
1580+ ptr += 2; \
1581+ BF_ENCRYPT; \
1582+ *(ptr - 2) = L; \
1583+ *(ptr - 1) = R; \
1584+ } while (ptr < &data.ctx.S[3][0xFF]);
1585+#endif
1586+
1587+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1588+{
1589+ __CONST char *ptr = key;
1590+ int i, j;
1591+ BF_word tmp;
1592+
1593+ for (i = 0; i < BF_N + 2; i++) {
1594+ tmp = 0;
1595+ for (j = 0; j < 4; j++) {
1596+ tmp <<= 8;
1597+ tmp |= *ptr;
1598+
1599+ if (!*ptr) ptr = key; else ptr++;
1600+ }
1601+
1602+ expanded[i] = tmp;
1603+ initial[i] = BF_init_state.P[i] ^ tmp;
1604+ }
1605+}
1606+
1607+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
1608+ char *output, int size)
1609+{
1610+#if BF_ASM
1611+ extern void _BF_body_r(BF_ctx *ctx);
1612+#endif
1613+ struct {
1614+ BF_ctx ctx;
1615+ BF_key expanded_key;
1616+ union {
1617+ BF_word salt[4];
1618+ BF_word output[6];
1619+ } binary;
1620+ } data;
1621+ BF_word L, R;
1622+ BF_word tmp1, tmp2, tmp3, tmp4;
1623+ BF_word *ptr;
1624+ BF_word count;
1625+ int i;
1626+
1627+ if (size < 7 + 22 + 31 + 1) {
1628+ __set_errno(ERANGE);
1629+ return NULL;
1630+ }
1631+
1632+ if (setting[0] != '$' ||
1633+ setting[1] != '2' ||
1634+ setting[2] != 'a' ||
1635+ setting[3] != '$' ||
1636+ setting[4] < '0' || setting[4] > '3' ||
1637+ setting[5] < '0' || setting[5] > '9' ||
1638+ setting[6] != '$') {
1639+ __set_errno(EINVAL);
1640+ return NULL;
1641+ }
1642+
1643+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
1644+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
1645+ clean(data.binary.salt, sizeof(data.binary.salt));
1646+ __set_errno(EINVAL);
1647+ return NULL;
1648+ }
1649+
1650+ BF_swap(data.binary.salt, 4);
1651+
1652+ BF_set_key(key, data.expanded_key, data.ctx.P);
1653+
1654+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
1655+
1656+ L = R = 0;
1657+ for (i = 0; i < BF_N + 2; i += 2) {
1658+ L ^= data.binary.salt[i & 2];
1659+ R ^= data.binary.salt[(i & 2) + 1];
1660+ BF_ENCRYPT;
1661+ data.ctx.P[i] = L;
1662+ data.ctx.P[i + 1] = R;
1663+ }
1664+
1665+ ptr = data.ctx.S[0];
1666+ do {
1667+ ptr += 4;
1668+ L ^= data.binary.salt[(BF_N + 2) & 3];
1669+ R ^= data.binary.salt[(BF_N + 3) & 3];
1670+ BF_ENCRYPT;
1671+ *(ptr - 4) = L;
1672+ *(ptr - 3) = R;
1673+
1674+ L ^= data.binary.salt[(BF_N + 4) & 3];
1675+ R ^= data.binary.salt[(BF_N + 5) & 3];
1676+ BF_ENCRYPT;
1677+ *(ptr - 2) = L;
1678+ *(ptr - 1) = R;
1679+ } while (ptr < &data.ctx.S[3][0xFF]);
1680+
1681+ do {
1682+ data.ctx.P[0] ^= data.expanded_key[0];
1683+ data.ctx.P[1] ^= data.expanded_key[1];
1684+ data.ctx.P[2] ^= data.expanded_key[2];
1685+ data.ctx.P[3] ^= data.expanded_key[3];
1686+ data.ctx.P[4] ^= data.expanded_key[4];
1687+ data.ctx.P[5] ^= data.expanded_key[5];
1688+ data.ctx.P[6] ^= data.expanded_key[6];
1689+ data.ctx.P[7] ^= data.expanded_key[7];
1690+ data.ctx.P[8] ^= data.expanded_key[8];
1691+ data.ctx.P[9] ^= data.expanded_key[9];
1692+ data.ctx.P[10] ^= data.expanded_key[10];
1693+ data.ctx.P[11] ^= data.expanded_key[11];
1694+ data.ctx.P[12] ^= data.expanded_key[12];
1695+ data.ctx.P[13] ^= data.expanded_key[13];
1696+ data.ctx.P[14] ^= data.expanded_key[14];
1697+ data.ctx.P[15] ^= data.expanded_key[15];
1698+ data.ctx.P[16] ^= data.expanded_key[16];
1699+ data.ctx.P[17] ^= data.expanded_key[17];
1700+
1701+ BF_body();
1702+
1703+ tmp1 = data.binary.salt[0];
1704+ tmp2 = data.binary.salt[1];
1705+ tmp3 = data.binary.salt[2];
1706+ tmp4 = data.binary.salt[3];
1707+ data.ctx.P[0] ^= tmp1;
1708+ data.ctx.P[1] ^= tmp2;
1709+ data.ctx.P[2] ^= tmp3;
1710+ data.ctx.P[3] ^= tmp4;
1711+ data.ctx.P[4] ^= tmp1;
1712+ data.ctx.P[5] ^= tmp2;
1713+ data.ctx.P[6] ^= tmp3;
1714+ data.ctx.P[7] ^= tmp4;
1715+ data.ctx.P[8] ^= tmp1;
1716+ data.ctx.P[9] ^= tmp2;
1717+ data.ctx.P[10] ^= tmp3;
1718+ data.ctx.P[11] ^= tmp4;
1719+ data.ctx.P[12] ^= tmp1;
1720+ data.ctx.P[13] ^= tmp2;
1721+ data.ctx.P[14] ^= tmp3;
1722+ data.ctx.P[15] ^= tmp4;
1723+ data.ctx.P[16] ^= tmp1;
1724+ data.ctx.P[17] ^= tmp2;
1725+
1726+ BF_body();
1727+ } while (--count);
1728+
1729+ for (i = 0; i < 6; i += 2) {
1730+ L = BF_magic_w[i];
1731+ R = BF_magic_w[i + 1];
1732+
1733+ count = 64;
1734+ do {
1735+ BF_ENCRYPT;
1736+ } while (--count);
1737+
1738+ data.binary.output[i] = L;
1739+ data.binary.output[i + 1] = R;
1740+ }
1741+
1742+ memcpy(output, setting, 7 + 22 - 1);
1743+ output[7 + 22 - 1] = BF_itoa64[(int)
1744+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
1745+
1746+/* This has to be bug-compatible with the original implementation, so
1747+ * only encode 23 of the 24 bytes. :-) */
1748+ BF_swap(data.binary.output, 6);
1749+ BF_encode(&output[7 + 22], data.binary.output, 23);
1750+ output[7 + 22 + 31] = '\0';
1751+
1752+/* Overwrite the most obvious sensitive data we have on the stack. Note
1753+ * that this does not guarantee there's no sensitive data left on the
1754+ * stack and/or in registers; I'm not aware of portable code that does. */
1755+ clean(&data, sizeof(data));
1756+
1757+ return output;
1758+}
1759+
1760+char *_crypt_gensalt_blowfish_rn(unsigned long count,
1761+ __CONST char *input, int size, char *output, int output_size)
1762+{
1763+ if (size < 16 || output_size < 7 + 22 + 1 ||
1764+ (count && (count < 4 || count > 31))) {
1765+ if (output_size > 0) output[0] = '\0';
1766+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
1767+ return NULL;
1768+ }
1769+
1770+ if (!count) count = 5;
1771+
1772+ output[0] = '$';
1773+ output[1] = '2';
1774+ output[2] = 'a';
1775+ output[3] = '$';
1776+ output[4] = '0' + count / 10;
1777+ output[5] = '0' + count % 10;
1778+ output[6] = '$';
1779+
1780+ BF_encode(&output[7], (BF_word *)input, 16);
1781+ output[7 + 22] = '\0';
1782+
1783+ return output;
1784+}
1785diff -Nura php-4.4.1/ext/standard/crypt.c hardening-patch-4.4.1-0.4.5/ext/standard/crypt.c
1786--- php-4.4.1/ext/standard/crypt.c 2004-01-19 04:16:04.000000000 +0100
1787+++ hardening-patch-4.4.1-0.4.5/ext/standard/crypt.c 2005-10-30 17:12:13.000000000 +0100
1788@@ -100,6 +100,8 @@
1789 return SUCCESS;
1790 }
1791
1792+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
1793+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
1794
1795 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1796
1797@@ -135,7 +137,14 @@
1798
1799 /* The automatic salt generation only covers standard DES and md5-crypt */
1800 if(!*salt) {
1801-#if PHP_MD5_CRYPT
1802+#if PHP_BLOWFISH_CRYPT
1803+ char randat[16];
1804+ int i;
1805+
1806+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
1807+
1808+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
1809+#elif PHP_MD5_CRYPT
1810 strcpy(salt, "$1$");
1811 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
1812 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
1813@@ -145,8 +154,24 @@
1814 salt[2] = '\0';
1815 #endif
1816 }
1817-
1818- RETVAL_STRING(crypt(str, salt), 1);
1819+
1820+ if (salt[0] == '$' &&
1821+ salt[1] == '2' &&
1822+ salt[2] == 'a' &&
1823+ salt[3] == '$' &&
1824+ salt[4] >= '0' && salt[4] <= '3' &&
1825+ salt[5] >= '0' && salt[5] <= '9' &&
1826+ salt[6] == '$') {
1827+
1828+ char output[PHP_MAX_SALT_LEN+1];
1829+
1830+ output[0] = 0;
1831+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
1832+ RETVAL_STRING(output, 1);
1833+
1834+ } else {
1835+ RETVAL_STRING(crypt(str, salt), 1);
1836+ }
1837 }
1838 /* }}} */
1839 #endif
1840diff -Nura php-4.4.1/ext/standard/dl.c hardening-patch-4.4.1-0.4.5/ext/standard/dl.c
1841--- php-4.4.1/ext/standard/dl.c 2005-07-25 15:08:32.000000000 +0200
1842+++ hardening-patch-4.4.1-0.4.5/ext/standard/dl.c 2005-10-30 17:12:13.000000000 +0100
1843@@ -160,8 +160,35 @@
1844 RETURN_FALSE;
1845 }
1846 module_entry = get_module();
1847+
1848+ /* check if Hardening-Patch is installed */
1849+ if (module_entry->zend_api < 1000000000) {
1850+ php_error_docref(NULL TSRMLS_CC, error_type,
1851+ "%s: Unable to initialize module\n"
1852+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
1853+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1854+ "These options need to match\n",
1855+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
1856+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1857+ DL_UNLOAD(handle);
1858+ RETURN_FALSE;
1859+ }
1860+
1861+ /* check if correct Hardening-Patch is installed */
1862+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
1863+ php_error_docref(NULL TSRMLS_CC, error_type,
1864+ "%s: Unable to initialize module\n"
1865+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1866+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1867+ "These options need to match\n",
1868+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
1869+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1870+ DL_UNLOAD(handle);
1871+ RETURN_FALSE;
1872+ }
1873+
1874 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
1875- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
1876+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
1877 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
1878 struct pre_4_1_0_module_entry {
1879 char *name;
1880@@ -195,7 +222,7 @@
1881 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
1882 } else {
1883 name = module_entry->name;
1884- zend_api = module_entry->zend_api;
1885+ zend_api = module_entry->real_zend_api;
1886 zend_debug = module_entry->zend_debug;
1887 zts = module_entry->zts;
1888 }
1889diff -Nura php-4.4.1/ext/standard/file.c hardening-patch-4.4.1-0.4.5/ext/standard/file.c
1890--- php-4.4.1/ext/standard/file.c 2005-07-26 11:32:57.000000000 +0200
1891+++ hardening-patch-4.4.1-0.4.5/ext/standard/file.c 2005-10-30 17:12:13.000000000 +0100
1892@@ -2522,7 +2522,7 @@
1893 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1894 /* {{{ proto string realpath(string path)
1895 Return the resolved path */
1896-PHP_FUNCTION(realpath)
1897+PHP_FUNCTION(real_path)
1898 {
1899 zval **path;
1900 char resolved_path_buff[MAXPATHLEN];
1901diff -Nura php-4.4.1/ext/standard/file.h hardening-patch-4.4.1-0.4.5/ext/standard/file.h
1902--- php-4.4.1/ext/standard/file.h 2004-06-21 21:33:47.000000000 +0200
1903+++ hardening-patch-4.4.1-0.4.5/ext/standard/file.h 2005-10-30 17:12:13.000000000 +0100
1904@@ -64,7 +64,7 @@
1905 PHP_FUNCTION(fd_set);
1906 PHP_FUNCTION(fd_isset);
1907 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1908-PHP_FUNCTION(realpath);
1909+PHP_FUNCTION(real_path);
1910 #endif
1911 #ifdef HAVE_FNMATCH
1912 PHP_FUNCTION(fnmatch);
1913diff -Nura php-4.4.1/ext/standard/head.c hardening-patch-4.4.1-0.4.5/ext/standard/head.c
1914--- php-4.4.1/ext/standard/head.c 2005-07-27 13:22:36.000000000 +0200
1915+++ hardening-patch-4.4.1-0.4.5/ext/standard/head.c 2005-10-30 17:12:13.000000000 +0100
1916@@ -40,10 +40,31 @@
1917 {
1918 zend_bool rep = 1;
1919 sapi_header_line ctr = {0};
1920+#if HARDENING_PATCH
1921+ int i;
1922+#endif
1923
1924 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
1925 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
1926 return;
1927+
1928+#if HARDENING_PATCH
1929+ if (!HG(hphp_multiheader)) {
1930+ for (i=0; i<ctr.line_len; i++) {
1931+ if (ctr.line[i]==0) {
1932+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
1933+ ctr.line_len=i;
1934+ break;
1935+ } else if (ctr.line[i]=='\n') {
1936+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
1937+ continue;
1938+ }
1939+ php_security_log(S_MISC, "header(): headerline contains more than one header");
1940+ ctr.line_len=i;
1941+ }
1942+ }
1943+ }
1944+#endif
1945
1946 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
1947 }
1948diff -Nura php-4.4.1/ext/standard/info.c hardening-patch-4.4.1-0.4.5/ext/standard/info.c
1949--- php-4.4.1/ext/standard/info.c 2005-08-16 02:26:02.000000000 +0200
1950+++ hardening-patch-4.4.1-0.4.5/ext/standard/info.c 2005-11-01 15:17:58.000000000 +0100
1951@@ -408,7 +408,7 @@
1952
1953 if (flag & PHP_INFO_GENERAL) {
1954 char *zend_version = get_zend_version();
1955- char temp_api[9];
1956+ char temp_api[11];
1957
1958 php_uname = php_get_uname('a');
1959
1960@@ -430,11 +430,22 @@
1961 }
1962 }
1963
1964+#if HARDENING_PATCH
1965+ if (!sapi_module.phpinfo_as_text) {
1966+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
1967+ } else {
1968+ char temp_ver[40];
1969+
1970+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
1971+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
1972+ }
1973+#else
1974 if (!sapi_module.phpinfo_as_text) {
1975 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
1976 } else {
1977 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1978 }
1979+#endif
1980 php_info_print_box_end();
1981 php_info_print_table_start();
1982 php_info_print_table_row(2, "System", php_uname );
1983diff -Nura php-4.4.1/ext/standard/php_standard.h hardening-patch-4.4.1-0.4.5/ext/standard/php_standard.h
1984--- php-4.4.1/ext/standard/php_standard.h 2002-12-31 17:35:33.000000000 +0100
1985+++ hardening-patch-4.4.1-0.4.5/ext/standard/php_standard.h 2005-10-30 17:12:13.000000000 +0100
1986@@ -28,6 +28,7 @@
1987 #include "php_mail.h"
1988 #include "md5.h"
1989 #include "sha1.h"
1990+#include "sha256.h"
1991 #include "html.h"
1992 #include "exec.h"
1993 #include "file.h"
1994diff -Nura php-4.4.1/ext/standard/sha256.c hardening-patch-4.4.1-0.4.5/ext/standard/sha256.c
1995--- php-4.4.1/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
1996+++ hardening-patch-4.4.1-0.4.5/ext/standard/sha256.c 2005-10-30 17:12:13.000000000 +0100
1997@@ -0,0 +1,398 @@
1998+/*
1999+ +----------------------------------------------------------------------+
2000+ | PHP Version 5 |
2001+ +----------------------------------------------------------------------+
2002+ | Copyright (c) 1997-2004 The PHP Group |
2003+ +----------------------------------------------------------------------+
2004+ | This source file is subject to version 3.0 of the PHP license, |
2005+ | that is bundled with this package in the file LICENSE, and is |
2006+ | available through the world-wide-web at the following url: |
2007+ | http://www.php.net/license/3_0.txt. |
2008+ | If you did not receive a copy of the PHP license and are unable to |
2009+ | obtain it through the world-wide-web, please send a note to |
2010+ | license@php.net so we can mail you a copy immediately. |
2011+ +----------------------------------------------------------------------+
2012+ | Author: Stefan Esser <sesser@php.net> |
2013+ +----------------------------------------------------------------------+
2014+*/
2015+
2016+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2017+
2018+#include <stdio.h>
2019+#include "php.h"
2020+
2021+/* This code is heavily based on the PHP md5/sha1 implementations */
2022+
2023+#include "sha256.h"
2024+
2025+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2026+{
2027+ int i;
2028+
2029+ for (i = 0; i < 32; i++) {
2030+ sprintf(sha256str, "%02x", digest[i]);
2031+ sha256str += 2;
2032+ }
2033+
2034+ *sha256str = '\0';
2035+}
2036+
2037+/* {{{ proto string sha256(string str [, bool raw_output])
2038+ Calculate the sha256 hash of a string */
2039+PHP_FUNCTION(sha256)
2040+{
2041+ char *arg;
2042+ int arg_len;
2043+ zend_bool raw_output = 0;
2044+ char sha256str[65];
2045+ PHP_SHA256_CTX context;
2046+ unsigned char digest[32];
2047+
2048+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2049+ return;
2050+ }
2051+
2052+ sha256str[0] = '\0';
2053+ PHP_SHA256Init(&context);
2054+ PHP_SHA256Update(&context, arg, arg_len);
2055+ PHP_SHA256Final(digest, &context);
2056+ if (raw_output) {
2057+ RETURN_STRINGL(digest, 32, 1);
2058+ } else {
2059+ make_sha256_digest(sha256str, digest);
2060+ RETVAL_STRING(sha256str, 1);
2061+ }
2062+
2063+}
2064+
2065+/* }}} */
2066+
2067+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2068+ Calculate the sha256 hash of given filename */
2069+PHP_FUNCTION(sha256_file)
2070+{
2071+ char *arg;
2072+ int arg_len;
2073+ zend_bool raw_output = 0;
2074+ char sha256str[65];
2075+ unsigned char buf[1024];
2076+ unsigned char digest[32];
2077+ PHP_SHA256_CTX context;
2078+ int n;
2079+ FILE *fp;
2080+
2081+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2082+ return;
2083+ }
2084+
2085+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2086+ RETURN_FALSE;
2087+ }
2088+
2089+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2090+ RETURN_FALSE;
2091+ }
2092+
2093+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2094+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2095+ RETURN_FALSE;
2096+ }
2097+
2098+ PHP_SHA256Init(&context);
2099+
2100+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2101+ PHP_SHA256Update(&context, buf, n);
2102+ }
2103+
2104+ PHP_SHA256Final(digest, &context);
2105+
2106+ if (ferror(fp)) {
2107+ fclose(fp);
2108+ RETURN_FALSE;
2109+ }
2110+
2111+ fclose(fp);
2112+
2113+ if (raw_output) {
2114+ RETURN_STRINGL(digest, 32, 1);
2115+ } else {
2116+ make_sha256_digest(sha256str, digest);
2117+ RETVAL_STRING(sha256str, 1);
2118+ }
2119+}
2120+/* }}} */
2121+
2122+
2123+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2124+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2125+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2126+
2127+static unsigned char PADDING[64] =
2128+{
2129+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2130+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2131+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2132+};
2133+
2134+/* F, G, H and I are basic SHA256 functions.
2135+ */
2136+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2137+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2138+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2139+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2140+
2141+/* ROTATE_RIGHT rotates x right n bits.
2142+ */
2143+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2144+
2145+/* W[i]
2146+ */
2147+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2148+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2149+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2150+
2151+/* ROUND function of sha256
2152+ */
2153+
2154+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2155+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2156+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2157+ (d) += t1; \
2158+ }
2159+
2160+
2161+/* {{{ PHP_SHA256Init
2162+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2163+ */
2164+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2165+{
2166+ context->count[0] = context->count[1] = 0;
2167+ /* Load magic initialization constants.
2168+ */
2169+ context->state[0] = 0x6a09e667;
2170+ context->state[1] = 0xbb67ae85;
2171+ context->state[2] = 0x3c6ef372;
2172+ context->state[3] = 0xa54ff53a;
2173+ context->state[4] = 0x510e527f;
2174+ context->state[5] = 0x9b05688c;
2175+ context->state[6] = 0x1f83d9ab;
2176+ context->state[7] = 0x5be0cd19;
2177+}
2178+/* }}} */
2179+
2180+/* {{{ PHP_SHA256Update
2181+ SHA256 block update operation. Continues an SHA256 message-digest
2182+ operation, processing another message block, and updating the
2183+ context.
2184+ */
2185+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2186+ unsigned int inputLen)
2187+{
2188+ unsigned int i, index, partLen;
2189+
2190+ /* Compute number of bytes mod 64 */
2191+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2192+
2193+ /* Update number of bits */
2194+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2195+ < ((php_uint32) inputLen << 3))
2196+ context->count[1]++;
2197+ context->count[1] += ((php_uint32) inputLen >> 29);
2198+
2199+ partLen = 64 - index;
2200+
2201+ /* Transform as many times as possible.
2202+ */
2203+ if (inputLen >= partLen) {
2204+ memcpy
2205+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2206+ SHA256Transform(context->state, context->buffer);
2207+
2208+ for (i = partLen; i + 63 < inputLen; i += 64)
2209+ SHA256Transform(context->state, &input[i]);
2210+
2211+ index = 0;
2212+ } else
2213+ i = 0;
2214+
2215+ /* Buffer remaining input */
2216+ memcpy
2217+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2218+ inputLen - i);
2219+}
2220+/* }}} */
2221+
2222+/* {{{ PHP_SHA256Final
2223+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2224+ the message digest and zeroizing the context.
2225+ */
2226+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2227+{
2228+ unsigned char bits[8];
2229+ unsigned int index, padLen;
2230+
2231+ /* Save number of bits */
2232+ bits[7] = context->count[0] & 0xFF;
2233+ bits[6] = (context->count[0] >> 8) & 0xFF;
2234+ bits[5] = (context->count[0] >> 16) & 0xFF;
2235+ bits[4] = (context->count[0] >> 24) & 0xFF;
2236+ bits[3] = context->count[1] & 0xFF;
2237+ bits[2] = (context->count[1] >> 8) & 0xFF;
2238+ bits[1] = (context->count[1] >> 16) & 0xFF;
2239+ bits[0] = (context->count[1] >> 24) & 0xFF;
2240+
2241+ /* Pad out to 56 mod 64.
2242+ */
2243+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2244+ padLen = (index < 56) ? (56 - index) : (120 - index);
2245+ PHP_SHA256Update(context, PADDING, padLen);
2246+
2247+ /* Append length (before padding) */
2248+ PHP_SHA256Update(context, bits, 8);
2249+
2250+ /* Store state in digest */
2251+ SHA256Encode(digest, context->state, 32);
2252+
2253+ /* Zeroize sensitive information.
2254+ */
2255+ memset((unsigned char*) context, 0, sizeof(*context));
2256+}
2257+/* }}} */
2258+
2259+/* {{{ SHA256Transform
2260+ * SHA256 basic transformation. Transforms state based on block.
2261+ */
2262+static void SHA256Transform(state, block)
2263+php_uint32 state[8];
2264+const unsigned char block[64];
2265+{
2266+ php_uint32 a = state[0], b = state[1], c = state[2];
2267+ php_uint32 d = state[3], e = state[4], f = state[5];
2268+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2269+
2270+ SHA256Decode(x, block, 64);
2271+
2272+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2273+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2274+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2275+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2276+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2277+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2278+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2279+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2280+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2281+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2282+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2283+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2284+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2285+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2286+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2287+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2288+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2289+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2290+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2291+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2292+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2293+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2294+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2295+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2296+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2297+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2298+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2299+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2300+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2301+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2302+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2303+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2304+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2305+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2306+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2307+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2308+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2309+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2310+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2311+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2312+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2313+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2314+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2315+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2316+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2317+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2318+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2319+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2320+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2321+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2322+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2323+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2324+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2325+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2326+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2327+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2328+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2329+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2330+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2331+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2332+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2333+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2334+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2335+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2336+
2337+ state[0] += a;
2338+ state[1] += b;
2339+ state[2] += c;
2340+ state[3] += d;
2341+ state[4] += e;
2342+ state[5] += f;
2343+ state[6] += g;
2344+ state[7] += h;
2345+
2346+ /* Zeroize sensitive information. */
2347+ memset((unsigned char*) x, 0, sizeof(x));
2348+}
2349+/* }}} */
2350+
2351+/* {{{ SHA256Encode
2352+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2353+ a multiple of 4.
2354+ */
2355+static void SHA256Encode(output, input, len)
2356+unsigned char *output;
2357+php_uint32 *input;
2358+unsigned int len;
2359+{
2360+ unsigned int i, j;
2361+
2362+ for (i = 0, j = 0; j < len; i++, j += 4) {
2363+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2364+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2365+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2366+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2367+ }
2368+}
2369+/* }}} */
2370+
2371+/* {{{ SHA256Decode
2372+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2373+ a multiple of 4.
2374+ */
2375+static void SHA256Decode(output, input, len)
2376+php_uint32 *output;
2377+const unsigned char *input;
2378+unsigned int len;
2379+{
2380+ unsigned int i, j;
2381+
2382+ for (i = 0, j = 0; j < len; i++, j += 4)
2383+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2384+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2385+}
2386+/* }}} */
2387+
2388+/*
2389+ * Local variables:
2390+ * tab-width: 4
2391+ * c-basic-offset: 4
2392+ * End:
2393+ * vim600: sw=4 ts=4 fdm=marker
2394+ * vim<600: sw=4 ts=4
2395+ */
2396diff -Nura php-4.4.1/ext/standard/sha256.h hardening-patch-4.4.1-0.4.5/ext/standard/sha256.h
2397--- php-4.4.1/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2398+++ hardening-patch-4.4.1-0.4.5/ext/standard/sha256.h 2005-10-30 17:12:13.000000000 +0100
2399@@ -0,0 +1,40 @@
2400+/*
2401+ +----------------------------------------------------------------------+
2402+ | PHP Version 5 |
2403+ +----------------------------------------------------------------------+
2404+ | Copyright (c) 1997-2004 The PHP Group |
2405+ +----------------------------------------------------------------------+
2406+ | This source file is subject to version 3.0 of the PHP license, |
2407+ | that is bundled with this package in the file LICENSE, and is |
2408+ | available through the world-wide-web at the following url: |
2409+ | http://www.php.net/license/3_0.txt. |
2410+ | If you did not receive a copy of the PHP license and are unable to |
2411+ | obtain it through the world-wide-web, please send a note to |
2412+ | license@php.net so we can mail you a copy immediately. |
2413+ +----------------------------------------------------------------------+
2414+ | Author: Stefan Esser <sesser@php.net> |
2415+ +----------------------------------------------------------------------+
2416+*/
2417+
2418+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2419+
2420+#ifndef SHA256_H
2421+#define SHA256_H
2422+
2423+#include "ext/standard/basic_functions.h"
2424+
2425+/* SHA1 context. */
2426+typedef struct {
2427+ php_uint32 state[8]; /* state (ABCD) */
2428+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2429+ unsigned char buffer[64]; /* input buffer */
2430+} PHP_SHA256_CTX;
2431+
2432+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2433+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2434+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2435+
2436+PHP_FUNCTION(sha256);
2437+PHP_FUNCTION(sha256_file);
2438+
2439+#endif
2440diff -Nura php-4.4.1/ext/standard/syslog.c hardening-patch-4.4.1-0.4.5/ext/standard/syslog.c
2441--- php-4.4.1/ext/standard/syslog.c 2004-07-30 16:38:29.000000000 +0200
2442+++ hardening-patch-4.4.1-0.4.5/ext/standard/syslog.c 2005-10-30 17:12:13.000000000 +0100
2443@@ -42,6 +42,8 @@
2444 */
2445 PHP_MINIT_FUNCTION(syslog)
2446 {
2447+
2448+#if !HARDENING_PATCH
2449 /* error levels */
2450 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2451 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2452@@ -97,7 +99,7 @@
2453 /* AIX doesn't have LOG_PERROR */
2454 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2455 #endif
2456-
2457+#endif
2458 return SUCCESS;
2459 }
2460 /* }}} */
2461diff -Nura php-4.4.1/ext/varfilter/config.m4 hardening-patch-4.4.1-0.4.5/ext/varfilter/config.m4
2462--- php-4.4.1/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2463+++ hardening-patch-4.4.1-0.4.5/ext/varfilter/config.m4 2005-10-30 17:12:13.000000000 +0100
2464@@ -0,0 +1,11 @@
2465+dnl
2466+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2467+dnl
2468+
2469+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2470+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2471+
2472+if test "$PHP_VARFILTER" != "no"; then
2473+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2474+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2475+fi
2476diff -Nura php-4.4.1/ext/varfilter/CREDITS hardening-patch-4.4.1-0.4.5/ext/varfilter/CREDITS
2477--- php-4.4.1/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2478+++ hardening-patch-4.4.1-0.4.5/ext/varfilter/CREDITS 2005-10-30 17:12:13.000000000 +0100
2479@@ -0,0 +1,2 @@
2480+varfilter
2481+Stefan Esser
2482\ Kein Zeilenumbruch am Dateiende.
2483diff -Nura php-4.4.1/ext/varfilter/php_varfilter.h hardening-patch-4.4.1-0.4.5/ext/varfilter/php_varfilter.h
2484--- php-4.4.1/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2485+++ hardening-patch-4.4.1-0.4.5/ext/varfilter/php_varfilter.h 2005-11-01 15:48:03.000000000 +0100
2486@@ -0,0 +1,122 @@
2487+/*
2488+ +----------------------------------------------------------------------+
2489+ | Hardened-PHP Project's varfilter extension |
2490+ +----------------------------------------------------------------------+
2491+ | Copyright (c) 2004-2005 Stefan Esser |
2492+ +----------------------------------------------------------------------+
2493+ | This source file is subject to version 2.02 of the PHP license, |
2494+ | that is bundled with this package in the file LICENSE, and is |
2495+ | available at through the world-wide-web at |
2496+ | http://www.php.net/license/2_02.txt. |
2497+ | If you did not receive a copy of the PHP license and are unable to |
2498+ | obtain it through the world-wide-web, please send a note to |
2499+ | license@php.net so we can mail you a copy immediately. |
2500+ +----------------------------------------------------------------------+
2501+ | Author: Stefan Esser <sesser@hardened-php.net> |
2502+ +----------------------------------------------------------------------+
2503+
2504+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2505+*/
2506+
2507+#ifndef PHP_VARFILTER_H
2508+#define PHP_VARFILTER_H
2509+
2510+extern zend_module_entry varfilter_module_entry;
2511+#define phpext_varfilter_ptr &varfilter_module_entry
2512+
2513+#ifdef PHP_WIN32
2514+#define PHP_VARFILTER_API __declspec(dllexport)
2515+#else
2516+#define PHP_VARFILTER_API
2517+#endif
2518+
2519+#ifdef ZTS
2520+#include "TSRM.h"
2521+#endif
2522+
2523+#include "SAPI.h"
2524+
2525+#include "php_variables.h"
2526+
2527+
2528+PHP_MINIT_FUNCTION(varfilter);
2529+PHP_MSHUTDOWN_FUNCTION(varfilter);
2530+PHP_RINIT_FUNCTION(varfilter);
2531+PHP_RSHUTDOWN_FUNCTION(varfilter);
2532+PHP_MINFO_FUNCTION(varfilter);
2533+
2534+
2535+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2536+/* request variables */
2537+ long max_request_variables;
2538+ long cur_request_variables;
2539+ long max_varname_length;
2540+ long max_totalname_length;
2541+ long max_value_length;
2542+ long max_array_depth;
2543+ long max_array_index_length;
2544+ zend_bool disallow_nul;
2545+/* cookie variables */
2546+ long max_cookie_vars;
2547+ long cur_cookie_vars;
2548+ long max_cookie_name_length;
2549+ long max_cookie_totalname_length;
2550+ long max_cookie_value_length;
2551+ long max_cookie_array_depth;
2552+ long max_cookie_array_index_length;
2553+ zend_bool disallow_cookie_nul;
2554+/* get variables */
2555+ long max_get_vars;
2556+ long cur_get_vars;
2557+ long max_get_name_length;
2558+ long max_get_totalname_length;
2559+ long max_get_value_length;
2560+ long max_get_array_depth;
2561+ long max_get_array_index_length;
2562+ zend_bool disallow_get_nul;
2563+/* post variables */
2564+ long max_post_vars;
2565+ long cur_post_vars;
2566+ long max_post_name_length;
2567+ long max_post_totalname_length;
2568+ long max_post_value_length;
2569+ long max_post_array_depth;
2570+ long max_post_array_index_length;
2571+ zend_bool disallow_post_nul;
2572+/* fileupload */
2573+ long max_uploads;
2574+ long cur_uploads;
2575+ zend_bool disallow_elf_files;
2576+ char *verification_script;
2577+
2578+ zend_bool no_more_variables;
2579+ zend_bool no_more_get_variables;
2580+ zend_bool no_more_post_variables;
2581+ zend_bool no_more_cookie_variables;
2582+ zend_bool no_more_uploads;
2583+
2584+ZEND_END_MODULE_GLOBALS(varfilter)
2585+
2586+
2587+#ifdef ZTS
2588+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2589+#else
2590+#define VARFILTER_G(v) (varfilter_globals.v)
2591+#endif
2592+
2593+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2594+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
2595+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
2596+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
2597+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
2598+
2599+#endif /* PHP_VARFILTER_H */
2600+
2601+
2602+/*
2603+ * Local variables:
2604+ * tab-width: 4
2605+ * c-basic-offset: 4
2606+ * indent-tabs-mode: t
2607+ * End:
2608+ */
2609diff -Nura php-4.4.1/ext/varfilter/varfilter.c hardening-patch-4.4.1-0.4.5/ext/varfilter/varfilter.c
2610--- php-4.4.1/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2611+++ hardening-patch-4.4.1-0.4.5/ext/varfilter/varfilter.c 2005-11-01 15:52:23.000000000 +0100
2612@@ -0,0 +1,809 @@
2613+/*
2614+ +----------------------------------------------------------------------+
2615+ | Hardened-PHP Project's varfilter extension |
2616+ +----------------------------------------------------------------------+
2617+ | Copyright (c) 2004-2005 Stefan Esser |
2618+ +----------------------------------------------------------------------+
2619+ | This source file is subject to version 2.02 of the PHP license, |
2620+ | that is bundled with this package in the file LICENSE, and is |
2621+ | available at through the world-wide-web at |
2622+ | http://www.php.net/license/2_02.txt. |
2623+ | If you did not receive a copy of the PHP license and are unable to |
2624+ | obtain it through the world-wide-web, please send a note to |
2625+ | license@php.net so we can mail you a copy immediately. |
2626+ +----------------------------------------------------------------------+
2627+ | Author: Stefan Esser <sesser@hardened-php.net> |
2628+ +----------------------------------------------------------------------+
2629+
2630+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2631+*/
2632+
2633+#ifdef HAVE_CONFIG_H
2634+#include "config.h"
2635+#endif
2636+
2637+#include "php.h"
2638+#include "php_ini.h"
2639+#include "ext/standard/info.h"
2640+#include "php_varfilter.h"
2641+#include "hardening_patch.h"
2642+
2643+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2644+
2645+/* True global resources - no need for thread safety here */
2646+static int le_varfilter;
2647+
2648+/* {{{ varfilter_module_entry
2649+ */
2650+zend_module_entry varfilter_module_entry = {
2651+#if ZEND_MODULE_API_NO >= 20010901
2652+ STANDARD_MODULE_HEADER,
2653+#endif
2654+ "varfilter",
2655+ NULL,
2656+ PHP_MINIT(varfilter),
2657+ PHP_MSHUTDOWN(varfilter),
2658+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2659+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2660+ PHP_MINFO(varfilter),
2661+#if ZEND_MODULE_API_NO >= 20010901
2662+ "0.4.5", /* Replace with version number for your extension */
2663+#endif
2664+ STANDARD_MODULE_PROPERTIES
2665+};
2666+/* }}} */
2667+
2668+#ifdef COMPILE_DL_VARFILTER
2669+ZEND_GET_MODULE(varfilter)
2670+#endif
2671+
2672+/* {{{ PHP_INI
2673+ */
2674+PHP_INI_BEGIN()
2675+ /* for backward compatibility */
2676+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2677+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2678+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2679+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2680+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2681+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2682+
2683+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2684+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2685+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2686+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2687+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2688+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2689+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
2690+
2691+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
2692+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
2693+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
2694+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
2695+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
2696+ 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)
2697+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
2698+
2699+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
2700+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
2701+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
2702+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
2703+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
2704+ 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)
2705+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
2706+
2707+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
2708+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
2709+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
2710+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
2711+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
2712+ 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)
2713+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
2714+
2715+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
2716+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
2717+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
2718+
2719+
2720+PHP_INI_END()
2721+/* }}} */
2722+
2723+/* {{{ php_varfilter_init_globals
2724+ */
2725+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2726+{
2727+ varfilter_globals->max_request_variables = 200;
2728+ varfilter_globals->max_varname_length = 64;
2729+ varfilter_globals->max_value_length = 10000;
2730+ varfilter_globals->max_array_depth = 100;
2731+ varfilter_globals->max_totalname_length = 256;
2732+ varfilter_globals->max_array_index_length = 64;
2733+ varfilter_globals->disallow_nul = 1;
2734+
2735+ varfilter_globals->max_cookie_vars = 100;
2736+ varfilter_globals->max_cookie_name_length = 64;
2737+ varfilter_globals->max_cookie_totalname_length = 256;
2738+ varfilter_globals->max_cookie_value_length = 10000;
2739+ varfilter_globals->max_cookie_array_depth = 100;
2740+ varfilter_globals->max_cookie_array_index_length = 64;
2741+ varfilter_globals->disallow_cookie_nul = 1;
2742+
2743+ varfilter_globals->max_get_vars = 100;
2744+ varfilter_globals->max_get_name_length = 64;
2745+ varfilter_globals->max_get_totalname_length = 256;
2746+ varfilter_globals->max_get_value_length = 512;
2747+ varfilter_globals->max_get_array_depth = 50;
2748+ varfilter_globals->max_get_array_index_length = 64;
2749+ varfilter_globals->disallow_get_nul = 1;
2750+
2751+ varfilter_globals->max_post_vars = 200;
2752+ varfilter_globals->max_post_name_length = 64;
2753+ varfilter_globals->max_post_totalname_length = 256;
2754+ varfilter_globals->max_post_value_length = 65000;
2755+ varfilter_globals->max_post_array_depth = 100;
2756+ varfilter_globals->max_post_array_index_length = 64;
2757+ varfilter_globals->disallow_post_nul = 1;
2758+
2759+ varfilter_globals->max_uploads = 25;
2760+ varfilter_globals->disallow_elf_files = 1;
2761+ varfilter_globals->verification_script = NULL;
2762+
2763+ varfilter_globals->no_more_variables = 0;
2764+ varfilter_globals->no_more_get_variables = 0;
2765+ varfilter_globals->no_more_post_variables = 0;
2766+ varfilter_globals->no_more_cookie_variables = 0;
2767+ varfilter_globals->no_more_uploads = 0;
2768+}
2769+/* }}} */
2770+
2771+/* {{{ PHP_MINIT_FUNCTION
2772+ */
2773+PHP_MINIT_FUNCTION(varfilter)
2774+{
2775+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2776+ REGISTER_INI_ENTRIES();
2777+
2778+ sapi_register_input_filter(varfilter_input_filter);
2779+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
2780+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
2781+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
2782+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
2783+
2784+ return SUCCESS;
2785+}
2786+/* }}} */
2787+
2788+/* {{{ PHP_MSHUTDOWN_FUNCTION
2789+ */
2790+PHP_MSHUTDOWN_FUNCTION(varfilter)
2791+{
2792+ UNREGISTER_INI_ENTRIES();
2793+
2794+ return SUCCESS;
2795+}
2796+/* }}} */
2797+
2798+/* Remove if there's nothing to do at request start */
2799+/* {{{ PHP_RINIT_FUNCTION
2800+ */
2801+PHP_RINIT_FUNCTION(varfilter)
2802+{
2803+ VARFILTER_G(cur_request_variables) = 0;
2804+ VARFILTER_G(cur_get_vars) = 0;
2805+ VARFILTER_G(cur_post_vars) = 0;
2806+ VARFILTER_G(cur_cookie_vars) = 0;
2807+
2808+ VARFILTER_G(cur_uploads) = 0;
2809+
2810+ VARFILTER_G(no_more_variables) = 0;
2811+ VARFILTER_G(no_more_get_variables) = 0;
2812+ VARFILTER_G(no_more_post_variables) = 0;
2813+ VARFILTER_G(no_more_cookie_variables) = 0;
2814+ VARFILTER_G(no_more_uploads) = 0;
2815+
2816+ return SUCCESS;
2817+}
2818+/* }}} */
2819+
2820+/* Remove if there's nothing to do at request end */
2821+/* {{{ PHP_RSHUTDOWN_FUNCTION
2822+ */
2823+PHP_RSHUTDOWN_FUNCTION(varfilter)
2824+{
2825+ return SUCCESS;
2826+}
2827+/* }}} */
2828+
2829+/* {{{ PHP_MINFO_FUNCTION
2830+ */
2831+PHP_MINFO_FUNCTION(varfilter)
2832+{
2833+ php_info_print_table_start();
2834+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
2835+ php_info_print_table_end();
2836+
2837+ DISPLAY_INI_ENTRIES();
2838+}
2839+/* }}} */
2840+
2841+/* {{{ normalize_varname
2842+ */
2843+static void normalize_varname(char *varname)
2844+{
2845+ char *s=varname, *index=NULL, *indexend=NULL, *p;
2846+
2847+ /* overjump leading space */
2848+ while (*s == ' ') {
2849+ s++;
2850+ }
2851+
2852+ /* and remove it */
2853+ if (s != varname) {
2854+ memmove(varname, s, strlen(s)+1);
2855+ }
2856+
2857+ for (p=varname; *p && *p != '['; p++) {
2858+ switch(*p) {
2859+ case ' ':
2860+ case '.':
2861+ *p='_';
2862+ break;
2863+ }
2864+ }
2865+
2866+ /* find index */
2867+ index = strchr(varname, '[');
2868+ if (index) {
2869+ index++;
2870+ s=index;
2871+ } else {
2872+ return;
2873+ }
2874+
2875+ /* done? */
2876+ while (index) {
2877+
2878+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
2879+ index++;
2880+ }
2881+ indexend = strchr(index, ']');
2882+ indexend = indexend ? indexend + 1 : index + strlen(index);
2883+
2884+ if (s != index) {
2885+ memmove(s, index, strlen(index)+1);
2886+ s += indexend-index;
2887+ } else {
2888+ s = indexend;
2889+ }
2890+
2891+ if (*s == '[') {
2892+ s++;
2893+ index = s;
2894+ } else {
2895+ index = NULL;
2896+ }
2897+ }
2898+ *s++='\0';
2899+}
2900+/* }}} */
2901+
2902+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
2903+ */
2904+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
2905+{
2906+ char *index, *prev_index = NULL, *var;
2907+ unsigned int var_len, total_len, depth = 0;
2908+
2909+ var = estrdup(varname);
2910+
2911+ /* Normalize the variable name */
2912+ normalize_varname(var);
2913+
2914+ /* Find length of variable name */
2915+ index = strchr(var, '[');
2916+ total_len = strlen(var);
2917+ var_len = index ? index-var : total_len;
2918+
2919+ /* Drop this variable if it exceeds the varname/total length limit */
2920+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
2921+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
2922+ goto return_failure;
2923+ }
2924+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
2925+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
2926+ goto return_failure;
2927+ }
2928+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
2929+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
2930+
2931+ goto return_failure;
2932+ }
2933+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
2934+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
2935+ goto return_failure;
2936+ }
2937+
2938+ /* Find out array depth */
2939+ while (index) {
2940+ unsigned int index_length;
2941+
2942+ depth++;
2943+ index = strchr(index+1, '[');
2944+
2945+ if (prev_index) {
2946+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
2947+
2948+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
2949+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
2950+ goto return_failure;
2951+ }
2952+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
2953+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
2954+ goto return_failure;
2955+ }
2956+ prev_index = index;
2957+ }
2958+
2959+ }
2960+
2961+ /* Drop this variable if it exceeds the array depth limit */
2962+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
2963+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
2964+ goto return_failure;
2965+ }
2966+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
2967+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
2968+ goto return_failure;
2969+ }
2970+
2971+
2972+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
2973+ /* This is to protect several silly scripts that do globalizing themself */
2974+
2975+ switch (var_len) {
2976+ case 18:
2977+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
2978+ break;
2979+ case 17:
2980+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
2981+ break;
2982+ case 16:
2983+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
2984+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
2985+ break;
2986+ case 15:
2987+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
2988+ break;
2989+ case 14:
2990+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
2991+ break;
2992+ case 13:
2993+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
2994+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
2995+ break;
2996+ case 8:
2997+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
2998+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
2999+ break;
3000+ case 7:
3001+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3002+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3003+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3004+ break;
3005+ case 6:
3006+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3007+ break;
3008+ case 5:
3009+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3010+ break;
3011+ case 4:
3012+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3013+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3014+ break;
3015+ }
3016+
3017+ efree(var);
3018+ return SUCCESS;
3019+protected_varname2:
3020+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3021+return_failure:
3022+ efree(var);
3023+ return FAILURE;
3024+}
3025+/* }}} */
3026+
3027+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3028+ */
3029+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3030+{
3031+ /* Drop if no more variables flag is set */
3032+ if (VARFILTER_G(no_more_uploads)) {
3033+ return FAILURE;
3034+ }
3035+ /* Drop this fileupload if the limit is reached */
3036+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3037+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3038+ VARFILTER_G(no_more_uploads) = 1;
3039+ return FAILURE;
3040+ }
3041+
3042+ return SUCCESS;
3043+}
3044+/* }}} */
3045+
3046+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3047+ */
3048+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3049+{
3050+
3051+ if (VARFILTER_G(disallow_elf_files)) {
3052+
3053+ if (offset == 0 && buffer_len > 10) {
3054+
3055+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3056+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3057+ return FAILURE;
3058+ }
3059+ }
3060+
3061+ }
3062+
3063+ return SUCCESS;
3064+}
3065+/* }}} */
3066+
3067+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3068+ */
3069+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3070+{
3071+ int retval = SUCCESS;
3072+
3073+ if (VARFILTER_G(verification_script)) {
3074+ char cmd[8192];
3075+ FILE *in;
3076+ int first=1;
3077+
3078+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3079+
3080+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3081+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3082+ return FAILURE;
3083+ }
3084+
3085+ retval = FAILURE;
3086+
3087+ /* read and forget the result */
3088+ while (1) {
3089+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3090+ if (readbytes<=0) {
3091+ break;
3092+ }
3093+ if (first) {
3094+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3095+ first = 0;
3096+ }
3097+ }
3098+ pclose(in);
3099+ }
3100+
3101+ if (retval != SUCCESS) {
3102+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3103+ return FAILURE;
3104+ }
3105+
3106+ VARFILTER_G(cur_uploads)++;
3107+ return SUCCESS;
3108+}
3109+/* }}} */
3110+
3111+/* {{{ SAPI_INPUT_FILTER_FUNC
3112+ */
3113+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3114+{
3115+ char *index, *prev_index = NULL;
3116+ unsigned int var_len, total_len, depth = 0;
3117+
3118+ /* Drop this variable if the limit was reached */
3119+ switch (arg) {
3120+ case PARSE_GET:
3121+ if (VARFILTER_G(no_more_get_variables)) {
3122+ return 0;
3123+ }
3124+ break;
3125+ case PARSE_POST:
3126+ if (VARFILTER_G(no_more_post_variables)) {
3127+ return 0;
3128+ }
3129+ break;
3130+ case PARSE_COOKIE:
3131+ if (VARFILTER_G(no_more_cookie_variables)) {
3132+ return 0;
3133+ }
3134+ break;
3135+ }
3136+ if (VARFILTER_G(no_more_variables)) {
3137+ return 0;
3138+ }
3139+
3140+ /* Drop this variable if the limit is now reached */
3141+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3142+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3143+ VARFILTER_G(no_more_variables) = 1;
3144+ return 0;
3145+ }
3146+ switch (arg) {
3147+ case PARSE_GET:
3148+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3149+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3150+ VARFILTER_G(no_more_get_variables) = 1;
3151+ return 0;
3152+ }
3153+ break;
3154+ case PARSE_COOKIE:
3155+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3156+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3157+ VARFILTER_G(no_more_cookie_variables) = 1;
3158+ return 0;
3159+ }
3160+ break;
3161+ case PARSE_POST:
3162+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3163+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3164+ VARFILTER_G(no_more_post_variables) = 1;
3165+ return 0;
3166+ }
3167+ break;
3168+ }
3169+
3170+
3171+ /* Drop this variable if it exceeds the value length limit */
3172+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3173+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3174+ return 0;
3175+ }
3176+ switch (arg) {
3177+ case PARSE_GET:
3178+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3179+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3180+ return 0;
3181+ }
3182+ break;
3183+ case PARSE_COOKIE:
3184+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3185+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3186+ return 0;
3187+ }
3188+ break;
3189+ case PARSE_POST:
3190+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3191+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3192+ return 0;
3193+ }
3194+ break;
3195+ }
3196+
3197+ /* Normalize the variable name */
3198+ normalize_varname(var);
3199+
3200+ /* Find length of variable name */
3201+ index = strchr(var, '[');
3202+ total_len = strlen(var);
3203+ var_len = index ? index-var : total_len;
3204+
3205+ /* Drop this variable if it exceeds the varname/total length limit */
3206+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3207+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3208+ return 0;
3209+ }
3210+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3211+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3212+ return 0;
3213+ }
3214+ switch (arg) {
3215+ case PARSE_GET:
3216+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3217+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3218+ return 0;
3219+ }
3220+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3221+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3222+ return 0;
3223+ }
3224+ break;
3225+ case PARSE_COOKIE:
3226+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3227+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3228+ return 0;
3229+ }
3230+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3231+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3232+ return 0;
3233+ }
3234+ break;
3235+ case PARSE_POST:
3236+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3237+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3238+ return 0;
3239+ }
3240+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3241+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3242+ return 0;
3243+ }
3244+ break;
3245+ }
3246+
3247+ /* Find out array depth */
3248+ while (index) {
3249+ unsigned int index_length;
3250+
3251+ depth++;
3252+ index = strchr(index+1, '[');
3253+
3254+ if (prev_index) {
3255+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3256+
3257+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3258+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3259+ return 0;
3260+ }
3261+ switch (arg) {
3262+ case PARSE_GET:
3263+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3264+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3265+ return 0;
3266+ }
3267+ break;
3268+ case PARSE_COOKIE:
3269+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3270+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3271+ return 0;
3272+ }
3273+ break;
3274+ case PARSE_POST:
3275+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3276+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3277+ return 0;
3278+ }
3279+ break;
3280+ }
3281+ prev_index = index;
3282+ }
3283+
3284+ }
3285+
3286+ /* Drop this variable if it exceeds the array depth limit */
3287+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3288+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3289+ return 0;
3290+ }
3291+ switch (arg) {
3292+ case PARSE_GET:
3293+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3294+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3295+ return 0;
3296+ }
3297+ break;
3298+ case PARSE_COOKIE:
3299+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3300+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3301+ return 0;
3302+ }
3303+ break;
3304+ case PARSE_POST:
3305+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3306+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3307+ return 0;
3308+ }
3309+ break;
3310+ }
3311+
3312+ /* Check if variable value is truncated by a \0 */
3313+
3314+ if (val && *val && val_len != strlen(*val)) {
3315+
3316+ if (VARFILTER_G(disallow_nul)) {
3317+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3318+ return 0;
3319+ }
3320+ switch (arg) {
3321+ case PARSE_GET:
3322+ if (VARFILTER_G(disallow_get_nul)) {
3323+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3324+ return 0;
3325+ }
3326+ break;
3327+ case PARSE_COOKIE:
3328+ if (VARFILTER_G(disallow_cookie_nul)) {
3329+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3330+ return 0;
3331+ }
3332+ break;
3333+ case PARSE_POST:
3334+ if (VARFILTER_G(disallow_post_nul)) {
3335+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3336+ return 0;
3337+ }
3338+ break;
3339+ }
3340+ }
3341+
3342+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3343+ /* This is to protect several silly scripts that do globalizing themself */
3344+
3345+ switch (var_len) {
3346+ case 18:
3347+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3348+ break;
3349+ case 17:
3350+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3351+ break;
3352+ case 16:
3353+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3354+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3355+ break;
3356+ case 15:
3357+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3358+ break;
3359+ case 14:
3360+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3361+ break;
3362+ case 13:
3363+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3364+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3365+ break;
3366+ case 8:
3367+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3368+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3369+ break;
3370+ case 7:
3371+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3372+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3373+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3374+ break;
3375+ case 6:
3376+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3377+ break;
3378+ case 5:
3379+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3380+ break;
3381+ case 4:
3382+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3383+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3384+ break;
3385+ }
3386+
3387+ /* Okay let PHP register this variable */
3388+ VARFILTER_G(cur_request_variables)++;
3389+ switch (arg) {
3390+ case PARSE_GET:
3391+ VARFILTER_G(cur_get_vars)++;
3392+ break;
3393+ case PARSE_COOKIE:
3394+ VARFILTER_G(cur_cookie_vars)++;
3395+ break;
3396+ case PARSE_POST:
3397+ VARFILTER_G(cur_post_vars)++;
3398+ break;
3399+ }
3400+
3401+ if (new_val_len) {
3402+ *new_val_len = val_len;
3403+ }
3404+
3405+ return 1;
3406+protected_varname:
3407+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3408+ return 0;
3409+}
3410+/* }}} */
3411+
3412+/*
3413+ * Local variables:
3414+ * tab-width: 4
3415+ * c-basic-offset: 4
3416+ * End:
3417+ * vim600: noet sw=4 ts=4 fdm=marker
3418+ * vim<600: noet sw=4 ts=4
3419+ */
3420+
3421+
3422diff -Nura php-4.4.1/main/fopen_wrappers.c hardening-patch-4.4.1-0.4.5/main/fopen_wrappers.c
3423--- php-4.4.1/main/fopen_wrappers.c 2005-09-27 17:08:43.000000000 +0200
3424+++ hardening-patch-4.4.1-0.4.5/main/fopen_wrappers.c 2005-10-30 17:12:13.000000000 +0100
3425@@ -156,6 +156,21 @@
3426 char *pathbuf;
3427 char *ptr;
3428 char *end;
3429+ char path_copy[MAXPATHLEN];
3430+ int path_len;
3431+
3432+ /* Special case path ends with a trailing slash */
3433+ path_len = strlen(path);
3434+ if (path_len >= MAXPATHLEN) {
3435+ errno = EPERM; /* we deny permission to open it */
3436+ return -1;
3437+ }
3438+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3439+ memcpy(path_copy, path, path_len+1);
3440+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3441+ path_copy[path_len] = '\0';
3442+ path = (const char *)&path_copy;
3443+ }
3444
3445 pathbuf = estrdup(PG(open_basedir));
3446
3447diff -Nura php-4.4.1/main/hardened_globals.h hardening-patch-4.4.1-0.4.5/main/hardened_globals.h
3448--- php-4.4.1/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3449+++ hardening-patch-4.4.1-0.4.5/main/hardened_globals.h 2005-10-30 17:12:13.000000000 +0100
3450@@ -0,0 +1,62 @@
3451+/*
3452+ +----------------------------------------------------------------------+
3453+ | Hardening-Patch for PHP |
3454+ +----------------------------------------------------------------------+
3455+ | Copyright (c) 2004-2005 Stefan Esser |
3456+ +----------------------------------------------------------------------+
3457+ | This source file is subject to version 2.02 of the PHP license, |
3458+ | that is bundled with this package in the file LICENSE, and is |
3459+ | available at through the world-wide-web at |
3460+ | http://www.php.net/license/2_02.txt. |
3461+ | If you did not receive a copy of the PHP license and are unable to |
3462+ | obtain it through the world-wide-web, please send a note to |
3463+ | license@php.net so we can mail you a copy immediately. |
3464+ +----------------------------------------------------------------------+
3465+ | Author: Stefan Esser <sesser@hardened-php.net> |
3466+ +----------------------------------------------------------------------+
3467+ */
3468+
3469+#ifndef HARDENED_GLOBALS_H
3470+#define HARDENED_GLOBALS_H
3471+
3472+typedef struct _hardened_globals hardened_globals_struct;
3473+
3474+#ifdef ZTS
3475+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3476+extern int hardened_globals_id;
3477+#else
3478+# define HG(v) (hardened_globals.v)
3479+extern struct _hardened_globals hardened_globals;
3480+#endif
3481+
3482+
3483+struct _hardened_globals {
3484+#if HARDENING_PATCH_MM_PROTECT
3485+ unsigned int canary_1;
3486+ unsigned int canary_2;
3487+#endif
3488+#if HARDENING_PATCH_LL_PROTECT
3489+ unsigned int canary_3;
3490+ unsigned int canary_4;
3491+ unsigned int ll_canary_inited;
3492+#endif
3493+ zend_bool hphp_sql_bailout_on_error;
3494+ zend_bool hphp_multiheader;
3495+ HashTable *eval_whitelist;
3496+ HashTable *eval_blacklist;
3497+ HashTable *func_whitelist;
3498+ HashTable *func_blacklist;
3499+ HashTable *include_whitelist;
3500+ HashTable *include_blacklist;
3501+ unsigned int dummy;
3502+};
3503+
3504+
3505+#endif /* HARDENED_GLOBALS_H */
3506+
3507+/*
3508+ * Local variables:
3509+ * tab-width: 4
3510+ * c-basic-offset: 4
3511+ * End:
3512+ */
3513diff -Nura php-4.4.1/main/hardening_patch.c hardening-patch-4.4.1-0.4.5/main/hardening_patch.c
3514--- php-4.4.1/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
3515+++ hardening-patch-4.4.1-0.4.5/main/hardening_patch.c 2005-11-01 17:51:58.494027504 +0100
3516@@ -0,0 +1,431 @@
3517+/*
3518+ +----------------------------------------------------------------------+
3519+ | Hardening Patch for PHP |
3520+ +----------------------------------------------------------------------+
3521+ | Copyright (c) 2004-2005 Stefan Esser |
3522+ +----------------------------------------------------------------------+
3523+ | This source file is subject to version 2.02 of the PHP license, |
3524+ | that is bundled with this package in the file LICENSE, and is |
3525+ | available at through the world-wide-web at |
3526+ | http://www.php.net/license/2_02.txt. |
3527+ | If you did not receive a copy of the PHP license and are unable to |
3528+ | obtain it through the world-wide-web, please send a note to |
3529+ | license@php.net so we can mail you a copy immediately. |
3530+ +----------------------------------------------------------------------+
3531+ | Author: Stefan Esser <sesser@hardened-php.net> |
3532+ +----------------------------------------------------------------------+
3533+ */
3534+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
3535+
3536+#include "php.h"
3537+
3538+#include <stdio.h>
3539+#include <stdlib.h>
3540+
3541+#if HAVE_UNISTD_H
3542+#include <unistd.h>
3543+#endif
3544+#include "SAPI.h"
3545+#include "php_globals.h"
3546+
3547+#if HARDENING_PATCH
3548+
3549+#ifdef HAVE_SYS_SOCKET_H
3550+#include <sys/socket.h>
3551+#endif
3552+
3553+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
3554+#undef AF_UNIX
3555+#endif
3556+
3557+#if defined(AF_UNIX)
3558+#include <sys/un.h>
3559+#endif
3560+
3561+#define SYSLOG_PATH "/dev/log"
3562+
3563+#include "snprintf.h"
3564+
3565+#include "hardening_patch.h"
3566+
3567+#ifdef ZTS
3568+#include "hardened_globals.h"
3569+int hardened_globals_id;
3570+#else
3571+struct _hardened_globals hardened_globals;
3572+#endif
3573+
3574+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
3575+{
3576+ memset(hardened_globals, 0, sizeof(*hardened_globals));
3577+}
3578+
3579+
3580+PHPAPI void hardened_startup()
3581+{
3582+#ifdef ZTS
3583+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
3584+#else
3585+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
3586+#endif
3587+}
3588+
3589+
3590+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
3591+{
3592+ HG(canary_1) = php_canary();
3593+ HG(canary_2) = php_canary();
3594+}
3595+
3596+char *loglevel2string(int loglevel)
3597+{
3598+ switch (loglevel) {
3599+ case S_FILES:
3600+ return "FILES";
3601+ case S_INCLUDE:
3602+ return "INCLUDE";
3603+ case S_MEMORY:
3604+ return "MEMORY";
3605+ case S_MISC:
3606+ return "MISC";
3607+ case S_SQL:
3608+ return "SQL";
3609+ case S_EXECUTOR:
3610+ return "EXECUTOR";
3611+ case S_VARS:
3612+ return "VARS";
3613+ default:
3614+ return "UNKNOWN";
3615+ }
3616+}
3617+
3618+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
3619+{
3620+#if defined(AF_UNIX)
3621+ int s, r, i=0;
3622+ struct sockaddr_un saun;
3623+ char buf[4096+64];
3624+ char error[4096+100];
3625+ char *ip_address;
3626+ char *fname;
3627+ int lineno;
3628+ va_list ap;
3629+ TSRMLS_FETCH();
3630+
3631+ if (EG(hphp_log_use_x_forwarded_for)) {
3632+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
3633+ if (ip_address == NULL) {
3634+ ip_address = "X-FORWARDED-FOR not set";
3635+ }
3636+ } else {
3637+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
3638+ if (ip_address == NULL) {
3639+ ip_address = "REMOTE_ADDR not set";
3640+ }
3641+ }
3642+
3643+
3644+ va_start(ap, fmt);
3645+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
3646+ va_end(ap);
3647+ while (error[i]) {
3648+ if (error[i] < 32) error[i] = '.';
3649+ i++;
3650+ }
3651+
3652+ if (zend_is_executing(TSRMLS_C)) {
3653+ lineno = zend_get_executed_lineno(TSRMLS_C);
3654+ fname = zend_get_executed_filename(TSRMLS_C);
3655+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
3656+ } else {
3657+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
3658+ if (fname==NULL) {
3659+ fname = "unknown";
3660+ }
3661+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
3662+ }
3663+
3664+ /* Syslog-Logging disabled? */
3665+ if ((EG(hphp_log_syslog) & loglevel)==0) {
3666+ goto log_sapi;
3667+ }
3668+
3669+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
3670+
3671+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
3672+ if (s == -1) {
3673+ goto log_sapi;
3674+ }
3675+
3676+ memset(&saun, 0, sizeof(saun));
3677+ saun.sun_family = AF_UNIX;
3678+ strcpy(saun.sun_path, SYSLOG_PATH);
3679+ /*saun.sun_len = sizeof(saun);*/
3680+
3681+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3682+ if (r) {
3683+ close(s);
3684+ s = socket(AF_UNIX, SOCK_STREAM, 0);
3685+ if (s == -1) {
3686+ goto log_sapi;
3687+ }
3688+
3689+ memset(&saun, 0, sizeof(saun));
3690+ saun.sun_family = AF_UNIX;
3691+ strcpy(saun.sun_path, SYSLOG_PATH);
3692+ /*saun.sun_len = sizeof(saun);*/
3693+
3694+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3695+ if (r) {
3696+ close(s);
3697+ goto log_sapi;
3698+ }
3699+ }
3700+ send(s, error, strlen(error), 0);
3701+
3702+ close(s);
3703+
3704+log_sapi:
3705+ /* SAPI Logging activated? */
3706+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
3707+ sapi_module.log_message(buf);
3708+ }
3709+
3710+log_script:
3711+ /* script logging activaed? */
3712+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
3713+ char cmd[8192], *cmdpos, *bufpos;
3714+ FILE *in;
3715+ int space;
3716+
3717+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
3718+ space = sizeof(cmd) - strlen(cmd);
3719+ cmdpos = cmd + strlen(cmd);
3720+ bufpos = buf;
3721+ if (space <= 1) return;
3722+ while (space > 2 && *bufpos) {
3723+ if (*bufpos == '\'') {
3724+ if (space<=5) break;
3725+ *cmdpos++ = '\'';
3726+ *cmdpos++ = '\\';
3727+ *cmdpos++ = '\'';
3728+ *cmdpos++ = '\'';
3729+ bufpos++;
3730+ space-=4;
3731+ } else {
3732+ *cmdpos++ = *bufpos++;
3733+ space--;
3734+ }
3735+ }
3736+ *cmdpos++ = '\'';
3737+ *cmdpos = 0;
3738+
3739+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3740+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
3741+ return;
3742+ }
3743+ /* read and forget the result */
3744+ while (1) {
3745+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3746+ if (readbytes<=0) {
3747+ break;
3748+ }
3749+ }
3750+ pclose(in);
3751+ }
3752+
3753+#endif
3754+}
3755+#endif
3756+
3757+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3758+
3759+/* will be replaced later with more compatible method */
3760+PHPAPI unsigned int php_canary()
3761+{
3762+ time_t t;
3763+ unsigned int canary;
3764+ int fd;
3765+
3766+ fd = open("/dev/urandom", 0);
3767+ if (fd != -1) {
3768+ int r = read(fd, &canary, sizeof(canary));
3769+ close(fd);
3770+ if (r == sizeof(canary)) {
3771+ return (canary);
3772+ }
3773+ }
3774+ /* not good but we never want to do this */
3775+ time(&t);
3776+ canary = *(unsigned int *)&t + getpid() << 16;
3777+ return (canary);
3778+}
3779+#endif
3780+
3781+#if HARDENING_PATCH_INC_PROTECT
3782+
3783+PHPAPI int php_is_valid_include(zval *z)
3784+{
3785+ char *filename;
3786+ int len, i;
3787+ TSRMLS_FETCH();
3788+
3789+ /* must be of type string */
3790+ if (z->type != IS_STRING || z->value.str.val == NULL) {
3791+ return (0);
3792+ }
3793+
3794+ /* short cut */
3795+ filename = z->value.str.val;
3796+ len = z->value.str.len;
3797+
3798+ /* 1. must be shorter than MAXPATHLEN */
3799+ if (len > MAXPATHLEN) {
3800+ char *fname = estrndup(filename, len);
3801+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3802+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
3803+ efree(fname);
3804+ return (0);
3805+ }
3806+
3807+ /* 2. must not be cutted */
3808+ if (len != strlen(filename)) {
3809+ char *fname = estrndup(filename, len);
3810+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
3811+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
3812+ efree(fname);
3813+ return (0);
3814+ }
3815+
3816+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
3817+ if (strstr(filename, "://")) {
3818+ char *fname = estrndup(filename, len);
3819+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3820+
3821+ /* no black or whitelist then disallow all */
3822+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
3823+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
3824+ efree(fname);
3825+ return (0);
3826+ }
3827+
3828+ /* whitelist is stronger than blacklist */
3829+ if (HG(include_whitelist)) {
3830+ char *s, *t, *h, *index;
3831+ uint indexlen;
3832+ ulong numindex;
3833+
3834+ s = filename;
3835+
3836+ do {
3837+ zend_bool isOk = 0;
3838+ int tlen;
3839+
3840+ t = h = strstr(s, "://");
3841+ if (h == NULL) break;
3842+
3843+
3844+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
3845+ t--;
3846+ }
3847+
3848+ tlen = strlen(t);
3849+
3850+ zend_hash_internal_pointer_reset(HG(include_whitelist));
3851+ do {
3852+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
3853+
3854+ if (r==HASH_KEY_NON_EXISTANT) {
3855+ break;
3856+ }
3857+ if (r==HASH_KEY_IS_STRING) {
3858+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
3859+ if (strncmp(t, index, indexlen-1)==0) {
3860+ isOk = 1;
3861+ break;
3862+ }
3863+ }
3864+ }
3865+
3866+ zend_hash_move_forward(HG(include_whitelist));
3867+ } while (1);
3868+
3869+ /* not found in whitelist */
3870+ if (!isOk) {
3871+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
3872+ efree(fname);
3873+ return 0;
3874+ }
3875+
3876+ s = h + 3;
3877+ } while (1);
3878+ } else {
3879+ /* okay then handle the blacklist */
3880+ char *s, *t, *h, *index;
3881+ uint indexlen;
3882+ ulong numindex;
3883+
3884+ s = filename;
3885+
3886+ do {
3887+ int tlen;
3888+
3889+ t = h = strstr(s, "://");
3890+ if (h == NULL) break;
3891+
3892+
3893+ while (t > s) {
3894+ if (isalnum(t[-1]) || t[-1]=='_') t--;
3895+ }
3896+
3897+ tlen = strlen(t);
3898+
3899+ zend_hash_internal_pointer_reset(HG(include_blacklist));
3900+ do {
3901+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
3902+
3903+ if (r==HASH_KEY_NON_EXISTANT) {
3904+ break;
3905+ }
3906+ if (r==HASH_KEY_IS_STRING) {
3907+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
3908+ if (strncmp(t, index, indexlen-1)==0) {
3909+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
3910+ efree(fname);
3911+ return 0;
3912+ }
3913+ }
3914+ }
3915+
3916+ zend_hash_move_forward(HG(include_blacklist));
3917+ } while (1);
3918+
3919+ s = h + 3;
3920+ } while (1);
3921+ }
3922+
3923+ efree(fname);
3924+ }
3925+
3926+ /* 4. must not be an uploaded file */
3927+ if (SG(rfc1867_uploaded_files)) {
3928+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
3929+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
3930+ return (0);
3931+ }
3932+ }
3933+
3934+ /* passed all tests */
3935+ return (1);
3936+}
3937+
3938+#endif
3939+
3940+/*
3941+ * Local variables:
3942+ * tab-width: 4
3943+ * c-basic-offset: 4
3944+ * End:
3945+ * vim600: sw=4 ts=4 fdm=marker
3946+ * vim<600: sw=4 ts=4
3947+ */
3948diff -Nura php-4.4.1/main/hardening_patch.h hardening-patch-4.4.1-0.4.5/main/hardening_patch.h
3949--- php-4.4.1/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
3950+++ hardening-patch-4.4.1-0.4.5/main/hardening_patch.h 2005-11-01 13:37:29.000000000 +0100
3951@@ -0,0 +1,46 @@
3952+/*
3953+ +----------------------------------------------------------------------+
3954+ | Hardening Patch for PHP |
3955+ +----------------------------------------------------------------------+
3956+ | Copyright (c) 2004-2005 Stefan Esser |
3957+ +----------------------------------------------------------------------+
3958+ | This source file is subject to version 2.02 of the PHP license, |
3959+ | that is bundled with this package in the file LICENSE, and is |
3960+ | available at through the world-wide-web at |
3961+ | http://www.php.net/license/2_02.txt. |
3962+ | If you did not receive a copy of the PHP license and are unable to |
3963+ | obtain it through the world-wide-web, please send a note to |
3964+ | license@php.net so we can mail you a copy immediately. |
3965+ +----------------------------------------------------------------------+
3966+ | Author: Stefan Esser <sesser@hardened-php.net> |
3967+ +----------------------------------------------------------------------+
3968+ */
3969+
3970+#ifndef HARDENING_PATCH_H
3971+#define HARDENING_PATCH_H
3972+
3973+#include "zend.h"
3974+
3975+#if HARDENING_PATCH
3976+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
3977+PHPAPI void hardened_startup();
3978+#define HARDENING_PATCH_VERSION "0.4.5"
3979+
3980+#endif
3981+
3982+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3983+PHPAPI unsigned int php_canary();
3984+#endif
3985+
3986+#if HARDENING_PATCH_INC_PROTECT
3987+PHPAPI int php_is_valid_include(zval *z);
3988+#endif
3989+
3990+#endif /* HARDENING_PATCH_H */
3991+
3992+/*
3993+ * Local variables:
3994+ * tab-width: 4
3995+ * c-basic-offset: 4
3996+ * End:
3997+ */
3998diff -Nura php-4.4.1/main/hardening_patch.m4 hardening-patch-4.4.1-0.4.5/main/hardening_patch.m4
3999--- php-4.4.1/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4000+++ hardening-patch-4.4.1-0.4.5/main/hardening_patch.m4 2005-10-30 17:12:13.000000000 +0100
4001@@ -0,0 +1,95 @@
4002+dnl
4003+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4004+dnl
4005+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4006+dnl
4007+
4008+AC_ARG_ENABLE(hardening-patch-mm-protect,
4009+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4010+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4011+],[
4012+ DO_HARDENING_PATCH_MM_PROTECT=yes
4013+])
4014+
4015+AC_ARG_ENABLE(hardening-patch-ll-protect,
4016+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4017+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4018+],[
4019+ DO_HARDENING_PATCH_LL_PROTECT=yes
4020+])
4021+
4022+AC_ARG_ENABLE(hardening-patch-inc-protect,
4023+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4024+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4025+],[
4026+ DO_HARDENING_PATCH_INC_PROTECT=yes
4027+])
4028+
4029+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4030+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4031+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4032+],[
4033+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4034+])
4035+
4036+AC_ARG_ENABLE(hardening-patch-hash-protect,
4037+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4038+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4039+],[
4040+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4041+])
4042+
4043+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4044+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4045+
4046+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4047+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4048+
4049+AC_MSG_CHECKING(whether to protect include/require statements)
4050+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4051+
4052+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4053+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4054+
4055+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4056+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4057+
4058+
4059+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4060+
4061+
4062+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4063+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4064+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4065+else
4066+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4067+fi
4068+
4069+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4070+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4071+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4072+else
4073+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4074+fi
4075+
4076+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4077+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4078+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4079+else
4080+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4081+fi
4082+
4083+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4084+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4085+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4086+else
4087+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4088+fi
4089+
4090+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4091+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4092+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4093+else
4094+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4095+fi
4096+
4097diff -Nura php-4.4.1/main/main.c hardening-patch-4.4.1-0.4.5/main/main.c
4098--- php-4.4.1/main/main.c 2005-09-15 16:06:15.000000000 +0200
4099+++ hardening-patch-4.4.1-0.4.5/main/main.c 2005-11-01 16:52:53.018021784 +0100
4100@@ -92,6 +92,10 @@
4101 PHPAPI int core_globals_id;
4102 #endif
4103
4104+#if HARDENING_PATCH
4105+#include "hardened_globals.h"
4106+#endif
4107+
4108 #define ERROR_BUF_LEN 1024
4109
4110 typedef struct {
4111@@ -142,10 +146,33 @@
4112 */
4113 static PHP_INI_MH(OnChangeMemoryLimit)
4114 {
4115+#if HARDENING_PATCH
4116+ long orig_memory_limit;
4117+
4118+ if (entry->modified) {
4119+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4120+ } else {
4121+ orig_memory_limit = 1<<30;
4122+ }
4123+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4124+ orig_memory_limit = 1<<30;
4125+ }
4126+#endif
4127 if (new_value) {
4128 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4129+#if HARDENING_PATCH
4130+ if (PG(memory_limit) > orig_memory_limit) {
4131+ PG(memory_limit) = orig_memory_limit;
4132+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4133+ return FAILURE;
4134+ }
4135+#endif
4136 } else {
4137+#if HARDENING_PATCH
4138+ PG(memory_limit) = orig_memory_limit;
4139+#else
4140 PG(memory_limit) = 1<<30; /* effectively, no limit */
4141+#endif
4142 }
4143 return zend_set_memory_limit(PG(memory_limit));
4144 }
4145@@ -998,6 +1025,9 @@
4146
4147 zend_try {
4148 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4149+#if HARDENING_PATCH
4150+ hardened_clear_mm_canaries(TSRMLS_C);
4151+#endif
4152 } zend_end_try();
4153
4154 zend_try {
4155@@ -1088,6 +1118,10 @@
4156 tsrm_ls = ts_resource(0);
4157 #endif
4158
4159+#if HARDENING_PATCH
4160+ hardened_startup();
4161+#endif
4162+
4163 sapi_initialize_empty_request(TSRMLS_C);
4164 sapi_activate(TSRMLS_C);
4165
4166@@ -1100,6 +1134,12 @@
4167 php_output_startup();
4168 php_output_activate(TSRMLS_C);
4169
4170+#if HARDENING_PATCH_INC_PROTECT
4171+ zuf.is_valid_include = php_is_valid_include;
4172+#endif
4173+#if HARDENING_PATCH
4174+ zuf.security_log_function = php_security_log;
4175+#endif
4176 zuf.error_function = php_error_cb;
4177 zuf.printf_function = php_printf;
4178 zuf.write_function = php_body_write_wrapper;
4179@@ -1201,6 +1241,10 @@
4180 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4181 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);
4182 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4183+#if HARDENING_PATCH
4184+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4185+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4186+#endif
4187 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4188 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4189 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4190@@ -1308,7 +1352,7 @@
4191 */
4192 static inline void php_register_server_variables(TSRMLS_D)
4193 {
4194- zval *array_ptr=NULL;
4195+ zval *array_ptr=NULL, *vptr;
4196
4197 ALLOC_ZVAL(array_ptr);
4198 array_init(array_ptr);
4199@@ -1318,6 +1362,16 @@
4200 /* Server variables */
4201 if (sapi_module.register_server_variables) {
4202 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
4203+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
4204+ char *str;
4205+ if (vptr->type != IS_STRING) {
4206+ str = "Array";
4207+ } else {
4208+ str = vptr->value.str.val;
4209+ }
4210+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
4211+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
4212+ }
4213 }
4214
4215 /* PHP Authentication support */
4216diff -Nura php-4.4.1/main/php_config.h.in hardening-patch-4.4.1-0.4.5/main/php_config.h.in
4217--- php-4.4.1/main/php_config.h.in 2005-10-30 12:06:40.000000000 +0100
4218+++ hardening-patch-4.4.1-0.4.5/main/php_config.h.in 2005-10-30 17:12:13.000000000 +0100
4219@@ -859,6 +859,39 @@
4220 /* Enabling BIND8 compatibility for Panther */
4221 #undef BIND_8_COMPAT
4222
4223+/* Hardening-Patch */
4224+#undef HARDENING_PATCH
4225+
4226+/* Memory Manager Protection */
4227+#undef HARDENING_PATCH_MM_PROTECT
4228+
4229+/* Memory Manager Protection */
4230+#undef HARDENING_PATCH_MM_PROTECT
4231+
4232+/* Linked List Protection */
4233+#undef HARDENING_PATCH_LL_PROTECT
4234+
4235+/* Linked List Protection */
4236+#undef HARDENING_PATCH_LL_PROTECT
4237+
4238+/* Include/Require Protection */
4239+#undef HARDENING_PATCH_INC_PROTECT
4240+
4241+/* Include/Require Protection */
4242+#undef HARDENING_PATCH_INC_PROTECT
4243+
4244+/* Fmt String Protection */
4245+#undef HARDENING_PATCH_FMT_PROTECT
4246+
4247+/* Fmt String Protection */
4248+#undef HARDENING_PATCH_FMT_PROTECT
4249+
4250+/* HashTable DTOR Protection */
4251+#undef HARDENING_PATCH_HASH_PROTECT
4252+
4253+/* HashTable DTOR Protection */
4254+#undef HARDENING_PATCH_HASH_PROTECT
4255+
4256 /* Whether you have AOLserver */
4257 #undef HAVE_AOLSERVER
4258
4259@@ -1142,6 +1175,12 @@
4260 /* Define if you have the getaddrinfo function */
4261 #undef HAVE_GETADDRINFO
4262
4263+/* Whether realpath is broken */
4264+#undef PHP_BROKEN_REALPATH
4265+
4266+/* Whether realpath is broken */
4267+#undef PHP_BROKEN_REALPATH
4268+
4269 /* Whether system headers declare timezone */
4270 #undef HAVE_DECLARED_TIMEZONE
4271
4272diff -Nura php-4.4.1/main/php_content_types.c hardening-patch-4.4.1-0.4.5/main/php_content_types.c
4273--- php-4.4.1/main/php_content_types.c 2002-12-31 17:26:14.000000000 +0100
4274+++ hardening-patch-4.4.1-0.4.5/main/php_content_types.c 2005-10-30 17:12:13.000000000 +0100
4275@@ -77,6 +77,7 @@
4276 sapi_register_post_entries(php_post_entries);
4277 sapi_register_default_post_reader(php_default_post_reader);
4278 sapi_register_treat_data(php_default_treat_data);
4279+ sapi_register_input_filter(php_default_input_filter);
4280 return SUCCESS;
4281 }
4282 /* }}} */
4283diff -Nura php-4.4.1/main/php.h hardening-patch-4.4.1-0.4.5/main/php.h
4284--- php-4.4.1/main/php.h 2005-07-27 12:26:25.000000000 +0200
4285+++ hardening-patch-4.4.1-0.4.5/main/php.h 2005-10-30 17:12:13.000000000 +0100
4286@@ -35,11 +35,19 @@
4287 #include "zend_qsort.h"
4288 #include "php_compat.h"
4289
4290+
4291 #include "zend_API.h"
4292
4293 #undef sprintf
4294 #define sprintf php_sprintf
4295
4296+#if HARDENING_PATCH
4297+#if HAVE_REALPATH
4298+#undef realpath
4299+#define realpath php_realpath
4300+#endif
4301+#endif
4302+
4303 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4304 #undef PHP_DEBUG
4305 #define PHP_DEBUG ZEND_DEBUG
4306@@ -407,6 +415,10 @@
4307 #endif
4308 #endif /* !XtOffsetOf */
4309
4310+#if HARDENING_PATCH
4311+#include "hardening_patch.h"
4312+#endif
4313+
4314 #endif
4315
4316 /*
4317diff -Nura php-4.4.1/main/php_variables.c hardening-patch-4.4.1-0.4.5/main/php_variables.c
4318--- php-4.4.1/main/php_variables.c 2005-10-02 13:33:27.000000000 +0200
4319+++ hardening-patch-4.4.1-0.4.5/main/php_variables.c 2005-10-30 17:12:13.000000000 +0100
4320@@ -236,17 +236,28 @@
4321 while (var) {
4322 val = strchr(var, '=');
4323 if (val) { /* have a value */
4324- int val_len;
4325+ unsigned int val_len, new_val_len;
4326
4327 *val++ = '\0';
4328 php_url_decode(var, strlen(var));
4329 val_len = php_url_decode(val, strlen(val));
4330- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4331+ val = estrndup(val, val_len);
4332+ if (sapi_module.input_filter(PARSE_POST, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4333+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4334+ }
4335+ efree(val);
4336 }
4337 var = php_strtok_r(NULL, "&", &strtok_buf);
4338 }
4339 }
4340
4341+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter)
4342+{
4343+ /* TODO: check .ini setting here and apply user-defined input filter */
4344+ *new_val_len = val_len;
4345+ return 1;
4346+}
4347+
4348 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
4349 {
4350 char *res = NULL, *var, *val, *separator=NULL;
4351@@ -324,15 +335,26 @@
4352 while (var) {
4353 val = strchr(var, '=');
4354 if (val) { /* have a value */
4355- int val_len;
4356+ unsigned int val_len, new_val_len;
4357
4358 *val++ = '\0';
4359 php_url_decode(var, strlen(var));
4360 val_len = php_url_decode(val, strlen(val));
4361- php_register_variable_safe(var, val, val_len, array_ptr TSRMLS_CC);
4362+ val = estrndup(val, val_len);
4363+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4364+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4365+ }
4366+ efree(val);
4367 } else {
4368+ unsigned int val_len, new_val_len;
4369+
4370 php_url_decode(var, strlen(var));
4371- php_register_variable_safe(var, "", 0, array_ptr TSRMLS_CC);
4372+ val_len = 0;
4373+ val = estrndup("", 0);
4374+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) {
4375+ php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC);
4376+ }
4377+ efree(val);
4378 }
4379 var = php_strtok_r(NULL, separator, &strtok_buf);
4380 }
4381diff -Nura php-4.4.1/main/rfc1867.c hardening-patch-4.4.1-0.4.5/main/rfc1867.c
4382--- php-4.4.1/main/rfc1867.c 2005-07-13 22:47:56.000000000 +0200
4383+++ hardening-patch-4.4.1-0.4.5/main/rfc1867.c 2005-10-30 17:12:13.000000000 +0100
4384@@ -128,6 +128,8 @@
4385 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4386 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4387 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4388+#define UPLOAD_ERROR_X 99 /* Filter forbids upload */
4389+
4390
4391 void php_rfc1867_register_constants(TSRMLS_D)
4392 {
4393@@ -138,6 +140,7 @@
4394 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4395 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4396 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4397+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4398 }
4399
4400 static void normalize_protected_variable(char *varname TSRMLS_DC)
4401@@ -849,6 +852,7 @@
4402 char buff[FILLUNIT];
4403 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4404 int blen=0, wlen=0;
4405+ unsigned long offset;
4406
4407 zend_llist_clean(&header);
4408
4409@@ -897,21 +901,24 @@
4410 if (!filename && param) {
4411
4412 char *value = multipart_buffer_read_body(mbuff TSRMLS_CC);
4413+ unsigned int new_val_len; /* Dummy variable */
4414
4415 if (!value) {
4416 value = estrdup("");
4417 }
4418
4419+ if (sapi_module.input_filter(PARSE_POST, param, &value, strlen(value), &new_val_len TSRMLS_CC)) {
4420 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
4421- if (php_mb_encoding_translation(TSRMLS_C)) {
4422- php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4423- &num_vars, &num_vars_max TSRMLS_CC);
4424- } else {
4425- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4426- }
4427+ if (php_mb_encoding_translation(TSRMLS_C)) {
4428+ php_mb_gpc_stack_variable(param, value, &val_list, &len_list,
4429+ &num_vars, &num_vars_max TSRMLS_CC);
4430+ } else {
4431+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4432+ }
4433 #else
4434- safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4435+ safe_php_register_variable(param, value, array_ptr, 0 TSRMLS_CC);
4436 #endif
4437+ }
4438 if (!strcasecmp(param, "MAX_FILE_SIZE")) {
4439 max_file_size = atol(value);
4440 }
4441@@ -963,7 +970,11 @@
4442 tmp++;
4443 }
4444 }
4445-
4446+
4447+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4448+ skip_upload = 1;
4449+ }
4450+
4451 total_bytes = cancel_upload = 0;
4452
4453 if (!skip_upload) {
4454@@ -987,6 +998,11 @@
4455 cancel_upload = UPLOAD_ERROR_D;
4456 }
4457
4458+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4459+ cancel_upload = UPLOAD_ERROR_X;
4460+ }
4461+
4462+ offset = 0;
4463 end = 0;
4464 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4465 {
4466@@ -997,6 +1013,11 @@
4467 sapi_module.sapi_error(E_WARNING, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename);
4468 cancel_upload = UPLOAD_ERROR_B;
4469 } else if (blen > 0) {
4470+
4471+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4472+ cancel_upload = UPLOAD_ERROR_X;
4473+ }
4474+
4475 wlen = write(fd, buff, blen);
4476
4477 if (wlen < blen) {
4478@@ -1004,6 +1025,7 @@
4479 cancel_upload = UPLOAD_ERROR_F;
4480 } else {
4481 total_bytes += wlen;
4482+ offset += wlen;
4483 }
4484 }
4485 }
4486@@ -1025,6 +1047,10 @@
4487 }
4488 #endif
4489
4490+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4491+ cancel_upload = UPLOAD_ERROR_X;
4492+ }
4493+
4494 if (cancel_upload) {
4495 if (temp_filename) {
4496 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4497diff -Nura php-4.4.1/main/SAPI.c hardening-patch-4.4.1-0.4.5/main/SAPI.c
4498--- php-4.4.1/main/SAPI.c 2005-10-19 22:36:19.000000000 +0200
4499+++ hardening-patch-4.4.1-0.4.5/main/SAPI.c 2005-10-30 17:12:13.000000000 +0100
4500@@ -837,6 +837,37 @@
4501 return SUCCESS;
4502 }
4503
4504+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))
4505+{
4506+ sapi_module.input_filter = input_filter;
4507+ return SUCCESS;
4508+}
4509+
4510+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
4511+{
4512+ sapi_module.upload_varname_filter = upload_varname_filter;
4513+ return SUCCESS;
4514+}
4515+
4516+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4517+{
4518+ sapi_module.pre_upload_filter = pre_upload_filter;
4519+ return SUCCESS;
4520+}
4521+
4522+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))
4523+{
4524+ sapi_module.upload_content_filter = upload_content_filter;
4525+ return SUCCESS;
4526+}
4527+
4528+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4529+{
4530+ sapi_module.post_upload_filter = post_upload_filter;
4531+ return SUCCESS;
4532+}
4533+
4534+
4535
4536 SAPI_API int sapi_flush(TSRMLS_D)
4537 {
4538diff -Nura php-4.4.1/main/SAPI.h hardening-patch-4.4.1-0.4.5/main/SAPI.h
4539--- php-4.4.1/main/SAPI.h 2003-04-09 22:27:55.000000000 +0200
4540+++ hardening-patch-4.4.1-0.4.5/main/SAPI.h 2005-10-30 17:12:13.000000000 +0100
4541@@ -101,9 +101,10 @@
4542 char *current_user;
4543 int current_user_length;
4544
4545- /* this is necessary for CLI module */
4546- int argc;
4547- char **argv;
4548+ /* this is necessary for CLI module */
4549+ int argc;
4550+ char **argv;
4551+
4552 } sapi_request_info;
4553
4554
4555@@ -177,6 +178,10 @@
4556 SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry);
4557 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D));
4558 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4559+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));
4560+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4561+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));
4562+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4563
4564 SAPI_API int sapi_flush(TSRMLS_D);
4565 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4566@@ -238,8 +243,16 @@
4567 int (*get_target_uid)(uid_t * TSRMLS_DC);
4568 int (*get_target_gid)(gid_t * TSRMLS_DC);
4569
4570+ unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4571+
4572+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
4573+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
4574+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
4575+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
4576+
4577 void (*ini_defaults)(HashTable *configuration_hash);
4578 int phpinfo_as_text;
4579+
4580 };
4581
4582
4583@@ -262,16 +275,27 @@
4584
4585 #define SAPI_DEFAULT_MIMETYPE "text/html"
4586 #define SAPI_DEFAULT_CHARSET ""
4587+
4588+#if HARDENING_PATCH
4589+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
4590+#else
4591 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4592+#endif
4593
4594 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4595 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4596
4597 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4598+#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)
4599+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
4600+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
4601+#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)
4602+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
4603
4604 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4605 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4606 SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data);
4607+SAPI_API SAPI_INPUT_FILTER_FUNC(php_default_input_filter);
4608
4609 #define STANDARD_SAPI_MODULE_PROPERTIES
4610
4611diff -Nura php-4.4.1/main/snprintf.c hardening-patch-4.4.1-0.4.5/main/snprintf.c
4612--- php-4.4.1/main/snprintf.c 2005-04-08 07:44:53.000000000 +0200
4613+++ hardening-patch-4.4.1-0.4.5/main/snprintf.c 2005-10-30 17:12:13.000000000 +0100
4614@@ -1013,7 +1013,11 @@
4615
4616
4617 case 'n':
4618+#if HARDENING_PATCH_FMT_PROTECT
4619+ php_security_log(S_MISC, "'n' specifier within format string");
4620+#else
4621 *(va_arg(ap, int *)) = cc;
4622+#endif
4623 break;
4624
4625 /*
4626diff -Nura php-4.4.1/main/spprintf.c hardening-patch-4.4.1-0.4.5/main/spprintf.c
4627--- php-4.4.1/main/spprintf.c 2005-04-08 07:44:53.000000000 +0200
4628+++ hardening-patch-4.4.1-0.4.5/main/spprintf.c 2005-10-30 17:12:13.000000000 +0100
4629@@ -630,7 +630,11 @@
4630
4631
4632 case 'n':
4633+#if HARDENING_PATCH_FMT_PROTECT
4634+ php_security_log(S_MISC, "'n' specifier within format string");
4635+#else
4636 *(va_arg(ap, int *)) = xbuf->len;
4637+#endif
4638 break;
4639
4640 /*
4641diff -Nura php-4.4.1/php.ini-dist hardening-patch-4.4.1-0.4.5/php.ini-dist
4642--- php-4.4.1/php.ini-dist 2005-04-28 15:14:45.000000000 +0200
4643+++ hardening-patch-4.4.1-0.4.5/php.ini-dist 2005-10-30 17:12:13.000000000 +0100
4644@@ -1112,6 +1112,197 @@
4645 ;exif.decode_jis_motorola = JIS
4646 ;exif.decode_jis_intel = JIS
4647
4648+[hardening-patch]
4649+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4650+; Hardening-Patch's logging ;
4651+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4652+
4653+;
4654+; hphp.log.syslog - Configures level for alerts reported through syslog
4655+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4656+; hphp.log.script - Configures level for alerts reported through external script
4657+;
4658+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4659+; Or each number up to get desired Hardening-Patch's reporting level
4660+;
4661+; S_ALL - All alerts
4662+; S_MEMORY - All canary violations and the safe unlink protection use this class
4663+; S_VARS - All variable filters trigger this class
4664+; S_FILES - All violation of uploaded files filter use this class
4665+; S_INCLUDE - The protection against malicious include filenames use this class
4666+; S_SQL - Failed SQL queries in MySQL are logged with this class
4667+; S_EXECUTOR - The execution depth protection uses this logging class
4668+; S_MISC - All other log messages (f.e. format string protection) use this class
4669+;
4670+; Example:
4671+;
4672+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4673+; memory alerts through syslog and SQL+Include alerts fo the script
4674+;
4675+;hphp.log.syslog = S_MEMORY
4676+;hphp.log.sapi = S_ALL & ~S_MEMORY
4677+;hphp.log.script = S_INCLUDE | S_SQL
4678+;
4679+; Syslog logging:
4680+;
4681+; - Facility configuration: one of the following facilities
4682+;
4683+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4684+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4685+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4686+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4687+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4688+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4689+; LOG_PERROR
4690+;
4691+; - Priority configuration: one of the followinf priorities
4692+;
4693+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4694+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4695+;
4696+hphp.log.syslog.priority = LOG_ALERT
4697+hphp.log.syslog.facility = LOG_USER
4698+;
4699+; Script logging:
4700+;
4701+;hphp.log.script.name = /home/hphp/log_script
4702+;
4703+; Alert configuration:
4704+;
4705+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4706+;
4707+;hphp.log.use-x-forwarded-for = On
4708+;
4709+
4710+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4711+; Hardening-Patch's Executor options ;
4712+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4713+
4714+; Execution depth limit
4715+;hphp.executor.max_depth = 8000
4716+
4717+; White-/blacklist for function calls during normal execution
4718+;hphp.executor.func.whitelist = ord,chr
4719+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4720+
4721+; White-/blacklist for function calls during eval() execution
4722+;hphp.executor.eval.whitelist = ord,chr
4723+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4724+
4725+; White-/blacklist for URLs allowes in include filenames
4726+;
4727+; - When both options are not set all URLs are forbidden
4728+;
4729+; - When both options are set whitelist is taken and blacklist ignored
4730+;
4731+; - An entry in the lists is either a URL sheme like: http, https
4732+; or the beginning of an URL like: php://input
4733+;
4734+;hphp.executor.include.whitelist = cookietest
4735+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
4736+
4737+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4738+; Hardening-Patch's REQUEST variable filters ;
4739+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4740+
4741+; Limits the number of REQUEST variables
4742+hphp.request.max_vars = 200
4743+
4744+; Limits the length of variable names (without indices)
4745+hphp.request.max_varname_length = 64
4746+
4747+; Limits the length of complete variable names (with indices)
4748+hphp.request.max_totalname_length = 256
4749+
4750+; Limits the length of array indices
4751+hphp.request.max_array_index_length = 64
4752+
4753+; Limits the depth of arrays
4754+hphp.request.max_array_depth = 100
4755+
4756+; Limits the length of variable values
4757+hphp.request.max_value_length = 65000
4758+
4759+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4760+; Hardening-Patch's COOKIE variable filters ;
4761+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4762+
4763+; Limits the number of COOKIE variables
4764+hphp.cookie.max_vars = 100
4765+
4766+; Limits the length of variable names (without indices)
4767+hphp.cookie.max_name_length = 64
4768+
4769+; Limits the length of complete variable names (with indices)
4770+hphp.cookie.max_totalname_length = 256
4771+
4772+; Limits the length of array indices
4773+hphp.cookie.max_array_index_length = 64
4774+
4775+; Limits the depth of arrays
4776+hphp.cookie.max_array_depth = 100
4777+
4778+; Limits the length of variable values
4779+hphp.cookie.max_value_length = 10000
4780+
4781+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4782+; Hardening-Patch's GET variable filters ;
4783+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4784+
4785+; Limits the number of COOKIE variables
4786+hphp.get.max_vars = 100
4787+
4788+; Limits the length of variable names (without indices)
4789+hphp.get.max_name_length = 64
4790+
4791+; Limits the length of complete variable names (with indices)
4792+hphp.get.max_totalname_length = 256
4793+
4794+; Limits the length of array indices
4795+hphp.get.max_array_index_length = 64
4796+
4797+; Limits the depth of arrays
4798+hphp.get.max_array_depth = 50
4799+
4800+; Limits the length of variable values
4801+hphp.get.max_value_length = 512
4802+
4803+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4804+; Hardening-Patch's POST variable filters ;
4805+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4806+
4807+; Limits the number of POST variables
4808+hphp.post.max_vars = 200
4809+
4810+; Limits the length of variable names (without indices)
4811+hphp.post.max_name_length = 64
4812+
4813+; Limits the length of complete variable names (with indices)
4814+hphp.post.max_totalname_length = 256
4815+
4816+; Limits the length of array indices
4817+hphp.post.max_array_index_length = 64
4818+
4819+; Limits the depth of arrays
4820+hphp.post.max_array_depth = 100
4821+
4822+; Limits the length of variable values
4823+hphp.post.max_value_length = 65000
4824+
4825+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4826+; Hardening-Patch's fileupload variable filters ;
4827+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4828+
4829+; Limits the number of uploadable files
4830+hphp.upload.max_uploads = 25
4831+
4832+; Filter out the upload of ELF executables
4833+hphp.upload.disallow_elf_files = On
4834+
4835+; External filterscript for upload verification
4836+;hphp.upload.verification_script = /home/hphp/verify_script
4837+
4838+
4839 ; Local Variables:
4840 ; tab-width: 4
4841 ; End:
4842diff -Nura php-4.4.1/php.ini-recommended hardening-patch-4.4.1-0.4.5/php.ini-recommended
4843--- php-4.4.1/php.ini-recommended 2005-04-28 15:14:46.000000000 +0200
4844+++ hardening-patch-4.4.1-0.4.5/php.ini-recommended 2005-10-30 17:12:13.000000000 +0100
4845@@ -1110,6 +1110,197 @@
4846 ;exif.decode_jis_motorola = JIS
4847 ;exif.decode_jis_intel = JIS
4848
4849+[hardening-patch]
4850+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4851+; Hardening-Patch's logging ;
4852+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4853+
4854+;
4855+; hphp.log.syslog - Configures level for alerts reported through syslog
4856+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4857+; hphp.log.script - Configures level for alerts reported through external script
4858+;
4859+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4860+; Or each number up to get desired Hardening-Patch's reporting level
4861+;
4862+; S_ALL - All alerts
4863+; S_MEMORY - All canary violations and the safe unlink protection use this class
4864+; S_VARS - All variable filters trigger this class
4865+; S_FILES - All violation of uploaded files filter use this class
4866+; S_INCLUDE - The protection against malicious include filenames use this class
4867+; S_SQL - Failed SQL queries in MySQL are logged with this class
4868+; S_EXECUTOR - The execution depth protection uses this logging class
4869+; S_MISC - All other log messages (f.e. format string protection) use this class
4870+;
4871+; Example:
4872+;
4873+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4874+; memory alerts through syslog and SQL+Include alerts fo the script
4875+;
4876+;hphp.log.syslog = S_MEMORY
4877+;hphp.log.sapi = S_ALL & ~S_MEMORY
4878+;hphp.log.script = S_INCLUDE | S_SQL
4879+;
4880+; Syslog logging:
4881+;
4882+; - Facility configuration: one of the following facilities
4883+;
4884+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4885+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4886+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4887+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4888+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4889+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4890+; LOG_PERROR
4891+;
4892+; - Priority configuration: one of the followinf priorities
4893+;
4894+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4895+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4896+;
4897+hphp.log.syslog.priority = LOG_ALERT
4898+hphp.log.syslog.facility = LOG_USER
4899+;
4900+; Script logging:
4901+;
4902+;hphp.log.script.name = /home/hphp/log_script
4903+;
4904+; Alert configuration:
4905+;
4906+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4907+;
4908+;hphp.log.use-x-forwarded-for = On
4909+;
4910+
4911+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4912+; Hardening-Patch's Executor options ;
4913+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4914+
4915+; Execution depth limit
4916+;hphp.executor.max_depth = 8000
4917+
4918+; White-/blacklist for function calls during normal execution
4919+;hphp.executor.func.whitelist = ord,chr
4920+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4921+
4922+; White-/blacklist for function calls during eval() execution
4923+;hphp.executor.eval.whitelist = ord,chr
4924+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4925+
4926+; White-/blacklist for URLs allowes in include filenames
4927+;
4928+; - When both options are not set all URLs are forbidden
4929+;
4930+; - When both options are set whitelist is taken and blacklist ignored
4931+;
4932+; - An entry in the lists is either a URL sheme like: http, https
4933+; or the beginning of an URL like: php://input
4934+;
4935+;hphp.executor.include.whitelist = cookietest
4936+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
4937+
4938+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4939+; Hardening-Patch's REQUEST variable filters ;
4940+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4941+
4942+; Limits the number of REQUEST variables
4943+hphp.request.max_vars = 200
4944+
4945+; Limits the length of variable names (without indices)
4946+hphp.request.max_varname_length = 64
4947+
4948+; Limits the length of complete variable names (with indices)
4949+hphp.request.max_totalname_length = 256
4950+
4951+; Limits the length of array indices
4952+hphp.request.max_array_index_length = 64
4953+
4954+; Limits the depth of arrays
4955+hphp.request.max_array_depth = 100
4956+
4957+; Limits the length of variable values
4958+hphp.request.max_value_length = 65000
4959+
4960+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4961+; Hardening-Patch's COOKIE variable filters ;
4962+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4963+
4964+; Limits the number of COOKIE variables
4965+hphp.cookie.max_vars = 100
4966+
4967+; Limits the length of variable names (without indices)
4968+hphp.cookie.max_name_length = 64
4969+
4970+; Limits the length of complete variable names (with indices)
4971+hphp.cookie.max_totalname_length = 256
4972+
4973+; Limits the length of array indices
4974+hphp.cookie.max_array_index_length = 64
4975+
4976+; Limits the depth of arrays
4977+hphp.cookie.max_array_depth = 100
4978+
4979+; Limits the length of variable values
4980+hphp.cookie.max_value_length = 10000
4981+
4982+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4983+; Hardening-Patch's GET variable filters ;
4984+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4985+
4986+; Limits the number of COOKIE variables
4987+hphp.get.max_vars = 100
4988+
4989+; Limits the length of variable names (without indices)
4990+hphp.get.max_name_length = 64
4991+
4992+; Limits the length of complete variable names (with indices)
4993+hphp.get.max_totalname_length = 256
4994+
4995+; Limits the length of array indices
4996+hphp.get.max_array_index_length = 64
4997+
4998+; Limits the depth of arrays
4999+hphp.get.max_array_depth = 50
5000+
5001+; Limits the length of variable values
5002+hphp.get.max_value_length = 512
5003+
5004+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5005+; Hardening-Patch's POST variable filters ;
5006+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5007+
5008+; Limits the number of POST variables
5009+hphp.post.max_vars = 200
5010+
5011+; Limits the length of variable names (without indices)
5012+hphp.post.max_name_length = 64
5013+
5014+; Limits the length of complete variable names (with indices)
5015+hphp.post.max_totalname_length = 256
5016+
5017+; Limits the length of array indices
5018+hphp.post.max_array_index_length = 64
5019+
5020+; Limits the depth of arrays
5021+hphp.post.max_array_depth = 100
5022+
5023+; Limits the length of variable values
5024+hphp.post.max_value_length = 65000
5025+
5026+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5027+; Hardening-Patch's fileupload variable filters ;
5028+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5029+
5030+; Limits the number of uploadable files
5031+hphp.upload.max_uploads = 25
5032+
5033+; Filter out the upload of ELF executables
5034+hphp.upload.disallow_elf_files = On
5035+
5036+; External filterscript for upload verification
5037+;hphp.upload.verification_script = /home/hphp/verify_script
5038+
5039+
5040 ; Local Variables:
5041 ; tab-width: 4
5042 ; End:
5043diff -Nura php-4.4.1/README.input_filter hardening-patch-4.4.1-0.4.5/README.input_filter
5044--- php-4.4.1/README.input_filter 1970-01-01 01:00:00.000000000 +0100
5045+++ hardening-patch-4.4.1-0.4.5/README.input_filter 2005-10-30 17:12:13.000000000 +0100
5046@@ -0,0 +1,193 @@
5047+Input Filter Support ported from PHP 5
5048+--------------------------------------
5049+
5050+XSS (Cross Site Scripting) hacks are becoming more and more prevalent,
5051+and can be quite difficult to prevent. Whenever you accept user data
5052+and somehow display this data back to users, you are likely vulnerable
5053+to XSS hacks.
5054+
5055+The Input Filter support in PHP 5 is aimed at providing the framework
5056+through which a company-wide or site-wide security policy can be
5057+enforced. It is implemented as a SAPI hook and is called from the
5058+treat_data and post handler functions. To implement your own security
5059+policy you will need to write a standard PHP extension.
5060+
5061+A simple implementation might look like the following. This stores the
5062+original raw user data and adds a my_get_raw() function while the normal
5063+$_POST, $_GET and $_COOKIE arrays are only populated with stripped
5064+data. In this simple example all I am doing is calling strip_tags() on
5065+the data. If register_globals is turned on, the default globals that
5066+are created will be stripped ($foo) while a $RAW_foo is created with the
5067+original user input.
5068+
5069+ZEND_BEGIN_MODULE_GLOBALS(my_input_filter)
5070+ zval *post_array;
5071+ zval *get_array;
5072+ zval *cookie_array;
5073+ZEND_END_MODULE_GLOBALS(my_input_filter)
5074+
5075+#ifdef ZTS
5076+#define IF_G(v) TSRMG(my_input_filter_globals_id, zend_my_input_filter_globals *, v)
5077+#else
5078+#define IF_G(v) (my_input_filter_globals.v)
5079+#endif
5080+
5081+ZEND_DECLARE_MODULE_GLOBALS(my_input_filter)
5082+
5083+function_entry my_input_filter_functions[] = {
5084+ PHP_FE(my_get_raw, NULL)
5085+ {NULL, NULL, NULL}
5086+};
5087+
5088+zend_module_entry my_input_filter_module_entry = {
5089+ STANDARD_MODULE_HEADER,
5090+ "my_input_filter",
5091+ my_input_filter_functions,
5092+ PHP_MINIT(my_input_filter),
5093+ PHP_MSHUTDOWN(my_input_filter),
5094+ NULL,
5095+ PHP_RSHUTDOWN(my_input_filter),
5096+ PHP_MINFO(my_input_filter),
5097+ "0.1",
5098+ STANDARD_MODULE_PROPERTIES
5099+};
5100+
5101+PHP_MINIT_FUNCTION(my_input_filter)
5102+{
5103+ ZEND_INIT_MODULE_GLOBALS(my_input_filter, php_my_input_filter_init_globals, NULL);
5104+
5105+ REGISTER_LONG_CONSTANT("POST", PARSE_POST, CONST_CS | CONST_PERSISTENT);
5106+ REGISTER_LONG_CONSTANT("GET", PARSE_GET, CONST_CS | CONST_PERSISTENT);
5107+ REGISTER_LONG_CONSTANT("COOKIE", PARSE_COOKIE, CONST_CS | CONST_PERSISTENT);
5108+
5109+ sapi_register_input_filter(my_sapi_input_filter);
5110+ return SUCCESS;
5111+}
5112+
5113+PHP_RSHUTDOWN_FUNCTION(my_input_filter)
5114+{
5115+ if(IF_G(get_array)) {
5116+ zval_ptr_dtor(&IF_G(get_array));
5117+ IF_G(get_array) = NULL;
5118+ }
5119+ if(IF_G(post_array)) {
5120+ zval_ptr_dtor(&IF_G(post_array));
5121+ IF_G(post_array) = NULL;
5122+ }
5123+ if(IF_G(cookie_array)) {
5124+ zval_ptr_dtor(&IF_G(cookie_array));
5125+ IF_G(cookie_array) = NULL;
5126+ }
5127+ return SUCCESS;
5128+}
5129+
5130+PHP_MINFO_FUNCTION(my_input_filter)
5131+{
5132+ php_info_print_table_start();
5133+ php_info_print_table_row( 2, "My Input Filter Support", "enabled" );
5134+ php_info_print_table_row( 2, "Revision", "$Revision: 1.1 $");
5135+ php_info_print_table_end();
5136+}
5137+
5138+/* The filter handler. If you return 1 from it, then PHP also registers the
5139+ * (modified) variable. Returning 0 prevents PHP from registering the variable;
5140+ * you can use this if your filter already registers the variable under a
5141+ * different name, or if you just don't want the variable registered at all. */
5142+SAPI_INPUT_FILTER_FUNC(my_sapi_input_filter)
5143+{
5144+ zval new_var;
5145+ zval *array_ptr = NULL;
5146+ char *raw_var;
5147+ int var_len;
5148+
5149+ assert(*val != NULL);
5150+
5151+ switch(arg) {
5152+ case PARSE_GET:
5153+ if(!IF_G(get_array)) {
5154+ ALLOC_ZVAL(array_ptr);
5155+ array_init(array_ptr);
5156+ INIT_PZVAL(array_ptr);
5157+ }
5158+ IF_G(get_array) = array_ptr;
5159+ break;
5160+ case PARSE_POST:
5161+ if(!IF_G(post_array)) {
5162+ ALLOC_ZVAL(array_ptr);
5163+ array_init(array_ptr);
5164+ INIT_PZVAL(array_ptr);
5165+ }
5166+ IF_G(post_array) = array_ptr;
5167+ break;
5168+ case PARSE_COOKIE:
5169+ if(!IF_G(cookie_array)) {
5170+ ALLOC_ZVAL(array_ptr);
5171+ array_init(array_ptr);
5172+ INIT_PZVAL(array_ptr);
5173+ }
5174+ IF_G(cookie_array) = array_ptr;
5175+ break;
5176+ }
5177+ Z_STRLEN(new_var) = val_len;
5178+ Z_STRVAL(new_var) = estrndup(*val, val_len);
5179+ Z_TYPE(new_var) = IS_STRING;
5180+
5181+ var_len = strlen(var);
5182+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5183+ strcpy(raw_var, "RAW_");
5184+ strlcat(raw_var,var,var_len+5);
5185+
5186+ php_register_variable_ex(raw_var, &new_var, array_ptr TSRMLS_DC);
5187+
5188+ php_strip_tags(*val, val_len, NULL, NULL, 0);
5189+
5190+ *new_val_len = strlen(*val);
5191+ return 1;
5192+}
5193+
5194+PHP_FUNCTION(my_get_raw)
5195+{
5196+ long arg;
5197+ char *var;
5198+ int var_len;
5199+ zval **tmp;
5200+ zval *array_ptr = NULL;
5201+ HashTable *hash_ptr;
5202+ char *raw_var;
5203+
5204+ if(zend_parse_parameters(2 TSRMLS_CC, "ls", &arg, &var, &var_len) == FAILURE) {
5205+ return;
5206+ }
5207+
5208+ switch(arg) {
5209+ case PARSE_GET:
5210+ array_ptr = IF_G(get_array);
5211+ break;
5212+ case PARSE_POST:
5213+ array_ptr = IF_G(post_array);
5214+ break;
5215+ case PARSE_COOKIE:
5216+ array_ptr = IF_G(post_array);
5217+ break;
5218+ }
5219+
5220+ if(!array_ptr) RETURN_FALSE;
5221+
5222+ /*
5223+ * I'm changing the variable name here because when running with register_globals on,
5224+ * the variable will end up in the global symbol table
5225+ */
5226+ raw_var = emalloc(var_len+5); /* RAW_ and a \0 */
5227+ strcpy(raw_var, "RAW_");
5228+ strlcat(raw_var,var,var_len+5);
5229+ hash_ptr = HASH_OF(array_ptr);
5230+
5231+ if(zend_hash_find(hash_ptr, raw_var, var_len+5, (void **)&tmp) == SUCCESS) {
5232+ *return_value = **tmp;
5233+ zval_copy_ctor(return_value);
5234+ } else {
5235+ RETVAL_FALSE;
5236+ }
5237+ efree(raw_var);
5238+}
5239+
5240diff -Nura php-4.4.1/sapi/apache/mod_php4.c hardening-patch-4.4.1-0.4.5/sapi/apache/mod_php4.c
5241--- php-4.4.1/sapi/apache/mod_php4.c 2005-05-19 18:14:46.000000000 +0200
5242+++ hardening-patch-4.4.1-0.4.5/sapi/apache/mod_php4.c 2005-10-30 17:12:13.000000000 +0100
5243@@ -452,7 +452,7 @@
5244 sapi_apache_get_fd,
5245 sapi_apache_force_http_10,
5246 sapi_apache_get_target_uid,
5247- sapi_apache_get_target_gid
5248+ sapi_apache_get_target_gid,
5249 };
5250 /* }}} */
5251
5252@@ -898,7 +898,11 @@
5253 {
5254 TSRMLS_FETCH();
5255 if (PG(expose_php)) {
5256+#if HARDENING_PATCH
5257+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5258+#else
5259 ap_add_version_component("PHP/" PHP_VERSION);
5260+#endif
5261 }
5262 }
5263 #endif
5264diff -Nura php-4.4.1/sapi/apache2filter/sapi_apache2.c hardening-patch-4.4.1-0.4.5/sapi/apache2filter/sapi_apache2.c
5265--- php-4.4.1/sapi/apache2filter/sapi_apache2.c 2005-08-03 16:49:50.000000000 +0200
5266+++ hardening-patch-4.4.1-0.4.5/sapi/apache2filter/sapi_apache2.c 2005-10-30 17:12:13.000000000 +0100
5267@@ -562,7 +562,11 @@
5268 {
5269 TSRMLS_FETCH();
5270 if (PG(expose_php)) {
5271+#if HARDENING_PATCH
5272+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5273+#else
5274 ap_add_version_component(p, "PHP/" PHP_VERSION);
5275+#endif
5276 }
5277 }
5278
5279diff -Nura php-4.4.1/sapi/apache2handler/sapi_apache2.c hardening-patch-4.4.1-0.4.5/sapi/apache2handler/sapi_apache2.c
5280--- php-4.4.1/sapi/apache2handler/sapi_apache2.c 2005-10-12 23:41:36.000000000 +0200
5281+++ hardening-patch-4.4.1-0.4.5/sapi/apache2handler/sapi_apache2.c 2005-10-30 17:12:13.000000000 +0100
5282@@ -340,7 +340,11 @@
5283 {
5284 TSRMLS_FETCH();
5285 if (PG(expose_php)) {
5286+#if HARDENING_PATCH
5287+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5288+#else
5289 ap_add_version_component(p, "PHP/" PHP_VERSION);
5290+#endif
5291 }
5292 }
5293
5294diff -Nura php-4.4.1/sapi/cgi/cgi_main.c hardening-patch-4.4.1-0.4.5/sapi/cgi/cgi_main.c
5295--- php-4.4.1/sapi/cgi/cgi_main.c 2005-10-06 22:39:26.000000000 +0200
5296+++ hardening-patch-4.4.1-0.4.5/sapi/cgi/cgi_main.c 2005-10-30 17:12:13.000000000 +0100
5297@@ -1440,11 +1440,19 @@
5298 SG(headers_sent) = 1;
5299 SG(request_info).no_headers = 1;
5300 }
5301+#if HARDENING_PATCH
5302+#if ZEND_DEBUG
5303+ 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());
5304+#else
5305+ 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());
5306+#endif
5307+#else
5308 #if ZEND_DEBUG
5309 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());
5310 #else
5311 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());
5312 #endif
5313+#endif
5314 php_end_ob_buffers(1 TSRMLS_CC);
5315 exit(0);
5316 break;
5317diff -Nura php-4.4.1/sapi/cli/php_cli.c hardening-patch-4.4.1-0.4.5/sapi/cli/php_cli.c
5318--- php-4.4.1/sapi/cli/php_cli.c 2005-10-11 20:59:23.000000000 +0200
5319+++ hardening-patch-4.4.1-0.4.5/sapi/cli/php_cli.c 2005-10-30 17:12:13.000000000 +0100
5320@@ -654,11 +654,19 @@
5321 if (php_request_startup(TSRMLS_C)==FAILURE) {
5322 goto err;
5323 }
5324+#if HARDENING_PATCH
5325+#if ZEND_DEBUG
5326+ 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());
5327+#else
5328+ 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());
5329+#endif
5330+#else
5331 #if ZEND_DEBUG
5332 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());
5333 #else
5334 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());
5335 #endif
5336+#endif
5337 php_end_ob_buffers(1 TSRMLS_CC);
5338 exit_status=0;
5339 goto out;
5340diff -Nura php-4.4.1/TSRM/TSRM.h hardening-patch-4.4.1-0.4.5/TSRM/TSRM.h
5341--- php-4.4.1/TSRM/TSRM.h 2005-07-26 15:34:52.000000000 +0200
5342+++ hardening-patch-4.4.1-0.4.5/TSRM/TSRM.h 2005-10-30 17:12:13.000000000 +0100
5343@@ -33,6 +33,13 @@
5344 # define TSRM_API
5345 #endif
5346
5347+#if HARDENING_PATCH
5348+# if HAVE_REALPATH
5349+# undef realpath
5350+# define realpath php_realpath
5351+# endif
5352+#endif
5353+
5354 /* Only compile multi-threading functions if we're in ZTS mode */
5355 #ifdef ZTS
5356
5357@@ -84,6 +91,7 @@
5358
5359 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5360
5361+
5362 #ifdef __cplusplus
5363 extern "C" {
5364 #endif
5365diff -Nura php-4.4.1/TSRM/tsrm_virtual_cwd.c hardening-patch-4.4.1-0.4.5/TSRM/tsrm_virtual_cwd.c
5366--- php-4.4.1/TSRM/tsrm_virtual_cwd.c 2005-08-03 16:51:24.000000000 +0200
5367+++ hardening-patch-4.4.1-0.4.5/TSRM/tsrm_virtual_cwd.c 2005-10-30 17:12:13.000000000 +0100
5368@@ -179,6 +179,165 @@
5369 return p;
5370 }
5371
5372+#if HARDENING_PATCH
5373+CWD_API char *php_realpath(const char *path, char *resolved)
5374+{
5375+ struct stat sb;
5376+ char *p, *q, *s;
5377+ size_t left_len, resolved_len;
5378+ unsigned symlinks;
5379+ int serrno, slen;
5380+ int is_dir = 1;
5381+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5382+
5383+ serrno = errno;
5384+ symlinks = 0;
5385+ if (path[0] == '/') {
5386+ resolved[0] = '/';
5387+ resolved[1] = '\0';
5388+ if (path[1] == '\0')
5389+ return (resolved);
5390+ resolved_len = 1;
5391+ left_len = strlcpy(left, path + 1, sizeof(left));
5392+ } else {
5393+ if (getcwd(resolved, PATH_MAX) == NULL) {
5394+ strlcpy(resolved, ".", PATH_MAX);
5395+ return (NULL);
5396+ }
5397+ resolved_len = strlen(resolved);
5398+ left_len = strlcpy(left, path, sizeof(left));
5399+ }
5400+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5401+ errno = ENAMETOOLONG;
5402+ return (NULL);
5403+ }
5404+
5405+ /*
5406+ * Iterate over path components in `left'.
5407+ */
5408+ while (left_len != 0) {
5409+ /*
5410+ * Extract the next path component and adjust `left'
5411+ * and its length.
5412+ */
5413+ p = strchr(left, '/');
5414+ s = p ? p : left + left_len;
5415+ if (s - left >= sizeof(next_token)) {
5416+ errno = ENAMETOOLONG;
5417+ return (NULL);
5418+ }
5419+ memcpy(next_token, left, s - left);
5420+ next_token[s - left] = '\0';
5421+ left_len -= s - left;
5422+ if (p != NULL)
5423+ memmove(left, s + 1, left_len + 1);
5424+ if (resolved[resolved_len - 1] != '/') {
5425+ if (resolved_len + 1 >= PATH_MAX) {
5426+ errno = ENAMETOOLONG;
5427+ return (NULL);
5428+ }
5429+ resolved[resolved_len++] = '/';
5430+ resolved[resolved_len] = '\0';
5431+ }
5432+ if (next_token[0] == '\0')
5433+ continue;
5434+ else if (strcmp(next_token, ".") == 0)
5435+ continue;
5436+ else if (strcmp(next_token, "..") == 0) {
5437+ /*
5438+ * Strip the last path component except when we have
5439+ * single "/"
5440+ */
5441+ if (!is_dir) {
5442+ errno = ENOENT;
5443+ return (NULL);
5444+ }
5445+ if (resolved_len > 1) {
5446+ resolved[resolved_len - 1] = '\0';
5447+ q = strrchr(resolved, '/');
5448+ *q = '\0';
5449+ resolved_len = q - resolved;
5450+ }
5451+ continue;
5452+ }
5453+
5454+ /*
5455+ * Append the next path component and lstat() it. If
5456+ * lstat() fails we still can return successfully if
5457+ * there are no more path components left.
5458+ */
5459+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
5460+ if (resolved_len >= PATH_MAX) {
5461+ errno = ENAMETOOLONG;
5462+ return (NULL);
5463+ }
5464+ if (lstat(resolved, &sb) != 0) {
5465+ if (errno == ENOENT && p == NULL) {
5466+ errno = serrno;
5467+ return (resolved);
5468+ }
5469+ return (NULL);
5470+ }
5471+ if (S_ISLNK(sb.st_mode)) {
5472+ if (symlinks++ > MAXSYMLINKS) {
5473+ errno = ELOOP;
5474+ return (NULL);
5475+ }
5476+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
5477+ if (slen < 0)
5478+ return (NULL);
5479+ symlink[slen] = '\0';
5480+ if (symlink[0] == '/') {
5481+ resolved[1] = 0;
5482+ resolved_len = 1;
5483+ } else if (resolved_len > 1) {
5484+ /* Strip the last path component. */
5485+ resolved[resolved_len - 1] = '\0';
5486+ q = strrchr(resolved, '/');
5487+ *q = '\0';
5488+ resolved_len = q - resolved;
5489+ }
5490+
5491+ /*
5492+ * If there are any path components left, then
5493+ * append them to symlink. The result is placed
5494+ * in `left'.
5495+ */
5496+ if (p != NULL) {
5497+ if (symlink[slen - 1] != '/') {
5498+ if (slen + 1 >= sizeof(symlink)) {
5499+ errno = ENAMETOOLONG;
5500+ return (NULL);
5501+ }
5502+ symlink[slen] = '/';
5503+ symlink[slen + 1] = 0;
5504+ }
5505+ left_len = strlcat(symlink, left, sizeof(left));
5506+ if (left_len >= sizeof(left)) {
5507+ errno = ENAMETOOLONG;
5508+ return (NULL);
5509+ }
5510+ }
5511+ left_len = strlcpy(left, symlink, sizeof(left));
5512+ } else {
5513+ if (S_ISDIR(sb.st_mode)) {
5514+ is_dir = 1;
5515+ } else {
5516+ is_dir = 0;
5517+ }
5518+ }
5519+ }
5520+
5521+ /*
5522+ * Remove trailing slash except when the resolved pathname
5523+ * is a single "/".
5524+ */
5525+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
5526+ resolved[resolved_len - 1] = '\0';
5527+ return (resolved);
5528+}
5529+#endif
5530+
5531 CWD_API void virtual_cwd_startup(void)
5532 {
5533 char cwd[MAXPATHLEN];
5534@@ -313,8 +472,7 @@
5535 path = resolved_path;
5536 path_length = strlen(path);
5537 } else {
5538- /* disable for now
5539- return 1; */
5540+ return 1;
5541 }
5542 }
5543 } else { /* Concat current directory with relative path and then run realpath() on it */
5544@@ -340,9 +498,8 @@
5545 path = resolved_path;
5546 path_length = strlen(path);
5547 } else {
5548- /* disable for now
5549 free(tmp);
5550- return 1; */
5551+ return 1;
5552 }
5553 }
5554 free(tmp);
5555diff -Nura php-4.4.1/TSRM/tsrm_virtual_cwd.h hardening-patch-4.4.1-0.4.5/TSRM/tsrm_virtual_cwd.h
5556--- php-4.4.1/TSRM/tsrm_virtual_cwd.h 2005-08-03 16:51:24.000000000 +0200
5557+++ hardening-patch-4.4.1-0.4.5/TSRM/tsrm_virtual_cwd.h 2005-10-30 17:12:13.000000000 +0100
5558@@ -128,6 +128,22 @@
5559
5560 typedef int (*verify_path_func)(const cwd_state *);
5561
5562+#ifndef HAVE_STRLCPY
5563+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
5564+#undef strlcpy
5565+#define strlcpy php_strlcpy
5566+#endif
5567+
5568+#ifndef HAVE_STRLCAT
5569+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
5570+#undef strlcat
5571+#define strlcat php_strlcat
5572+#endif
5573+
5574+
5575+#if HARDENING_PATCH
5576+CWD_API char *php_realpath(const char *path, char *resolved);
5577+#endif
5578 CWD_API void virtual_cwd_startup(void);
5579 CWD_API void virtual_cwd_shutdown(void);
5580 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
5581diff -Nura php-4.4.1/Zend/zend_alloc.c hardening-patch-4.4.1-0.4.5/Zend/zend_alloc.c
5582--- php-4.4.1/Zend/zend_alloc.c 2005-08-18 17:14:48.000000000 +0200
5583+++ hardening-patch-4.4.1-0.4.5/Zend/zend_alloc.c 2005-10-30 17:12:13.000000000 +0100
5584@@ -56,6 +56,11 @@
5585 # define END_MAGIC_SIZE 0
5586 #endif
5587
5588+#if HARDENING_PATCH_MM_PROTECT
5589+# define CANARY_SIZE sizeof(unsigned int)
5590+#else
5591+# define CANARY_SIZE 0
5592+#endif
5593
5594 # if MEMORY_LIMIT
5595 # if ZEND_DEBUG
5596@@ -96,9 +101,17 @@
5597 if (p==AG(head)) { \
5598 AG(head) = p->pNext; \
5599 } else { \
5600+ if (p != p->pLast->pNext) { \
5601+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5602+ exit(1); \
5603+ } \
5604 p->pLast->pNext = p->pNext; \
5605 } \
5606 if (p->pNext) { \
5607+ if (p != p->pNext->pLast) { \
5608+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5609+ exit(1); \
5610+ } \
5611 p->pNext->pLast = p->pLast; \
5612 }
5613
5614@@ -130,6 +143,12 @@
5615 DECLARE_CACHE_VARS();
5616 TSRMLS_FETCH();
5617
5618+#if HARDENING_PATCH_MM_PROTECT
5619+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
5620+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
5621+ exit(1);
5622+ }
5623+#endif
5624 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
5625
5626 if (!ZEND_DISABLE_MEMORY_CACHE && (CACHE_INDEX < MAX_CACHED_MEMORY) && (AG(cache_count)[CACHE_INDEX] > 0)) {
5627@@ -147,6 +166,10 @@
5628 AG(cache_stats)[CACHE_INDEX][1]++;
5629 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5630 #endif
5631+#if HARDENING_PATCH_MM_PROTECT
5632+ p->canary = HG(canary_1);
5633+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5634+#endif
5635 p->cached = 0;
5636 p->size = size;
5637 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5638@@ -162,7 +185,7 @@
5639 AG(allocated_memory_peak) = AG(allocated_memory);
5640 }
5641 #endif
5642- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
5643+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
5644 }
5645
5646 HANDLE_BLOCK_INTERRUPTIONS();
5647@@ -192,7 +215,10 @@
5648 # endif
5649 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5650 #endif
5651-
5652+#if HARDENING_PATCH_MM_PROTECT
5653+ p->canary = HG(canary_1);
5654+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5655+#endif
5656 HANDLE_UNBLOCK_INTERRUPTIONS();
5657 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5658 }
5659@@ -219,17 +245,36 @@
5660 return emalloc_rel(lval + offset);
5661 }
5662 }
5663-
5664+
5665+#if HARDENING_PATCH
5666+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
5667+#endif
5668 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%ld * %ld + %ld)", nmemb, size, offset);
5669 return 0;
5670 }
5671
5672 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5673 {
5674+#if HARDENING_PATCH_MM_PROTECT
5675+ unsigned int canary_2;
5676+#endif
5677 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
5678 DECLARE_CACHE_VARS();
5679 TSRMLS_FETCH();
5680
5681+#if HARDENING_PATCH_MM_PROTECT
5682+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
5683+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5684+ if (canary_2 != HG(canary_2)) {
5685+efree_canary_mismatch:
5686+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
5687+ exit(1);
5688+ }
5689+ /* to catch double efree()s */
5690+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
5691+ p->canary = 0;
5692+#endif
5693+
5694 #if defined(ZTS) && TSRM_DEBUG
5695 if (p->thread_id != tsrm_thread_id()) {
5696 tsrm_error(TSRM_ERROR_LEVEL_ERROR, "Memory block allocated at %s:(%d) on thread %x freed at %s:(%d) on thread %x, ignoring",
5697@@ -274,6 +319,9 @@
5698 size_t _size = nmemb * size;
5699
5700 if (nmemb && (_size/nmemb!=size)) {
5701+#if HARDENING_PATCH
5702+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
5703+#endif
5704 fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
5705 #if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
5706 kill(getpid(), SIGSEGV);
5707@@ -293,6 +341,9 @@
5708
5709 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5710 {
5711+#if HARDENING_PATCH_MM_PROTECT
5712+ unsigned int canary_2;
5713+#endif
5714 zend_mem_header *p;
5715 zend_mem_header *orig;
5716 DECLARE_CACHE_VARS();
5717@@ -304,6 +355,16 @@
5718
5719 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
5720
5721+#if HARDENING_PATCH_MM_PROTECT
5722+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
5723+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5724+ if (canary_2 != HG(canary_2)) {
5725+erealloc_canary_mismatch:
5726+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
5727+ exit(1);
5728+ }
5729+#endif
5730+
5731 #if defined(ZTS) && TSRM_DEBUG
5732 if (p->thread_id != tsrm_thread_id()) {
5733 void *new_p;
5734@@ -327,7 +388,7 @@
5735 }
5736 #endif
5737 REMOVE_POINTER_FROM_LIST(p);
5738- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
5739+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
5740 if (!p) {
5741 if (!allow_failure) {
5742 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
5743@@ -349,6 +410,9 @@
5744 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5745 #endif
5746
5747+#if HARDENING_PATCH_MM_PROTECT
5748+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5749+#endif
5750 p->size = size;
5751
5752 HANDLE_UNBLOCK_INTERRUPTIONS();
5753@@ -423,6 +487,10 @@
5754 {
5755 AG(head) = NULL;
5756
5757+#if HARDENING_PATCH_MM_PROTECT
5758+ HG(canary_1) = zend_canary();
5759+ HG(canary_2) = zend_canary();
5760+#endif
5761 #if MEMORY_LIMIT
5762 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
5763 AG(allocated_memory) = 0;
5764diff -Nura php-4.4.1/Zend/zend_alloc.h hardening-patch-4.4.1-0.4.5/Zend/zend_alloc.h
5765--- php-4.4.1/Zend/zend_alloc.h 2005-06-07 15:37:33.000000000 +0200
5766+++ hardening-patch-4.4.1-0.4.5/Zend/zend_alloc.h 2005-10-30 17:12:13.000000000 +0100
5767@@ -32,6 +32,9 @@
5768 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
5769
5770 typedef struct _zend_mem_header {
5771+#if HARDENING_PATCH_MM_PROTECT
5772+ unsigned int canary;
5773+#endif
5774 #if ZEND_DEBUG
5775 long magic;
5776 char *filename;
5777diff -Nura php-4.4.1/Zend/zend_builtin_functions.c hardening-patch-4.4.1-0.4.5/Zend/zend_builtin_functions.c
5778--- php-4.4.1/Zend/zend_builtin_functions.c 2005-06-23 14:20:47.000000000 +0200
5779+++ hardening-patch-4.4.1-0.4.5/Zend/zend_builtin_functions.c 2005-10-30 17:12:13.000000000 +0100
5780@@ -49,6 +49,9 @@
5781 static ZEND_FUNCTION(crash);
5782 #endif
5783 #endif
5784+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5785+static ZEND_FUNCTION(heap_overflow);
5786+#endif
5787 static ZEND_FUNCTION(get_included_files);
5788 static ZEND_FUNCTION(is_subclass_of);
5789 static ZEND_FUNCTION(is_a);
5790@@ -101,6 +104,9 @@
5791 ZEND_FE(crash, NULL)
5792 #endif
5793 #endif
5794+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5795+ ZEND_FE(heap_overflow, NULL)
5796+#endif
5797 ZEND_FE(get_included_files, NULL)
5798 ZEND_FALIAS(get_required_files, get_included_files, NULL)
5799 ZEND_FE(is_subclass_of, NULL)
5800@@ -805,6 +811,19 @@
5801
5802 #endif /* ZEND_DEBUG */
5803
5804+
5805+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5806+ZEND_FUNCTION(heap_overflow)
5807+{
5808+ char *nowhere = emalloc(10);
5809+
5810+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
5811+
5812+ efree(nowhere);
5813+}
5814+#endif
5815+
5816+
5817 /* {{{ proto array get_included_files(void)
5818 Returns an array with the file names that were include_once()'d */
5819 ZEND_FUNCTION(get_included_files)
5820diff -Nura php-4.4.1/Zend/zend.c hardening-patch-4.4.1-0.4.5/Zend/zend.c
5821--- php-4.4.1/Zend/zend.c 2005-06-09 12:14:25.000000000 +0200
5822+++ hardening-patch-4.4.1-0.4.5/Zend/zend.c 2005-11-01 17:47:17.328771120 +0100
5823@@ -53,6 +53,12 @@
5824 ZEND_API void (*zend_unblock_interruptions)(void);
5825 ZEND_API void (*zend_ticks_function)(int ticks);
5826 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
5827+#if HARDENING_PATCH
5828+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
5829+#endif
5830+#if HARDENING_PATCH_INC_PROTECT
5831+ZEND_API int (*zend_is_valid_include)(zval *z);
5832+#endif
5833
5834 void (*zend_on_timeout)(int seconds TSRMLS_DC);
5835
5836@@ -70,9 +76,390 @@
5837 return SUCCESS;
5838 }
5839
5840+#if HARDENING_PATCH
5841+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
5842+{
5843+ if (!new_value) {
5844+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
5845+ } else {
5846+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
5847+ }
5848+ return SUCCESS;
5849+}
5850+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
5851+{
5852+ if (!new_value) {
5853+ EG(hphp_log_syslog_facility) = LOG_USER;
5854+ } else {
5855+ EG(hphp_log_syslog_facility) = atoi(new_value);
5856+ }
5857+ return SUCCESS;
5858+}
5859+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
5860+{
5861+ if (!new_value) {
5862+ EG(hphp_log_syslog_priority) = LOG_ALERT;
5863+ } else {
5864+ EG(hphp_log_syslog_priority) = atoi(new_value);
5865+ }
5866+ return SUCCESS;
5867+}
5868+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
5869+{
5870+ if (!new_value) {
5871+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
5872+ } else {
5873+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
5874+ }
5875+ return SUCCESS;
5876+}
5877+static ZEND_INI_MH(OnUpdateHPHP_log_script)
5878+{
5879+ if (!new_value) {
5880+ EG(hphp_log_script) = S_ALL & (~S_MEMORY) & (~S_INTERNAL);
5881+ } else {
5882+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
5883+ }
5884+ return SUCCESS;
5885+}
5886+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
5887+{
5888+ if (EG(hphp_log_scriptname)) {
5889+ pefree(EG(hphp_log_scriptname),1);
5890+ }
5891+ EG(hphp_log_scriptname) = NULL;
5892+ if (new_value) {
5893+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
5894+ }
5895+ return SUCCESS;
5896+}
5897+
5898+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
5899+{
5900+ char *s = NULL, *e, *val;
5901+ unsigned long dummy = 1;
5902+
5903+ if (!new_value) {
5904+include_whitelist_destroy:
5905+ if (HG(include_whitelist)) {
5906+ zend_hash_destroy(HG(include_whitelist));
5907+ pefree(HG(include_whitelist),1);
5908+ }
5909+ HG(include_whitelist) = NULL;
5910+ return SUCCESS;
5911+ }
5912+ if (!(*new_value)) {
5913+ goto include_whitelist_destroy;
5914+ }
5915+
5916+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
5917+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
5918+
5919+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5920+ e = val;
5921+
5922+ while (*e) {
5923+ switch (*e) {
5924+ case ' ':
5925+ case ',':
5926+ if (s) {
5927+ *e = '\0';
5928+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5929+ s = NULL;
5930+ }
5931+ break;
5932+ default:
5933+ if (!s) {
5934+ s = e;
5935+ }
5936+ break;
5937+ }
5938+ e++;
5939+ }
5940+ if (s) {
5941+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5942+ }
5943+ efree(val);
5944+
5945+ return SUCCESS;
5946+}
5947+
5948+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
5949+{
5950+ char *s = NULL, *e, *val;
5951+ unsigned long dummy = 1;
5952+
5953+ if (!new_value) {
5954+include_blacklist_destroy:
5955+ if (HG(include_blacklist)) {
5956+ zend_hash_destroy(HG(include_blacklist));
5957+ pefree(HG(include_blacklist),1);
5958+ }
5959+ HG(include_blacklist) = NULL;
5960+ return SUCCESS;
5961+ }
5962+ if (!(*new_value)) {
5963+ goto include_blacklist_destroy;
5964+ }
5965+
5966+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
5967+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
5968+
5969+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5970+ e = val;
5971+
5972+ while (*e) {
5973+ switch (*e) {
5974+ case ' ':
5975+ case ',':
5976+ if (s) {
5977+ *e = '\0';
5978+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5979+ s = NULL;
5980+ }
5981+ break;
5982+ default:
5983+ if (!s) {
5984+ s = e;
5985+ }
5986+ break;
5987+ }
5988+ e++;
5989+ }
5990+ if (s) {
5991+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5992+ }
5993+ efree(val);
5994+
5995+ return SUCCESS;
5996+}
5997+
5998+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
5999+{
6000+ char *s = NULL, *e, *val;
6001+ unsigned long dummy = 1;
6002+
6003+ if (!new_value) {
6004+eval_whitelist_destroy:
6005+ if (HG(eval_whitelist)) {
6006+ zend_hash_destroy(HG(eval_whitelist));
6007+ pefree(HG(eval_whitelist),1);
6008+ }
6009+ HG(eval_whitelist) = NULL;
6010+ return SUCCESS;
6011+ }
6012+ if (!(*new_value)) {
6013+ goto eval_whitelist_destroy;
6014+ }
6015+
6016+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
6017+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
6018+
6019+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6020+ e = val;
6021+
6022+ while (*e) {
6023+ switch (*e) {
6024+ case ' ':
6025+ case ',':
6026+ if (s) {
6027+ *e = '\0';
6028+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6029+ s = NULL;
6030+ }
6031+ break;
6032+ default:
6033+ if (!s) {
6034+ s = e;
6035+ }
6036+ break;
6037+ }
6038+ e++;
6039+ }
6040+ if (s) {
6041+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6042+ }
6043+ efree(val);
6044+
6045+ return SUCCESS;
6046+}
6047+
6048+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
6049+{
6050+ char *s = NULL, *e, *val;
6051+ unsigned long dummy = 1;
6052+
6053+ if (!new_value) {
6054+eval_blacklist_destroy:
6055+ if (HG(eval_blacklist)) {
6056+ zend_hash_destroy(HG(eval_blacklist));
6057+ pefree(HG(eval_blacklist), 1);
6058+ }
6059+ HG(eval_blacklist) = NULL;
6060+ return SUCCESS;
6061+ }
6062+ if (!(*new_value)) {
6063+ goto eval_blacklist_destroy;
6064+ }
6065+
6066+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
6067+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
6068+
6069+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6070+ e = val;
6071+
6072+ while (*e) {
6073+ switch (*e) {
6074+ case ' ':
6075+ case ',':
6076+ if (s) {
6077+ *e = '\0';
6078+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6079+ s = NULL;
6080+ }
6081+ break;
6082+ default:
6083+ if (!s) {
6084+ s = e;
6085+ }
6086+ break;
6087+ }
6088+ e++;
6089+ }
6090+ if (s) {
6091+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6092+ }
6093+ efree(val);
6094+
6095+
6096+ return SUCCESS;
6097+}
6098+
6099+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
6100+{
6101+ char *s = NULL, *e, *val;
6102+ unsigned long dummy = 1;
6103+
6104+ if (!new_value) {
6105+func_whitelist_destroy:
6106+ if (HG(func_whitelist)) {
6107+ zend_hash_destroy(HG(func_whitelist));
6108+ pefree(HG(func_whitelist),1);
6109+ }
6110+ HG(func_whitelist) = NULL;
6111+ return SUCCESS;
6112+ }
6113+ if (!(*new_value)) {
6114+ goto func_whitelist_destroy;
6115+ }
6116+
6117+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6118+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6119+
6120+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6121+ e = val;
6122+
6123+ while (*e) {
6124+ switch (*e) {
6125+ case ' ':
6126+ case ',':
6127+ if (s) {
6128+ *e = '\0';
6129+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6130+ s = NULL;
6131+ }
6132+ break;
6133+ default:
6134+ if (!s) {
6135+ s = e;
6136+ }
6137+ break;
6138+ }
6139+ e++;
6140+ }
6141+ if (s) {
6142+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6143+ }
6144+ efree(val);
6145+
6146+ return SUCCESS;
6147+}
6148+
6149+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6150+{
6151+ char *s = NULL, *e, *val;
6152+ unsigned long dummy = 1;
6153+
6154+ if (!new_value) {
6155+func_blacklist_destroy:
6156+ if (HG(func_blacklist)) {
6157+ zend_hash_destroy(HG(func_blacklist));
6158+ pefree(HG(func_blacklist),1);
6159+ }
6160+ HG(func_blacklist) = NULL;
6161+ return SUCCESS;
6162+ }
6163+ if (!(*new_value)) {
6164+ goto func_blacklist_destroy;
6165+ }
6166+
6167+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6168+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6169+
6170+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6171+ e = val;
6172+
6173+ while (*e) {
6174+ switch (*e) {
6175+ case ' ':
6176+ case ',':
6177+ if (s) {
6178+ *e = '\0';
6179+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6180+ s = NULL;
6181+ }
6182+ break;
6183+ default:
6184+ if (!s) {
6185+ s = e;
6186+ }
6187+ break;
6188+ }
6189+ e++;
6190+ }
6191+ if (s) {
6192+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6193+ }
6194+ efree(val);
6195+
6196+
6197+ return SUCCESS;
6198+}
6199+
6200+#endif
6201
6202 ZEND_INI_BEGIN()
6203 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6204+#if HARDENING_PATCH
6205+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6206+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6207+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6208+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6209+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6210+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6211+ 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)
6212+
6213+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6214+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6215+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6216+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6217+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6218+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6219+
6220+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
6221+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
6222+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6223+#endif
6224 ZEND_INI_END()
6225
6226
6227@@ -354,8 +741,12 @@
6228 zend_init_rsrc_plist(TSRMLS_C);
6229 EG(lambda_count)=0;
6230 EG(user_error_handler) = NULL;
6231+ EG(in_code_type) = 0;
6232 EG(in_execution) = 0;
6233 EG(current_execute_data) = NULL;
6234+#if HARDENING_PATCH
6235+ EG(hphp_log_scriptname) = NULL;
6236+#endif
6237 }
6238
6239
6240@@ -420,6 +811,14 @@
6241 extern zend_scanner_globals language_scanner_globals;
6242 #endif
6243
6244+ /* Set up Hardening-Patch utility functions first */
6245+#if HARDENING_PATCH
6246+ zend_security_log = utility_functions->security_log_function;
6247+#endif
6248+#if HARDENING_PATCH_INC_PROTECT
6249+ zend_is_valid_include = utility_functions->is_valid_include;
6250+#endif
6251+
6252 #ifdef ZTS
6253 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6254 #else
6255@@ -623,6 +1022,7 @@
6256 }
6257 CG(unclean_shutdown) = 1;
6258 CG(in_compilation) = EG(in_execution) = 0;
6259+ EG(in_code_type) = 0;
6260 EG(current_execute_data) = NULL;
6261 longjmp(EG(bailout), FAILURE);
6262 }
6263diff -Nura php-4.4.1/Zend/zend_canary.c hardening-patch-4.4.1-0.4.5/Zend/zend_canary.c
6264--- php-4.4.1/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6265+++ hardening-patch-4.4.1-0.4.5/Zend/zend_canary.c 2005-10-30 17:12:13.000000000 +0100
6266@@ -0,0 +1,58 @@
6267+/*
6268+ +----------------------------------------------------------------------+
6269+ | Hardening-Patch for PHP |
6270+ +----------------------------------------------------------------------+
6271+ | Copyright (c) 2004-2005 Stefan Esser |
6272+ +----------------------------------------------------------------------+
6273+ | This source file is subject to version 2.02 of the PHP license, |
6274+ | that is bundled with this package in the file LICENSE, and is |
6275+ | available at through the world-wide-web at |
6276+ | http://www.php.net/license/2_02.txt. |
6277+ | If you did not receive a copy of the PHP license and are unable to |
6278+ | obtain it through the world-wide-web, please send a note to |
6279+ | license@php.net so we can mail you a copy immediately. |
6280+ +----------------------------------------------------------------------+
6281+ | Author: Stefan Esser <sesser@hardened-php.net> |
6282+ +----------------------------------------------------------------------+
6283+ */
6284+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6285+
6286+#include "zend.h"
6287+
6288+#include <stdio.h>
6289+#include <stdlib.h>
6290+
6291+
6292+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6293+
6294+/* will be replaced later with more compatible method */
6295+ZEND_API unsigned int zend_canary()
6296+{
6297+ time_t t;
6298+ unsigned int canary;
6299+ int fd;
6300+
6301+ fd = open("/dev/urandom", 0);
6302+ if (fd != -1) {
6303+ int r = read(fd, &canary, sizeof(canary));
6304+ close(fd);
6305+ if (r == sizeof(canary)) {
6306+ return (canary);
6307+ }
6308+ }
6309+ /* not good but we never want to do this */
6310+ time(&t);
6311+ canary = *(unsigned int *)&t + getpid() << 16;
6312+ return (canary);
6313+}
6314+#endif
6315+
6316+
6317+/*
6318+ * Local variables:
6319+ * tab-width: 4
6320+ * c-basic-offset: 4
6321+ * End:
6322+ * vim600: sw=4 ts=4 fdm=marker
6323+ * vim<600: sw=4 ts=4
6324+ */
6325diff -Nura php-4.4.1/Zend/zend_compile.c hardening-patch-4.4.1-0.4.5/Zend/zend_compile.c
6326--- php-4.4.1/Zend/zend_compile.c 2005-10-07 10:42:49.000000000 +0200
6327+++ hardening-patch-4.4.1-0.4.5/Zend/zend_compile.c 2005-10-30 17:12:13.000000000 +0100
6328@@ -768,6 +768,13 @@
6329 op_array.function_name = name;
6330 op_array.arg_types = NULL;
6331 op_array.return_reference = return_reference;
6332+#if HARDENING_PATCH
6333+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6334+ op_array.created_by_eval = 1;
6335+ } else {
6336+ op_array.created_by_eval = 0;
6337+ }
6338+#endif
6339
6340 if (is_method) {
6341 if (zend_hash_add(&CG(active_class_entry)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
6342diff -Nura php-4.4.1/Zend/zend_compile.h hardening-patch-4.4.1-0.4.5/Zend/zend_compile.h
6343--- php-4.4.1/Zend/zend_compile.h 2005-06-06 11:30:09.000000000 +0200
6344+++ hardening-patch-4.4.1-0.4.5/Zend/zend_compile.h 2005-10-30 17:12:13.000000000 +0100
6345@@ -106,6 +106,9 @@
6346 char *filename;
6347
6348 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6349+#if HARDENING_PATCH
6350+ zend_bool created_by_eval;
6351+#endif
6352 };
6353
6354
6355@@ -549,6 +552,7 @@
6356 #define ZEND_USER_FUNCTION 2
6357 #define ZEND_OVERLOADED_FUNCTION 3
6358 #define ZEND_EVAL_CODE 4
6359+#define ZEND_SANDBOX_CODE 6
6360
6361 #define ZEND_INTERNAL_CLASS 1
6362 #define ZEND_USER_CLASS 2
6363diff -Nura php-4.4.1/Zend/zend_constants.c hardening-patch-4.4.1-0.4.5/Zend/zend_constants.c
6364--- php-4.4.1/Zend/zend_constants.c 2004-07-13 21:29:45.000000000 +0200
6365+++ hardening-patch-4.4.1-0.4.5/Zend/zend_constants.c 2005-10-30 17:12:13.000000000 +0100
6366@@ -111,6 +111,73 @@
6367 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6368
6369 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6370+#if HARDENING_PATCH
6371+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6372+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6373+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6374+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6375+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6376+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6377+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6378+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6379+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6380+
6381+ /* error levels */
6382+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6383+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6384+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6385+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6386+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6387+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6388+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6389+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6390+ /* facility: type of program logging the message */
6391+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6392+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6393+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6394+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6395+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6396+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6397+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6398+#ifdef LOG_NEWS
6399+ /* No LOG_NEWS on HP-UX */
6400+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6401+#endif
6402+#ifdef LOG_UUCP
6403+ /* No LOG_UUCP on HP-UX */
6404+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6405+#endif
6406+#ifdef LOG_CRON
6407+ /* apparently some systems don't have this one */
6408+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6409+#endif
6410+#ifdef LOG_AUTHPRIV
6411+ /* AIX doesn't have LOG_AUTHPRIV */
6412+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
6413+#endif
6414+#if !defined(PHP_WIN32) && !defined(NETWARE)
6415+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
6416+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
6417+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
6418+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
6419+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
6420+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
6421+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
6422+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
6423+#endif
6424+ /* options */
6425+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
6426+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
6427+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
6428+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
6429+#ifdef LOG_NOWAIT
6430+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
6431+#endif
6432+#ifdef LOG_PERROR
6433+ /* AIX doesn't have LOG_PERROR */
6434+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
6435+#endif
6436+#endif
6437
6438 /* true/false constants */
6439 {
6440diff -Nura php-4.4.1/Zend/zend_errors.h hardening-patch-4.4.1-0.4.5/Zend/zend_errors.h
6441--- php-4.4.1/Zend/zend_errors.h 2002-12-31 17:22:59.000000000 +0100
6442+++ hardening-patch-4.4.1-0.4.5/Zend/zend_errors.h 2005-10-30 17:12:13.000000000 +0100
6443@@ -36,5 +36,17 @@
6444 #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)
6445 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
6446
6447+#if HARDENING_PATCH
6448+#define S_MEMORY (1<<0L)
6449+#define S_VARS (1<<1L)
6450+#define S_FILES (1<<2L)
6451+#define S_INCLUDE (1<<3L)
6452+#define S_SQL (1<<4L)
6453+#define S_EXECUTOR (1<<5L)
6454+#define S_MISC (1<<30L)
6455+#define S_INTERNAL (1<<29L)
6456+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
6457+#endif
6458+
6459 #endif /* ZEND_ERRORS_H */
6460
6461diff -Nura php-4.4.1/Zend/zend_execute_API.c hardening-patch-4.4.1-0.4.5/Zend/zend_execute_API.c
6462--- php-4.4.1/Zend/zend_execute_API.c 2005-08-02 19:52:33.000000000 +0200
6463+++ hardening-patch-4.4.1-0.4.5/Zend/zend_execute_API.c 2005-10-30 17:12:13.000000000 +0100
6464@@ -142,6 +142,7 @@
6465 EG(class_table) = CG(class_table);
6466
6467 EG(in_execution) = 0;
6468+ EG(in_code_type) = 0;
6469
6470 zend_ptr_stack_init(&EG(argument_stack));
6471
6472@@ -431,12 +432,14 @@
6473 zend_execute_data execute_data;
6474
6475 /* Initialize execute_data */
6476+ memset(&execute_data, 0, sizeof(execute_data));
6477 EX(fbc) = NULL;
6478 EX(object).ptr = NULL;
6479 EX(ce) = NULL;
6480 EX(Ts) = NULL;
6481 EX(op_array) = NULL;
6482 EX(opline) = NULL;
6483+ EX(execute_depth) = 0;
6484
6485 *retval_ptr_ptr = NULL;
6486
6487@@ -494,6 +497,39 @@
6488 zval_dtor(&function_name_copy);
6489 return FAILURE;
6490 }
6491+#if HARDENING_PATCH
6492+ if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
6493+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6494+ if (HG(eval_whitelist) != NULL) {
6495+ if (!zend_hash_exists(HG(eval_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
6496+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_copy.value.str.val);
6497+ zval_dtor(&function_name_copy);
6498+ zend_bailout();
6499+ }
6500+ } else if (HG(eval_blacklist) != NULL) {
6501+ if (zend_hash_exists(HG(eval_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
6502+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_copy.value.str.val);
6503+ zval_dtor(&function_name_copy);
6504+ zend_bailout();
6505+ }
6506+ }
6507+ }
6508+
6509+ if (HG(func_whitelist) != NULL) {
6510+ if (!zend_hash_exists(HG(func_whitelist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
6511+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_copy.value.str.val);
6512+ zval_dtor(&function_name_copy);
6513+ zend_bailout();
6514+ }
6515+ } else if (HG(func_blacklist) != NULL) {
6516+ if (zend_hash_exists(HG(func_blacklist), function_name_copy.value.str.val, function_name_copy.value.str.len+1)) {
6517+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_copy.value.str.val);
6518+ zval_dtor(&function_name_copy);
6519+ zend_bailout();
6520+ }
6521+ }
6522+ }
6523+#endif
6524 zval_dtor(&function_name_copy);
6525
6526 for (i=0; i<param_count; i++) {
6527@@ -606,8 +642,7 @@
6528 return SUCCESS;
6529 }
6530
6531-
6532-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6533+ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
6534 {
6535 zval pv;
6536 zend_op_array *new_op_array;
6537@@ -640,6 +675,7 @@
6538 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
6539 zend_op **original_opline_ptr = EG(opline_ptr);
6540
6541+ new_op_array->type = type;
6542 EG(return_value_ptr_ptr) = &local_retval_ptr;
6543 EG(active_op_array) = new_op_array;
6544 EG(no_extensions)=1;
6545@@ -673,6 +709,10 @@
6546 return retval;
6547 }
6548
6549+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6550+{
6551+ return (zend_eval_string_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
6552+}
6553
6554 void execute_new_code(TSRMLS_D)
6555 {
6556diff -Nura php-4.4.1/Zend/zend_execute.c hardening-patch-4.4.1-0.4.5/Zend/zend_execute.c
6557--- php-4.4.1/Zend/zend_execute.c 2005-10-13 10:46:27.000000000 +0200
6558+++ hardening-patch-4.4.1-0.4.5/Zend/zend_execute.c 2005-10-30 17:12:13.000000000 +0100
6559@@ -1042,6 +1042,7 @@
6560 zend_execute_data execute_data;
6561
6562 /* Initialize execute_data */
6563+ memset(&execute_data, 0, sizeof(execute_data));
6564 EX(fbc) = NULL;
6565 EX(ce) = NULL;
6566 EX(object).ptr = NULL;
6567@@ -1053,9 +1054,21 @@
6568 }
6569 EX(prev_execute_data) = EG(current_execute_data);
6570 EX(original_in_execution)=EG(in_execution);
6571+ EX(original_in_code_type)=EG(in_code_type);
6572
6573 EG(current_execute_data) = &execute_data;
6574
6575+#if HARDENING_PATCH
6576+ EX(execute_depth) = 0;
6577+
6578+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval) && EG(in_code_type) != ZEND_SANDBOX_CODE) {
6579+ EG(in_code_type) = ZEND_EVAL_CODE;
6580+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
6581+ EG(in_code_type) = ZEND_SANDBOX_CODE;
6582+ op_array->type = ZEND_EVAL_CODE;
6583+ }
6584+#endif
6585+
6586 EG(in_execution) = 1;
6587 if (op_array->start_op) {
6588 EX(opline) = op_array->start_op;
6589@@ -1087,6 +1100,19 @@
6590 }
6591 }
6592
6593+#if HARDENING_PATCH
6594+ if (EX(prev_execute_data) == NULL) {
6595+ EX(execute_depth) = 0;
6596+ } else {
6597+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
6598+ }
6599+
6600+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
6601+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
6602+ zend_bailout();
6603+ }
6604+#endif
6605+
6606 while (1) {
6607 #ifdef ZEND_WIN32
6608 if (EG(timed_out)) {
6609@@ -1634,6 +1660,36 @@
6610 if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
6611 zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
6612 }
6613+#if HARDENING_PATCH
6614+ if (active_function_table == EG(function_table)) {
6615+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6616+ if (HG(eval_whitelist) != NULL) {
6617+ if (!zend_hash_exists(HG(eval_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
6618+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name->value.str.val);
6619+ zend_bailout();
6620+ }
6621+ } else if (HG(eval_blacklist) != NULL) {
6622+ if (zend_hash_exists(HG(eval_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
6623+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name->value.str.val);
6624+ zend_bailout();
6625+ }
6626+ }
6627+ }
6628+
6629+ if (HG(func_whitelist) != NULL) {
6630+ if (!zend_hash_exists(HG(func_whitelist), function_name->value.str.val, function_name->value.str.len+1)) {
6631+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name->value.str.val);
6632+ zend_bailout();
6633+ }
6634+ } else if (HG(func_blacklist) != NULL) {
6635+ if (zend_hash_exists(HG(func_blacklist), function_name->value.str.val, function_name->value.str.len+1)) {
6636+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name->value.str.val);
6637+ zend_bailout();
6638+ }
6639+ }
6640+ }
6641+#endif
6642+
6643 zval_dtor(&tmp);
6644 EX(fbc) = function;
6645 overloaded_function_call_cont:
6646@@ -1649,6 +1705,35 @@
6647 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
6648 zend_error(E_ERROR, "Unknown function: %s()", fname->value.str.val);
6649 }
6650+#if HARDENING_PATCH
6651+ if (EX(function_state).function->type==ZEND_INTERNAL_FUNCTION) {
6652+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6653+ if (HG(eval_whitelist) != NULL) {
6654+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
6655+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
6656+ zend_bailout();
6657+ }
6658+ } else if (HG(eval_blacklist) != NULL) {
6659+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
6660+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
6661+ zend_bailout();
6662+ }
6663+ }
6664+ }
6665+
6666+ if (HG(func_whitelist) != NULL) {
6667+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
6668+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
6669+ zend_bailout();
6670+ }
6671+ } else if (HG(func_blacklist) != NULL) {
6672+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
6673+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
6674+ zend_bailout();
6675+ }
6676+ }
6677+ }
6678+#endif
6679 FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
6680 zend_ptr_stack_n_push(&EG(arg_types_stack), 2, EX(object).ptr, EX(ce));
6681 EX(object).ptr = NULL;
6682@@ -1821,6 +1906,7 @@
6683 efree(EX(Ts));
6684 }
6685 EG(in_execution) = EX(original_in_execution);
6686+ EG(in_code_type) = EX(original_in_code_type);
6687 EG(current_execute_data) = EX(prev_execute_data);
6688 return;
6689 }
6690@@ -2210,7 +2296,12 @@
6691 int dummy = 1;
6692 zend_file_handle file_handle = {0};
6693
6694+#if HARDENING_PATCH_INC_PROTECT
6695+ if (zend_is_valid_include(inc_filename)
6696+ && zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
6697+#else
6698 if (zend_open(inc_filename->value.str.val, &file_handle) == SUCCESS
6699+#endif
6700 && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) {
6701
6702 file_handle.filename = inc_filename->value.str.val;
6703@@ -2239,6 +2330,11 @@
6704 break;
6705 case ZEND_INCLUDE:
6706 case ZEND_REQUIRE:
6707+#if HARDENING_PATCH_INC_PROTECT
6708+ if (!zend_is_valid_include(inc_filename)) {
6709+ break;
6710+ }
6711+#endif
6712 new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
6713 break;
6714 case ZEND_EVAL: {
6715diff -Nura php-4.4.1/Zend/zend_execute_globals.h hardening-patch-4.4.1-0.4.5/Zend/zend_execute_globals.h
6716--- php-4.4.1/Zend/zend_execute_globals.h 2005-06-06 11:30:09.000000000 +0200
6717+++ hardening-patch-4.4.1-0.4.5/Zend/zend_execute_globals.h 2005-10-30 17:12:13.000000000 +0100
6718@@ -60,6 +60,8 @@
6719 object_info object;
6720 temp_variable *Ts;
6721 zend_bool original_in_execution;
6722+ zend_uint original_in_code_type;
6723+ zend_uint execute_depth;
6724 zend_op_array *op_array;
6725 struct _zend_execute_data *prev_execute_data;
6726 } zend_execute_data;
6727diff -Nura php-4.4.1/Zend/zend_extensions.c hardening-patch-4.4.1-0.4.5/Zend/zend_extensions.c
6728--- php-4.4.1/Zend/zend_extensions.c 2003-03-19 19:00:57.000000000 +0100
6729+++ hardening-patch-4.4.1-0.4.5/Zend/zend_extensions.c 2005-10-30 17:12:13.000000000 +0100
6730@@ -54,23 +54,44 @@
6731 return FAILURE;
6732 }
6733
6734+ /* check if module is compiled against Hardening-Patch */
6735+ if (extension_version_info->zend_extension_api_no < 1000000000) {
6736+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
6737+ "The Hardening-Patch version %d is installed.\n\n",
6738+ new_extension->name,
6739+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
6740+ DL_UNLOAD(handle);
6741+ return FAILURE;
6742+ }
6743+
6744+
6745+ /* check if module is compiled against correct Hardening-Patch version */
6746+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
6747+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
6748+ "The Hardening-Patch version %d is installed.\n\n",
6749+ new_extension->name,
6750+ extension_version_info->zend_extension_api_no,
6751+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
6752+ DL_UNLOAD(handle);
6753+ return FAILURE;
6754+ }
6755
6756 /* allow extension to proclaim compatibility with any Zend version */
6757- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
6758- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
6759+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
6760+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
6761 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
6762 "The Zend Engine API version %d which is installed, is outdated.\n\n",
6763 new_extension->name,
6764- extension_version_info->zend_extension_api_no,
6765+ extension_version_info->real_zend_extension_api_no,
6766 ZEND_EXTENSION_API_NO);
6767 DL_UNLOAD(handle);
6768 return FAILURE;
6769- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
6770+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
6771 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
6772 "The Zend Engine API version %d which is installed, is newer.\n"
6773 "Contact %s at %s for a later version of %s.\n\n",
6774 new_extension->name,
6775- extension_version_info->zend_extension_api_no,
6776+ extension_version_info->real_zend_extension_api_no,
6777 ZEND_EXTENSION_API_NO,
6778 new_extension->author,
6779 new_extension->URL,
6780diff -Nura php-4.4.1/Zend/zend_extensions.h hardening-patch-4.4.1-0.4.5/Zend/zend_extensions.h
6781--- php-4.4.1/Zend/zend_extensions.h 2005-06-06 11:44:59.000000000 +0200
6782+++ hardening-patch-4.4.1-0.4.5/Zend/zend_extensions.h 2005-10-30 17:12:13.000000000 +0100
6783@@ -23,6 +23,9 @@
6784
6785 #include "zend_compile.h"
6786
6787+/* Create own API version number for Hardening-Patch */
6788+
6789+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1001050805
6790 #define ZEND_EXTENSION_API_NO 20050606
6791
6792 typedef struct _zend_extension_version_info {
6793@@ -30,6 +33,7 @@
6794 char *required_zend_version;
6795 unsigned char thread_safe;
6796 unsigned char debug;
6797+ int real_zend_extension_api_no;
6798 } zend_extension_version_info;
6799
6800
6801@@ -96,7 +100,7 @@
6802
6803
6804 #define ZEND_EXTENSION() \
6805- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
6806+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
6807
6808 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6809 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6810diff -Nura php-4.4.1/Zend/zend_globals.h hardening-patch-4.4.1-0.4.5/Zend/zend_globals.h
6811--- php-4.4.1/Zend/zend_globals.h 2004-11-04 00:15:05.000000000 +0100
6812+++ hardening-patch-4.4.1-0.4.5/Zend/zend_globals.h 2005-10-30 17:12:13.000000000 +0100
6813@@ -163,6 +163,16 @@
6814
6815 int error_reporting;
6816 int orig_error_reporting;
6817+#if HARDENING_PATCH
6818+ int hphp_log_syslog;
6819+ int hphp_log_syslog_facility;
6820+ int hphp_log_syslog_priority;
6821+ int hphp_log_sapi;
6822+ int hphp_log_script;
6823+ char *hphp_log_scriptname;
6824+ zend_bool hphp_log_use_x_forwarded_for;
6825+ long hphp_executor_max_depth;
6826+#endif
6827 int exit_status;
6828
6829 zend_op_array *active_op_array;
6830@@ -176,6 +186,7 @@
6831 int ticks_count;
6832
6833 zend_bool in_execution;
6834+ zend_uint in_code_type;
6835 zend_bool bailout_set;
6836 zend_bool full_tables_cleanup;
6837
6838diff -Nura php-4.4.1/Zend/zend.h hardening-patch-4.4.1-0.4.5/Zend/zend.h
6839--- php-4.4.1/Zend/zend.h 2005-07-23 13:58:40.000000000 +0200
6840+++ hardening-patch-4.4.1-0.4.5/Zend/zend.h 2005-10-30 17:12:13.000000000 +0100
6841@@ -274,9 +274,10 @@
6842 struct _zval_struct {
6843 /* Variable information */
6844 zvalue_value value; /* value */
6845+ zend_uint refcount;
6846+ zend_ushort flags;
6847 zend_uchar type; /* active type */
6848 zend_uchar is_ref;
6849- zend_ushort refcount;
6850 };
6851
6852
6853@@ -337,6 +338,12 @@
6854 void (*ticks_function)(int ticks);
6855 void (*on_timeout)(int seconds TSRMLS_DC);
6856 zend_bool (*open_function)(const char *filename, struct _zend_file_handle *);
6857+#if HARDENING_PATCH
6858+ void (*security_log_function)(int loglevel, char *fmt, ...);
6859+#endif
6860+#if HARDENING_PATCH_INC_PROTECT
6861+ int (*is_valid_include)(zval *z);
6862+#endif
6863 } zend_utility_functions;
6864
6865
6866@@ -468,7 +475,16 @@
6867 extern ZEND_API void (*zend_ticks_function)(int ticks);
6868 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);
6869 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
6870+#if HARDENING_PATCH
6871+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6872+#endif
6873+#if HARDENING_PATCH_INC_PROTECT
6874+extern ZEND_API int (*zend_is_valid_include)(zval *z);
6875+#endif
6876
6877+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6878+ZEND_API unsigned int zend_canary(void);
6879+#endif
6880
6881 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 2, 3);
6882
6883@@ -575,6 +591,11 @@
6884
6885 #define ZEND_MAX_RESERVED_RESOURCES 4
6886
6887+#if HARDENING_PATCH
6888+#include "hardened_globals.h"
6889+#include "php_syslog.h"
6890+#endif
6891+
6892 #endif /* ZEND_H */
6893
6894 /*
6895diff -Nura php-4.4.1/Zend/zend_hash.c hardening-patch-4.4.1-0.4.5/Zend/zend_hash.c
6896--- php-4.4.1/Zend/zend_hash.c 2005-04-28 09:34:32.000000000 +0200
6897+++ hardening-patch-4.4.1-0.4.5/Zend/zend_hash.c 2005-10-30 17:12:13.000000000 +0100
6898@@ -26,6 +26,17 @@
6899 # include <stdlib.h>
6900 #endif
6901
6902+#if HARDENING_PATCH_HASH_PROTECT
6903+ unsigned int zend_hash_canary = 0x1234567;
6904+ zend_bool zend_hash_canary_inited = 0;
6905+#endif
6906+
6907+#define CHECK_HASH_CANARY(hash) \
6908+ if (zend_hash_canary != (hash)->canary) { \
6909+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
6910+ exit(1); \
6911+ }
6912+
6913 #define HANDLE_NUMERIC(key, length, func) { \
6914 register char *tmp=key; \
6915 \
6916@@ -175,6 +186,9 @@
6917 {
6918 uint i = 3;
6919 Bucket **tmp;
6920+#if HARDENING_PATCH_HASH_PROTECT
6921+ TSRMLS_FETCH();
6922+#endif
6923
6924 SET_INCONSISTENT(HT_OK);
6925
6926@@ -184,6 +198,13 @@
6927
6928 ht->nTableSize = 1 << i;
6929 ht->nTableMask = ht->nTableSize - 1;
6930+#if HARDENING_PATCH_HASH_PROTECT
6931+ if (zend_hash_canary_inited==0) {
6932+ zend_hash_canary = zend_canary();
6933+ zend_hash_canary_inited = 1;
6934+ }
6935+ ht->canary = zend_hash_canary;
6936+#endif
6937 ht->pDestructor = pDestructor;
6938 ht->pListHead = NULL;
6939 ht->pListTail = NULL;
6940@@ -259,6 +280,9 @@
6941 }
6942 #endif
6943 if (ht->pDestructor) {
6944+#if HARDENING_PATCH_HASH_PROTECT
6945+ CHECK_HASH_CANARY(ht);
6946+#endif
6947 ht->pDestructor(p->pData);
6948 }
6949 UPDATE_DATA(ht, p, pData, nDataSize);
6950@@ -327,6 +351,9 @@
6951 }
6952 #endif
6953 if (ht->pDestructor) {
6954+#if HARDENING_PATCH_HASH_PROTECT
6955+ CHECK_HASH_CANARY(ht);
6956+#endif
6957 ht->pDestructor(p->pData);
6958 }
6959 UPDATE_DATA(ht, p, pData, nDataSize);
6960@@ -402,6 +429,9 @@
6961 }
6962 #endif
6963 if (ht->pDestructor) {
6964+#if HARDENING_PATCH_HASH_PROTECT
6965+ CHECK_HASH_CANARY(ht);
6966+#endif
6967 ht->pDestructor(p->pData);
6968 }
6969 UPDATE_DATA(ht, p, pData, nDataSize);
6970@@ -450,7 +480,7 @@
6971 IS_CONSISTENT(ht);
6972
6973 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
6974- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6975+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6976 if (t) {
6977 HANDLE_BLOCK_INTERRUPTIONS();
6978 ht->arBuckets = t;
6979@@ -460,6 +490,7 @@
6980 HANDLE_UNBLOCK_INTERRUPTIONS();
6981 return SUCCESS;
6982 }
6983+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
6984 return FAILURE;
6985 }
6986 return SUCCESS;
6987@@ -524,6 +555,9 @@
6988 ht->pInternalPointer = p->pListNext;
6989 }
6990 if (ht->pDestructor) {
6991+#if HARDENING_PATCH_HASH_PROTECT
6992+ CHECK_HASH_CANARY(ht);
6993+#endif
6994 ht->pDestructor(p->pData);
6995 }
6996 if (!p->pDataPtr) {
6997@@ -553,6 +587,9 @@
6998 q = p;
6999 p = p->pListNext;
7000 if (ht->pDestructor) {
7001+#if HARDENING_PATCH_HASH_PROTECT
7002+ CHECK_HASH_CANARY(ht);
7003+#endif
7004 ht->pDestructor(q->pData);
7005 }
7006 if (!q->pDataPtr && q->pData) {
7007@@ -579,6 +616,9 @@
7008 q = p;
7009 p = p->pListNext;
7010 if (ht->pDestructor) {
7011+#if HARDENING_PATCH_HASH_PROTECT
7012+ CHECK_HASH_CANARY(ht);
7013+#endif
7014 ht->pDestructor(q->pData);
7015 }
7016 if (!q->pDataPtr && q->pData) {
7017@@ -608,6 +648,9 @@
7018 HANDLE_BLOCK_INTERRUPTIONS();
7019
7020 if (ht->pDestructor) {
7021+#if HARDENING_PATCH_HASH_PROTECT
7022+ CHECK_HASH_CANARY(ht);
7023+#endif
7024 ht->pDestructor(p->pData);
7025 }
7026 if (!p->pDataPtr) {
7027diff -Nura php-4.4.1/Zend/zend_hash.h hardening-patch-4.4.1-0.4.5/Zend/zend_hash.h
7028--- php-4.4.1/Zend/zend_hash.h 2002-12-31 17:23:03.000000000 +0100
7029+++ hardening-patch-4.4.1-0.4.5/Zend/zend_hash.h 2005-10-30 17:12:13.000000000 +0100
7030@@ -54,6 +54,9 @@
7031 } Bucket;
7032
7033 typedef struct _hashtable {
7034+#if HARDENING_PATCH_HASH_PROTECT
7035+ unsigned int canary;
7036+#endif
7037 uint nTableSize;
7038 uint nTableMask;
7039 uint nNumOfElements;
7040diff -Nura php-4.4.1/Zend/zend_ini.h hardening-patch-4.4.1-0.4.5/Zend/zend_ini.h
7041--- php-4.4.1/Zend/zend_ini.h 2005-01-09 18:00:16.000000000 +0100
7042+++ hardening-patch-4.4.1-0.4.5/Zend/zend_ini.h 2005-10-30 17:12:13.000000000 +0100
7043@@ -174,6 +174,7 @@
7044 /* Standard message handlers */
7045 BEGIN_EXTERN_C()
7046 ZEND_API ZEND_INI_MH(OnUpdateBool);
7047+#define OnUpdateLong OnUpdateInt
7048 ZEND_API ZEND_INI_MH(OnUpdateInt);
7049 ZEND_API ZEND_INI_MH(OnUpdateReal);
7050 ZEND_API ZEND_INI_MH(OnUpdateString);
7051diff -Nura php-4.4.1/Zend/zend_language_scanner.c hardening-patch-4.4.1-0.4.5/Zend/zend_language_scanner.c
7052--- php-4.4.1/Zend/zend_language_scanner.c 2005-10-30 12:06:40.000000000 +0100
7053+++ hardening-patch-4.4.1-0.4.5/Zend/zend_language_scanner.c 2005-10-30 17:12:13.000000000 +0100
7054@@ -3121,6 +3121,13 @@
7055 compilation_successful=0;
7056 } else {
7057 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7058+#if HARDENING_PATCH
7059+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7060+ op_array->created_by_eval = 1;
7061+ } else {
7062+ op_array->created_by_eval = 0;
7063+ }
7064+#endif
7065 CG(in_compilation) = 1;
7066 CG(active_op_array) = op_array;
7067 compiler_result = zendparse(TSRMLS_C);
7068diff -Nura php-4.4.1/Zend/zend_language_scanner.l hardening-patch-4.4.1-0.4.5/Zend/zend_language_scanner.l
7069--- php-4.4.1/Zend/zend_language_scanner.l 2005-03-09 16:07:19.000000000 +0100
7070+++ hardening-patch-4.4.1-0.4.5/Zend/zend_language_scanner.l 2005-10-30 17:12:13.000000000 +0100
7071@@ -393,6 +393,13 @@
7072 compilation_successful=0;
7073 } else {
7074 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
7075+#if HARDENING_PATCH
7076+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
7077+ op_array->created_by_eval = 1;
7078+ } else {
7079+ op_array->created_by_eval = 0;
7080+ }
7081+#endif
7082 CG(in_compilation) = 1;
7083 CG(active_op_array) = op_array;
7084 compiler_result = zendparse(TSRMLS_C);
7085diff -Nura php-4.4.1/Zend/zend_llist.c hardening-patch-4.4.1-0.4.5/Zend/zend_llist.c
7086--- php-4.4.1/Zend/zend_llist.c 2002-12-31 17:23:04.000000000 +0100
7087+++ hardening-patch-4.4.1-0.4.5/Zend/zend_llist.c 2005-10-30 17:12:13.000000000 +0100
7088@@ -21,9 +21,34 @@
7089 #include "zend.h"
7090 #include "zend_llist.h"
7091 #include "zend_qsort.h"
7092+#include "zend_globals.h"
7093+
7094+#define CHECK_LIST_CANARY(list) \
7095+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
7096+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
7097+ exit(1); \
7098+ }
7099+
7100+#define CHECK_LISTELEMENT_CANARY(elem) \
7101+ if (HG(canary_3) != (elem)->canary) { \
7102+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
7103+ exit(1); \
7104+ }
7105+
7106
7107 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
7108 {
7109+#if HARDENING_PATCH_LL_PROTECT
7110+ TSRMLS_FETCH();
7111+
7112+ if (!HG(ll_canary_inited)) {
7113+ HG(canary_3) = zend_canary();
7114+ HG(canary_4) = zend_canary();
7115+ HG(ll_canary_inited) = 1;
7116+ }
7117+ l->canary_h = HG(canary_3);
7118+ l->canary_t = HG(canary_4);
7119+#endif
7120 l->head = NULL;
7121 l->tail = NULL;
7122 l->count = 0;
7123@@ -37,6 +62,11 @@
7124 {
7125 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7126
7127+#if HARDENING_PATCH_LL_PROTECT
7128+ TSRMLS_FETCH();
7129+ CHECK_LIST_CANARY(l)
7130+ tmp->canary = HG(canary_3);
7131+#endif
7132 tmp->prev = l->tail;
7133 tmp->next = NULL;
7134 if (l->tail) {
7135@@ -55,6 +85,11 @@
7136 {
7137 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
7138
7139+#if HARDENING_PATCH_LL_PROTECT
7140+ TSRMLS_FETCH();
7141+ CHECK_LIST_CANARY(l)
7142+ tmp->canary = HG(canary_3);
7143+#endif
7144 tmp->next = l->head;
7145 tmp->prev = NULL;
7146 if (l->head) {
7147@@ -91,10 +126,20 @@
7148 zend_llist_element *current=l->head;
7149 zend_llist_element *next;
7150
7151+#if HARDENING_PATCH_LL_PROTECT
7152+ TSRMLS_FETCH();
7153+ CHECK_LIST_CANARY(l)
7154+#endif
7155 while (current) {
7156+#if HARDENING_PATCH_LL_PROTECT
7157+ CHECK_LISTELEMENT_CANARY(current)
7158+#endif
7159 next = current->next;
7160 if (compare(current->data, element)) {
7161 DEL_LLIST_ELEMENT(current, l);
7162+#if HARDENING_PATCH_LL_PROTECT
7163+ current->canary = 0;
7164+#endif
7165 break;
7166 }
7167 current = next;
7168@@ -106,7 +151,14 @@
7169 {
7170 zend_llist_element *current=l->head, *next;
7171
7172+#if HARDENING_PATCH_LL_PROTECT
7173+ TSRMLS_FETCH();
7174+ CHECK_LIST_CANARY(l)
7175+#endif
7176 while (current) {
7177+#if HARDENING_PATCH_LL_PROTECT
7178+ CHECK_LISTELEMENT_CANARY(current)
7179+#endif
7180 next = current->next;
7181 if (l->dtor) {
7182 l->dtor(current->data);
7183@@ -131,7 +183,14 @@
7184 zend_llist_element *old_tail;
7185 void *data;
7186
7187+#if HARDENING_PATCH_LL_PROTECT
7188+ TSRMLS_FETCH();
7189+ CHECK_LIST_CANARY(l)
7190+#endif
7191 if ((old_tail = l->tail)) {
7192+#if HARDENING_PATCH_LL_PROTECT
7193+ CHECK_LISTELEMENT_CANARY(old_tail)
7194+#endif
7195 if (l->tail->prev) {
7196 l->tail->prev->next = NULL;
7197 }
7198@@ -157,9 +216,16 @@
7199 {
7200 zend_llist_element *ptr;
7201
7202+#if HARDENING_PATCH_LL_PROTECT
7203+ TSRMLS_FETCH();
7204+ CHECK_LIST_CANARY(src)
7205+#endif
7206 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7207 ptr = src->head;
7208 while (ptr) {
7209+#if HARDENING_PATCH_LL_PROTECT
7210+ CHECK_LISTELEMENT_CANARY(ptr)
7211+#endif
7212 zend_llist_add_element(dst, ptr->data);
7213 ptr = ptr->next;
7214 }
7215@@ -170,11 +236,21 @@
7216 {
7217 zend_llist_element *element, *next;
7218
7219+#if HARDENING_PATCH_LL_PROTECT
7220+ TSRMLS_FETCH();
7221+ CHECK_LIST_CANARY(l)
7222+#endif
7223 element=l->head;
7224 while (element) {
7225+#if HARDENING_PATCH_LL_PROTECT
7226+ CHECK_LISTELEMENT_CANARY(element)
7227+#endif
7228 next = element->next;
7229 if (func(element->data)) {
7230 DEL_LLIST_ELEMENT(element, l);
7231+#if HARDENING_PATCH_LL_PROTECT
7232+ element->canary = 0;
7233+#endif
7234 }
7235 element = next;
7236 }
7237@@ -185,7 +261,13 @@
7238 {
7239 zend_llist_element *element;
7240
7241+#if HARDENING_PATCH_LL_PROTECT
7242+ CHECK_LIST_CANARY(l)
7243+#endif
7244 for (element=l->head; element; element=element->next) {
7245+#if HARDENING_PATCH_LL_PROTECT
7246+ CHECK_LISTELEMENT_CANARY(element)
7247+#endif
7248 func(element->data TSRMLS_CC);
7249 }
7250 }
7251@@ -197,6 +279,9 @@
7252 zend_llist_element **elements;
7253 zend_llist_element *element, **ptr;
7254
7255+#if HARDENING_PATCH_LL_PROTECT
7256+ CHECK_LIST_CANARY(l)
7257+#endif
7258 if (l->count <= 0) {
7259 return;
7260 }
7261@@ -206,6 +291,9 @@
7262 ptr = &elements[0];
7263
7264 for (element=l->head; element; element=element->next) {
7265+#if HARDENING_PATCH_LL_PROTECT
7266+ CHECK_LISTELEMENT_CANARY(element)
7267+#endif
7268 *ptr++ = element;
7269 }
7270
7271@@ -228,7 +316,13 @@
7272 {
7273 zend_llist_element *element;
7274
7275+#if HARDENING_PATCH_LL_PROTECT
7276+ CHECK_LIST_CANARY(l)
7277+#endif
7278 for (element=l->head; element; element=element->next) {
7279+#if HARDENING_PATCH_LL_PROTECT
7280+ CHECK_LISTELEMENT_CANARY(element)
7281+#endif
7282 func(element->data, arg TSRMLS_CC);
7283 }
7284 }
7285@@ -239,8 +333,14 @@
7286 zend_llist_element *element;
7287 va_list args;
7288
7289+#if HARDENING_PATCH_LL_PROTECT
7290+ CHECK_LIST_CANARY(l)
7291+#endif
7292 va_start(args, num_args);
7293 for (element=l->head; element; element=element->next) {
7294+#if HARDENING_PATCH_LL_PROTECT
7295+ CHECK_LISTELEMENT_CANARY(element)
7296+#endif
7297 func(element->data, num_args, args TSRMLS_CC);
7298 }
7299 va_end(args);
7300@@ -249,6 +349,10 @@
7301
7302 ZEND_API int zend_llist_count(zend_llist *l)
7303 {
7304+#if HARDENING_PATCH_LL_PROTECT
7305+ TSRMLS_FETCH();
7306+ CHECK_LIST_CANARY(l)
7307+#endif
7308 return l->count;
7309 }
7310
7311@@ -256,8 +360,15 @@
7312 {
7313 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7314
7315+#if HARDENING_PATCH_LL_PROTECT
7316+ TSRMLS_FETCH();
7317+ CHECK_LIST_CANARY(l)
7318+#endif
7319 *current = l->head;
7320 if (*current) {
7321+#if HARDENING_PATCH_LL_PROTECT
7322+ CHECK_LISTELEMENT_CANARY(*current)
7323+#endif
7324 return (*current)->data;
7325 } else {
7326 return NULL;
7327@@ -269,8 +380,15 @@
7328 {
7329 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7330
7331+#if HARDENING_PATCH_LL_PROTECT
7332+ TSRMLS_FETCH();
7333+ CHECK_LIST_CANARY(l)
7334+#endif
7335 *current = l->tail;
7336 if (*current) {
7337+#if HARDENING_PATCH_LL_PROTECT
7338+ CHECK_LISTELEMENT_CANARY(*current)
7339+#endif
7340 return (*current)->data;
7341 } else {
7342 return NULL;
7343@@ -282,9 +400,19 @@
7344 {
7345 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7346
7347+#if HARDENING_PATCH_LL_PROTECT
7348+ TSRMLS_FETCH();
7349+ CHECK_LIST_CANARY(l)
7350+#endif
7351 if (*current) {
7352+#if HARDENING_PATCH_LL_PROTECT
7353+ CHECK_LISTELEMENT_CANARY(*current)
7354+#endif
7355 *current = (*current)->next;
7356 if (*current) {
7357+#if HARDENING_PATCH_LL_PROTECT
7358+ CHECK_LISTELEMENT_CANARY(*current)
7359+#endif
7360 return (*current)->data;
7361 }
7362 }
7363@@ -296,9 +424,19 @@
7364 {
7365 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7366
7367+#if HARDENING_PATCH_LL_PROTECT
7368+ TSRMLS_FETCH();
7369+ CHECK_LIST_CANARY(l)
7370+#endif
7371 if (*current) {
7372+#if HARDENING_PATCH_LL_PROTECT
7373+ CHECK_LISTELEMENT_CANARY(*current)
7374+#endif
7375 *current = (*current)->prev;
7376 if (*current) {
7377+#if HARDENING_PATCH_LL_PROTECT
7378+ CHECK_LISTELEMENT_CANARY(*current)
7379+#endif
7380 return (*current)->data;
7381 }
7382 }
7383diff -Nura php-4.4.1/Zend/zend_llist.h hardening-patch-4.4.1-0.4.5/Zend/zend_llist.h
7384--- php-4.4.1/Zend/zend_llist.h 2002-12-31 17:23:04.000000000 +0100
7385+++ hardening-patch-4.4.1-0.4.5/Zend/zend_llist.h 2005-10-30 17:12:13.000000000 +0100
7386@@ -24,6 +24,9 @@
7387 #include <stdlib.h>
7388
7389 typedef struct _zend_llist_element {
7390+#if HARDENING_PATCH_LL_PROTECT
7391+ unsigned int canary;
7392+#endif
7393 struct _zend_llist_element *next;
7394 struct _zend_llist_element *prev;
7395 char data[1]; /* Needs to always be last in the struct */
7396@@ -36,6 +39,9 @@
7397 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7398
7399 typedef struct _zend_llist {
7400+#if HARDENING_PATCH_LL_PROTECT
7401+ unsigned int canary_h; /* head */
7402+#endif
7403 zend_llist_element *head;
7404 zend_llist_element *tail;
7405 size_t size;
7406@@ -43,6 +49,9 @@
7407 llist_dtor_func_t dtor;
7408 unsigned char persistent;
7409 zend_llist_element *traverse_ptr;
7410+#if HARDENING_PATCH_LL_PROTECT
7411+ unsigned int canary_t; /* tail */
7412+#endif
7413 } zend_llist;
7414
7415 typedef zend_llist_element* zend_llist_position;
7416diff -Nura php-4.4.1/Zend/zend_modules.h hardening-patch-4.4.1-0.4.5/Zend/zend_modules.h
7417--- php-4.4.1/Zend/zend_modules.h 2002-12-31 17:23:04.000000000 +0100
7418+++ hardening-patch-4.4.1-0.4.5/Zend/zend_modules.h 2005-10-30 17:12:13.000000000 +0100
7419@@ -34,6 +34,7 @@
7420 ZEND_API extern unsigned char second_arg_force_ref[];
7421 ZEND_API extern unsigned char third_arg_force_ref[];
7422
7423+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1001050912
7424 #define ZEND_MODULE_API_NO 20020429
7425 #ifdef ZTS
7426 #define USING_ZTS 1
7427@@ -41,9 +42,9 @@
7428 #define USING_ZTS 0
7429 #endif
7430
7431-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7432+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS
7433
7434-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
7435+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
7436
7437 #define STANDARD_MODULE_PROPERTIES \
7438 NULL, NULL, STANDARD_MODULE_PROPERTIES_EX
7439@@ -75,6 +76,7 @@
7440 unsigned char type;
7441 void *handle;
7442 int module_number;
7443+ unsigned int real_zend_api;
7444 };
7445
7446
7447diff -Nura php-4.4.1/Zend/zend_opcode.c hardening-patch-4.4.1-0.4.5/Zend/zend_opcode.c
7448--- php-4.4.1/Zend/zend_opcode.c 2002-12-31 17:23:04.000000000 +0100
7449+++ hardening-patch-4.4.1-0.4.5/Zend/zend_opcode.c 2005-10-30 17:12:13.000000000 +0100
7450@@ -88,6 +88,9 @@
7451 op_array->done_pass_two = 0;
7452
7453 op_array->start_op = NULL;
7454+#if HARDENING_PATCH
7455+ op_array->created_by_eval = 0;
7456+#endif
7457
7458 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
7459 }
7460diff -Nura php-4.4.1/Zend/zend_operators.c hardening-patch-4.4.1-0.4.5/Zend/zend_operators.c
7461--- php-4.4.1/Zend/zend_operators.c 2005-03-31 10:18:39.000000000 +0200
7462+++ hardening-patch-4.4.1-0.4.5/Zend/zend_operators.c 2005-10-30 17:12:13.000000000 +0100
7463@@ -1604,6 +1604,20 @@
7464 return (op->value.lval ? 1 : 0);
7465 }
7466
7467+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
7468+{
7469+ register unsigned char *str = (unsigned char*)source;
7470+ register unsigned char *result = (unsigned char*)dest;
7471+ register unsigned char *end = str + length;
7472+
7473+ while (str < end) {
7474+ *result++ = tolower((int)*str++);
7475+ }
7476+ *result = *end;
7477+
7478+ return dest;
7479+}
7480+
7481 ZEND_API void zend_str_tolower(char *str, unsigned int length)
7482 {
7483 register char *p=str, *end=p+length;
7484diff -Nura php-4.4.1/Zend/zend_operators.h hardening-patch-4.4.1-0.4.5/Zend/zend_operators.h
7485--- php-4.4.1/Zend/zend_operators.h 2005-03-31 10:18:40.000000000 +0200
7486+++ hardening-patch-4.4.1-0.4.5/Zend/zend_operators.h 2005-10-30 17:12:13.000000000 +0100
7487@@ -174,6 +174,14 @@
7488 #endif
7489
7490 ZEND_API void zend_str_tolower(char *str, unsigned int length);
7491+ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
7492+
7493+static inline char *
7494+zend_str_tolower_dup(const char *source, unsigned int length)
7495+{
7496+ return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
7497+}
7498+
7499 ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
7500 ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
7501 ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
diff --git a/0.4.5/hardening-patch-5.0.5-0.4.5.patch b/0.4.5/hardening-patch-5.0.5-0.4.5.patch
new file mode 100644
index 0000000..a3bc556
--- /dev/null
+++ b/0.4.5/hardening-patch-5.0.5-0.4.5.patch
@@ -0,0 +1,7316 @@
1diff -Nura php-5.0.5/acinclude.m4 hardening-patch-5.0.5-0.4.5/acinclude.m4
2--- php-5.0.5/acinclude.m4 2005-07-26 00:31:07.000000000 +0200
3+++ hardening-patch-5.0.5-0.4.5/acinclude.m4 2005-11-01 14:23:05.886273480 +0100
4@@ -1182,6 +1182,36 @@
5 fi
6 ])
7
8+dnl
9+dnl Check for broken realpath()
10+dnl
11+dnl realpath("/etc/hosts/../passwd",XXX) should not return
12+dnl "/etc/passwd"
13+dnl
14+AC_DEFUN([PHP_AC_BROKEN_REALPATH],[
15+ AC_CACHE_CHECK(whether realpath is broken, ac_cv_broken_realpath,[
16+ AC_TRY_RUN([
17+main() {
18+ char buf[4096+1];
19+ buf[0] = 0;
20+ realpath("/etc/hosts/../passwd", buf);
21+ exit(strcmp(buf, "/etc/passwd")==0);
22+}
23+ ],[
24+ ac_cv_broken_realpath=no
25+ ],[
26+ ac_cv_broken_realpath=yes
27+ ],[
28+ ac_cv_broken_realpath=no
29+ ])
30+ ])
31+ if test "$ac_cv_broken_realpath" = "yes"; then
32+ AC_DEFINE(PHP_BROKEN_REALPATH, 1, [Whether realpath is broken])
33+ else
34+ AC_DEFINE(PHP_BROKEN_REALPATH, 0, [Whether realpath is broken])
35+ fi
36+])
37+
38 dnl PHP_SHARED_MODULE(module-name, object-var, build-dir, cxx)
39 dnl
40 dnl Basically sets up the link-stage for building module-name
41diff -Nura php-5.0.5/configure hardening-patch-5.0.5-0.4.5/configure
42--- php-5.0.5/configure 2005-09-05 13:16:17.000000000 +0200
43+++ hardening-patch-5.0.5-0.4.5/configure 2005-11-01 14:23:05.925267552 +0100
44@@ -404,6 +404,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@@ -860,6 +870,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."
70@@ -2834,6 +2846,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@@ -17473,6 +17636,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:17478: checking for declared timezone" >&5
290 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then
291@@ -88634,7 +88853,7 @@
292 if test "$ac_cv_crypt_blowfish" = "yes"; then
293 ac_result=1
294 else
295- ac_result=0
296+ ac_result=1
297 fi
298 cat >> confdefs.h <<EOF
299 #define PHP_BLOWFISH_CRYPT $ac_result
300@@ -91230,7 +91449,7 @@
301 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
302 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
303 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
304- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c; do
305+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
306
307 IFS=.
308 set $ac_src
309@@ -91288,7 +91507,7 @@
310 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
311 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
312 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
313- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c; do
314+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
315
316 IFS=.
317 set $ac_src
318@@ -91480,7 +91699,7 @@
319 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
320 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
321 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
322- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c; do
323+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
324
325 IFS=.
326 set $ac_src
327@@ -91535,7 +91754,7 @@
328 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
329 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
330 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
331- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c; do
332+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c ; do
333
334 IFS=.
335 set $ac_src
336@@ -95503,6 +95722,265 @@
337 fi
338
339
340+echo $ac_n "checking whether to enable Hardening-Patch's variable filter""... $ac_c" 1>&6
341+echo "configure:82041: checking whether to enable Hardening-Patch's variable filter" >&5
342+# Check whether --enable-varfilter or --disable-varfilter was given.
343+if test "${enable_varfilter+set}" = set; then
344+ enableval="$enable_varfilter"
345+ PHP_VARFILTER=$enableval
346+else
347+
348+ PHP_VARFILTER=yes
349+
350+ if test "$PHP_ENABLE_ALL" && test "yes" = "yes"; then
351+ PHP_VARFILTER=$PHP_ENABLE_ALL
352+ fi
353+
354+fi
355+
356+
357+
358+ext_output="yes, shared"
359+ext_shared=yes
360+case $PHP_VARFILTER in
361+shared,*)
362+ PHP_VARFILTER=`echo "$PHP_VARFILTER"|sed 's/^shared,//'`
363+ ;;
364+shared)
365+ PHP_VARFILTER=yes
366+ ;;
367+no)
368+ ext_output=no
369+ ext_shared=no
370+ ;;
371+*)
372+ ext_output=yes
373+ ext_shared=no
374+ ;;
375+esac
376+
377+
378+
379+echo "$ac_t""$ext_output" 1>&6
380+
381+
382+
383+
384+if test "$PHP_VARFILTER" != "no"; then
385+ cat >> confdefs.h <<\EOF
386+#define HAVE_VARFILTER 1
387+EOF
388+
389+
390+ ext_builddir=ext/varfilter
391+ ext_srcdir=$abs_srcdir/ext/varfilter
392+
393+ ac_extra=
394+
395+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" != "cli"; then
396+
397+
398+
399+ case ext/varfilter in
400+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
401+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
402+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
403+ esac
404+
405+
406+
407+ b_c_pre=$php_c_pre
408+ b_cxx_pre=$php_cxx_pre
409+ b_c_meta=$php_c_meta
410+ b_cxx_meta=$php_cxx_meta
411+ b_c_post=$php_c_post
412+ b_cxx_post=$php_cxx_post
413+ b_lo=$php_lo
414+
415+
416+ old_IFS=$IFS
417+ for ac_src in varfilter.c; do
418+
419+ IFS=.
420+ set $ac_src
421+ ac_obj=$1
422+ IFS=$old_IFS
423+
424+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
425+
426+ case $ac_src in
427+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
428+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
429+ esac
430+
431+ cat >>Makefile.objects<<EOF
432+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
433+ $ac_comp
434+EOF
435+ done
436+
437+
438+ EXT_STATIC="$EXT_STATIC varfilter"
439+ if test "$ext_shared" != "nocli"; then
440+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
441+ fi
442+ else
443+ if test "$ext_shared" = "shared" || test "$ext_shared" = "yes"; then
444+
445+ case ext/varfilter in
446+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
447+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
448+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
449+ esac
450+
451+
452+
453+ b_c_pre=$shared_c_pre
454+ b_cxx_pre=$shared_cxx_pre
455+ b_c_meta=$shared_c_meta
456+ b_cxx_meta=$shared_cxx_meta
457+ b_c_post=$shared_c_post
458+ b_cxx_post=$shared_cxx_post
459+ b_lo=$shared_lo
460+
461+
462+ old_IFS=$IFS
463+ for ac_src in varfilter.c; do
464+
465+ IFS=.
466+ set $ac_src
467+ ac_obj=$1
468+ IFS=$old_IFS
469+
470+ shared_objects_varfilter="$shared_objects_varfilter $ac_bdir$ac_obj.lo"
471+
472+ case $ac_src in
473+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
474+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
475+ esac
476+
477+ cat >>Makefile.objects<<EOF
478+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
479+ $ac_comp
480+EOF
481+ done
482+
483+
484+ install_modules="install-modules"
485+ PHP_MODULES="$PHP_MODULES \$(phplibdir)/varfilter.la"
486+
487+ PHP_VAR_SUBST="$PHP_VAR_SUBST shared_objects_varfilter"
488+
489+ cat >>Makefile.objects<<EOF
490+\$(phplibdir)/varfilter.la: $ext_builddir/varfilter.la
491+ \$(LIBTOOL) --mode=install cp $ext_builddir/varfilter.la \$(phplibdir)
492+
493+$ext_builddir/varfilter.la: \$(shared_objects_varfilter) \$(VARFILTER_SHARED_DEPENDENCIES)
494+ \$(LIBTOOL) --mode=link \$(CC) \$(COMMON_FLAGS) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(LDFLAGS) -o \$@ -export-dynamic -avoid-version -prefer-pic -module -rpath \$(phplibdir) \$(EXTRA_LDFLAGS) \$(shared_objects_varfilter) \$(VARFILTER_SHARED_LIBADD)
495+
496+EOF
497+
498+ cat >> confdefs.h <<EOF
499+#define COMPILE_DL_VARFILTER 1
500+EOF
501+
502+ fi
503+ fi
504+
505+ if test "$ext_shared" != "shared" && test "$ext_shared" != "yes" && test "" = "cli"; then
506+ if test "$PHP_SAPI" = "cgi"; then
507+
508+
509+ case ext/varfilter in
510+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
511+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
512+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
513+ esac
514+
515+
516+
517+ b_c_pre=$php_c_pre
518+ b_cxx_pre=$php_cxx_pre
519+ b_c_meta=$php_c_meta
520+ b_cxx_meta=$php_cxx_meta
521+ b_c_post=$php_c_post
522+ b_cxx_post=$php_cxx_post
523+ b_lo=$php_lo
524+
525+
526+ old_IFS=$IFS
527+ for ac_src in varfilter.c; do
528+
529+ IFS=.
530+ set $ac_src
531+ ac_obj=$1
532+ IFS=$old_IFS
533+
534+ PHP_GLOBAL_OBJS="$PHP_GLOBAL_OBJS $ac_bdir$ac_obj.lo"
535+
536+ case $ac_src in
537+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
538+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
539+ esac
540+
541+ cat >>Makefile.objects<<EOF
542+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
543+ $ac_comp
544+EOF
545+ done
546+
547+
548+ EXT_STATIC="$EXT_STATIC varfilter"
549+ else
550+
551+
552+ case ext/varfilter in
553+ "") ac_srcdir="$abs_srcdir/"; unset ac_bdir; ac_inc="-I. -I$abs_srcdir" ;;
554+ /*) ac_srcdir=`echo "ext/varfilter"|cut -c 2-`"/"; ac_bdir=$ac_srcdir; ac_inc="-I$ac_bdir -I$abs_srcdir/$ac_bdir" ;;
555+ *) ac_srcdir="$abs_srcdir/ext/varfilter/"; ac_bdir="ext/varfilter/"; ac_inc="-I$ac_bdir -I$ac_srcdir" ;;
556+ esac
557+
558+
559+
560+ b_c_pre=$php_c_pre
561+ b_cxx_pre=$php_cxx_pre
562+ b_c_meta=$php_c_meta
563+ b_cxx_meta=$php_cxx_meta
564+ b_c_post=$php_c_post
565+ b_cxx_post=$php_cxx_post
566+ b_lo=$php_lo
567+
568+
569+ old_IFS=$IFS
570+ for ac_src in varfilter.c; do
571+
572+ IFS=.
573+ set $ac_src
574+ ac_obj=$1
575+ IFS=$old_IFS
576+
577+ PHP_CLI_OBJS="$PHP_CLI_OBJS $ac_bdir$ac_obj.lo"
578+
579+ case $ac_src in
580+ *.c) ac_comp="$b_c_pre $ac_extra $ac_inc $b_c_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_c_post" ;;
581+ *.cpp) ac_comp="$b_cxx_pre $ac_extra $ac_inc $b_cxx_meta -c $ac_srcdir$ac_src -o $ac_bdir$ac_obj.$b_lo $b_cxx_post" ;;
582+ esac
583+
584+ cat >>Makefile.objects<<EOF
585+$ac_bdir$ac_obj.lo: $ac_srcdir$ac_src
586+ $ac_comp
587+EOF
588+ done
589+
590+
591+ fi
592+ EXT_CLI_STATIC="$EXT_CLI_STATIC varfilter"
593+ fi
594+
595+ BUILD_DIR="$BUILD_DIR $ext_builddir"
596+
597+
598+fi
599
600
601 echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6
602@@ -106554,7 +107032,7 @@
603 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
604 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
605 network.c php_open_temporary_file.c php_logos.c \
606- output.c ; do
607+ output.c hardening_patch.c ; do
608
609 IFS=.
610 set $ac_src
611@@ -106795,7 +107273,7 @@
612 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
613 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
614 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
615- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c; do
616+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c; do
617
618 IFS=.
619 set $ac_src
620diff -Nura php-5.0.5/configure.in hardening-patch-5.0.5-0.4.5/configure.in
621--- php-5.0.5/configure.in 2005-09-05 12:41:12.000000000 +0200
622+++ hardening-patch-5.0.5-0.4.5/configure.in 2005-11-01 14:23:05.927267248 +0100
623@@ -247,7 +247,7 @@
624 sinclude(Zend/acinclude.m4)
625 sinclude(Zend/Zend.m4)
626 sinclude(TSRM/tsrm.m4)
627-
628+sinclude(main/hardening_patch.m4)
629
630
631 divert(2)
632@@ -631,6 +631,7 @@
633 AC_FUNC_ALLOCA
634 dnl PHP_AC_BROKEN_SPRINTF
635 dnl PHP_AC_BROKEN_SNPRINTF
636+PHP_AC_BROKEN_REALPATH
637 PHP_DECLARED_TIMEZONE
638 PHP_TIME_R_TYPE
639 PHP_READDIR_R_TYPE
640@@ -1284,7 +1285,7 @@
641 php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
642 strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
643 network.c php_open_temporary_file.c php_logos.c \
644- output.c )
645+ output.c hardening_patch.c )
646
647 PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
648 plain_wrapper.c userspace.c transports.c xp_socket.c mmap.c)
649@@ -1311,7 +1312,7 @@
650 zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
651 zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
652 zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
653- zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c)
654+ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_canary.c )
655
656 if test -r "$abs_srcdir/Zend/zend_objects.c"; then
657 PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c \
658diff -Nura php-5.0.5/ext/curl/interface.c hardening-patch-5.0.5-0.4.5/ext/curl/interface.c
659--- php-5.0.5/ext/curl/interface.c 2005-06-02 23:04:43.000000000 +0200
660+++ hardening-patch-5.0.5-0.4.5/ext/curl/interface.c 2005-11-01 15:14:43.059431592 +0100
661@@ -62,7 +62,7 @@
662 #define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s), (zval *) v);
663
664 #define PHP_CURL_CHECK_OPEN_BASEDIR(str, len) \
665- if (PG(open_basedir) && *PG(open_basedir) && \
666+ if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && \
667 strncasecmp(str, "file://", sizeof("file://") - 1) == 0) \
668 { \
669 php_url *tmp_url; \
670@@ -72,7 +72,7 @@
671 RETURN_FALSE; \
672 } \
673 \
674- if (php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
675+ if (tmp_url->query || tmp_url->fragment || php_check_open_basedir(tmp_url->path TSRMLS_CC) || \
676 (PG(safe_mode) && !php_checkuid(tmp_url->path, "rb+", CHECKUID_CHECK_MODE_PARAM)) \
677 ) { \
678 php_url_free(tmp_url); \
679diff -Nura php-5.0.5/ext/exif/exif.c hardening-patch-5.0.5-0.4.5/ext/exif/exif.c
680--- php-5.0.5/ext/exif/exif.c 2005-08-05 16:00:47.000000000 +0200
681+++ hardening-patch-5.0.5-0.4.5/ext/exif/exif.c 2005-11-01 15:06:08.116714784 +0100
682@@ -3032,6 +3032,12 @@
683 }
684 }
685 /*
686+ * Ignore IFD2 if it purportedly exists
687+ */
688+ if (section_index == SECTION_THUMBNAIL) {
689+ return TRUE;
690+ }
691+ /*
692 * Hack to make it process IDF1 I hope
693 * There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
694 */
695diff -Nura php-5.0.5/ext/fbsql/php_fbsql.c hardening-patch-5.0.5-0.4.5/ext/fbsql/php_fbsql.c
696--- php-5.0.5/ext/fbsql/php_fbsql.c 2005-02-09 20:32:45.000000000 +0100
697+++ hardening-patch-5.0.5-0.4.5/ext/fbsql/php_fbsql.c 2005-11-01 14:23:05.929266944 +0100
698@@ -1852,8 +1852,24 @@
699 }
700 else if (fbcmdErrorsFound(md))
701 {
702+#if HARDENING_PATCH
703+ char* query_copy;
704+ int i;
705+#endif
706 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
707 char* emg = fbcemdAllErrorMessages(emd);
708+#if HARDENING_PATCH
709+ query_copy=estrdup(query_copy);
710+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
711+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
712+ efree(query_copy);
713+ if (HG(hphp_sql_bailout_on_error)) {
714+ free(emg);
715+ fbcemdRelease(emd);
716+ result = 0;
717+ zend_bailout();
718+ }
719+#endif
720 if (FB_SQL_G(generateWarnings))
721 {
722 if (emg)
723diff -Nura php-5.0.5/ext/gd/gd.c hardening-patch-5.0.5-0.4.5/ext/gd/gd.c
724--- php-5.0.5/ext/gd/gd.c 2005-05-06 18:49:04.000000000 +0200
725+++ hardening-patch-5.0.5-0.4.5/ext/gd/gd.c 2005-11-01 14:59:55.318388744 +0100
726@@ -1726,7 +1726,7 @@
727 }
728
729 if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
730- if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC)) {
731+ if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
732 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filename '%s'", fn);
733 RETURN_FALSE;
734 }
735@@ -3824,13 +3824,13 @@
736 }
737
738 /* Check origin file */
739- if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC)) {
740+ if (!fn_org || fn_org == empty_string || php_check_open_basedir(fn_org TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_org, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
741 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid origin filename '%s'", fn_org);
742 RETURN_FALSE;
743 }
744
745 /* Check destination file */
746- if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC)) {
747+ if (!fn_dest || fn_dest == empty_string || php_check_open_basedir(fn_dest TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn_dest, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
748 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid destination filename '%s'", fn_dest);
749 RETURN_FALSE;
750 }
751diff -Nura php-5.0.5/ext/gd/gd_ctx.c hardening-patch-5.0.5-0.4.5/ext/gd/gd_ctx.c
752--- php-5.0.5/ext/gd/gd_ctx.c 2004-01-28 17:25:12.000000000 +0100
753+++ hardening-patch-5.0.5-0.4.5/ext/gd/gd_ctx.c 2005-11-01 14:58:44.575143352 +0100
754@@ -82,7 +82,7 @@
755 }
756
757 if ((argc == 2) || (argc > 2 && Z_STRLEN_PP(file))) {
758- if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC)) {
759+ if (!fn || fn == empty_string || php_check_open_basedir(fn TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(fn, "rb+", CHECKUID_CHECK_FILE_AND_DIR))) {
760 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filename '%s'", fn);
761 RETURN_FALSE;
762 }
763diff -Nura php-5.0.5/ext/mysql/php_mysql.c hardening-patch-5.0.5-0.4.5/ext/mysql/php_mysql.c
764--- php-5.0.5/ext/mysql/php_mysql.c 2005-04-08 00:23:28.000000000 +0200
765+++ hardening-patch-5.0.5-0.4.5/ext/mysql/php_mysql.c 2005-11-01 14:23:05.930266792 +0100
766@@ -1224,6 +1224,8 @@
767 {
768 php_mysql_conn *mysql;
769 MYSQL_RES *mysql_result;
770+ char *copy_query;
771+ int i;
772
773 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
774
775@@ -1274,6 +1276,13 @@
776 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
777 }
778 }
779+ copy_query = estrdup(Z_STRVAL_PP(query));
780+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
781+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
782+ efree(copy_query);
783+ if (HG(hphp_sql_bailout_on_error)) {
784+ zend_bailout();
785+ }
786 RETURN_FALSE;
787 }
788 #else
789@@ -1284,6 +1293,13 @@
790 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
791 }
792 }
793+ copy_query = estrdup(Z_STRVAL_PP(query));
794+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
795+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
796+ efree(copy_query);
797+ if (HG(hphp_sql_bailout_on_error)) {
798+ zend_bailout();
799+ }
800 RETURN_FALSE;
801 }
802 #endif
803diff -Nura php-5.0.5/ext/mysqli/mysqli_nonapi.c hardening-patch-5.0.5-0.4.5/ext/mysqli/mysqli_nonapi.c
804--- php-5.0.5/ext/mysqli/mysqli_nonapi.c 2005-08-06 18:56:06.000000000 +0200
805+++ hardening-patch-5.0.5-0.4.5/ext/mysqli/mysqli_nonapi.c 2005-11-01 14:25:45.702977648 +0100
806@@ -229,6 +229,17 @@
807 if (mysql_real_query(mysql->mysql, query, query_len)) {
808 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
809 unsigned int s_errno;
810+#if HARDENING_PATCH
811+ char *query_copy = estrdup(query);
812+ int i;
813+
814+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
815+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
816+ efree(query_copy);
817+ if (HG(hphp_sql_bailout_on_error)) {
818+ zend_bailout();
819+ }
820+#endif
821 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
822
823 /* we have to save error information, cause
824@@ -278,6 +289,17 @@
825 MYSQLI_DISABLE_MQ;
826
827 if (mysql_real_query(mysql->mysql, query, query_len)) {
828+#if HARDENING_PATCH
829+ char *query_copy = estrdup(query);
830+ int i;
831+
832+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
833+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_error, query_copy);
834+ efree(query_copy);
835+ if (HG(hphp_sql_bailout_on_error)) {
836+ zend_bailout();
837+ }
838+#endif
839 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
840 RETURN_FALSE;
841 }
842diff -Nura php-5.0.5/ext/pgsql/pgsql.c hardening-patch-5.0.5-0.4.5/ext/pgsql/pgsql.c
843--- php-5.0.5/ext/pgsql/pgsql.c 2005-07-05 14:47:06.000000000 +0200
844+++ hardening-patch-5.0.5-0.4.5/ext/pgsql/pgsql.c 2005-11-01 14:23:05.933266336 +0100
845@@ -1080,10 +1080,28 @@
846 case PGRES_EMPTY_QUERY:
847 case PGRES_BAD_RESPONSE:
848 case PGRES_NONFATAL_ERROR:
849- case PGRES_FATAL_ERROR:
850- PHP_PQ_ERROR("Query failed: %s", pgsql);
851- PQclear(pgsql_result);
852- RETURN_FALSE;
853+ case PGRES_FATAL_ERROR:
854+ {
855+#if HARDENING_PATCH
856+ int i;
857+ char *query_copy;
858+#endif
859+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
860+ PQclear(pgsql_result);
861+#if HARDENING_PATCH
862+ query_copy = estrdup(Z_STRVAL_PP(query));
863+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
864+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
865+ efree(query_copy);
866+ if (HG(hphp_sql_bailout_on_error)) {
867+ efree(msgbuf);
868+ zend_bailout();
869+ }
870+#endif
871+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
872+ efree(msgbuf);
873+ RETURN_FALSE;
874+ }
875 break;
876 case PGRES_COMMAND_OK: /* successful command that did not return rows */
877 default:
878diff -Nura php-5.0.5/ext/sqlite/sqlite.c hardening-patch-5.0.5-0.4.5/ext/sqlite/sqlite.c
879--- php-5.0.5/ext/sqlite/sqlite.c 2005-06-07 17:38:37.000000000 +0200
880+++ hardening-patch-5.0.5-0.4.5/ext/sqlite/sqlite.c 2005-11-01 14:23:05.935266032 +0100
881@@ -1481,6 +1481,19 @@
882 db->last_err_code = ret;
883
884 if (ret != SQLITE_OK) {
885+#if HARDENING_PATCH
886+ char *query_copy;
887+ int i;
888+
889+ query_copy = estrdup(sql);
890+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
891+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
892+ efree(query_copy);
893+ if (HG(hphp_sql_bailout_on_error)) {
894+ sqlite_freemem(errtext);
895+ zend_bailout();
896+ }
897+#endif
898 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
899 sqlite_freemem(errtext);
900 goto terminate;
901diff -Nura php-5.0.5/ext/standard/array.c hardening-patch-5.0.5-0.4.5/ext/standard/array.c
902--- php-5.0.5/ext/standard/array.c 2005-09-01 14:01:01.000000000 +0200
903+++ hardening-patch-5.0.5-0.4.5/ext/standard/array.c 2005-11-01 14:23:05.937265728 +0100
904@@ -1283,6 +1283,32 @@
905 }
906 }
907 }
908+
909+ if (var_name[0] == 'H') {
910+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
911+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
912+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
913+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
914+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
915+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
916+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
917+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
918+ return 0;
919+ }
920+ } else if (var_name[0] == '_') {
921+ if ((strcmp(var_name, "_COOKIE")==0)||
922+ (strcmp(var_name, "_ENV")==0)||
923+ (strcmp(var_name, "_FILES")==0)||
924+ (strcmp(var_name, "_GET")==0)||
925+ (strcmp(var_name, "_POST")==0)||
926+ (strcmp(var_name, "_REQUEST")==0)||
927+ (strcmp(var_name, "_SESSION")==0)||
928+ (strcmp(var_name, "_SERVER")==0)) {
929+ return 0;
930+ }
931+ } else if (strcmp(var_name, "GLOBALS")==0) {
932+ return 0;
933+ }
934
935 return 1;
936 }
937diff -Nura php-5.0.5/ext/standard/basic_functions.c hardening-patch-5.0.5-0.4.5/ext/standard/basic_functions.c
938--- php-5.0.5/ext/standard/basic_functions.c 2005-08-21 20:36:33.000000000 +0200
939+++ hardening-patch-5.0.5-0.4.5/ext/standard/basic_functions.c 2005-11-01 14:23:05.939265424 +0100
940@@ -142,12 +142,14 @@
941 typedef struct _php_shutdown_function_entry {
942 zval **arguments;
943 int arg_count;
944+ zend_bool created_by_eval;
945 } php_shutdown_function_entry;
946
947 typedef struct _user_tick_function_entry {
948 zval **arguments;
949 int arg_count;
950 int calling;
951+ zend_bool created_by_eval;
952 } user_tick_function_entry;
953
954 /* some prototypes for local functions */
955@@ -189,6 +191,8 @@
956 PHP_FE(get_html_translation_table, NULL)
957 PHP_FE(sha1, NULL)
958 PHP_FE(sha1_file, NULL)
959+ PHP_FE(sha256, NULL)
960+ PHP_FE(sha256_file, NULL)
961 PHP_NAMED_FE(md5,php_if_md5, NULL)
962 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
963 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
964@@ -616,7 +620,7 @@
965 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
966
967 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
968- PHP_FE(realpath, NULL)
969+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
970 #endif
971
972 #ifdef HAVE_FNMATCH
973@@ -2095,6 +2099,13 @@
974 {
975 zval retval;
976 char *function_name = NULL;
977+#if HARDENING_PATCH
978+ zend_uint orig_code_type = EG(in_code_type);
979+
980+ if (shutdown_function_entry->created_by_eval) {
981+ EG(in_code_type) = ZEND_EVAL_CODE;
982+ }
983+#endif
984
985 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
986 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
987@@ -2110,6 +2121,9 @@
988 if (function_name) {
989 efree(function_name);
990 }
991+#if HARDENING_PATCH
992+ EG(in_code_type) = orig_code_type;
993+#endif
994 return 0;
995 }
996
997@@ -2117,6 +2131,13 @@
998 {
999 zval retval;
1000 zval *function = tick_fe->arguments[0];
1001+#if HARDENING_PATCH
1002+ zend_uint orig_code_type = EG(in_code_type);
1003+
1004+ if (tick_fe->created_by_eval) {
1005+ EG(in_code_type) = ZEND_EVAL_CODE;
1006+ }
1007+#endif
1008
1009 /* Prevent reentrant calls to the same user ticks function */
1010 if (! tick_fe->calling) {
1011@@ -2148,6 +2169,9 @@
1012
1013 tick_fe->calling = 0;
1014 }
1015+#if HARDENING_PATCH
1016+ EG(in_code_type) = orig_code_type;
1017+#endif
1018 }
1019
1020 static void run_user_tick_functions(int tick_count)
1021@@ -2211,6 +2235,13 @@
1022 }
1023
1024 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
1025+#if HARDENING_PATCH
1026+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1027+ shutdown_function_entry.created_by_eval = 1;
1028+ } else {
1029+ shutdown_function_entry.created_by_eval = 0;
1030+ }
1031+#endif
1032
1033 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
1034 RETURN_FALSE;
1035@@ -2794,6 +2825,13 @@
1036 }
1037
1038 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
1039+#if HARDENING_PATCH
1040+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
1041+ tick_fe.created_by_eval = 1;
1042+ } else {
1043+ tick_fe.created_by_eval = 0;
1044+ }
1045+#endif
1046
1047 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
1048 RETURN_FALSE;
1049@@ -3082,6 +3120,35 @@
1050 memcpy(new_key, prefix, prefix_len);
1051 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
1052
1053+ if (new_key[0] == 'H') {
1054+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
1055+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
1056+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
1057+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
1058+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
1059+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
1060+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
1061+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
1062+ efree(new_key);
1063+ return 0;
1064+ }
1065+ } else if (new_key[0] == '_') {
1066+ if ((strcmp(new_key, "_COOKIE")==0)||
1067+ (strcmp(new_key, "_ENV")==0)||
1068+ (strcmp(new_key, "_FILES")==0)||
1069+ (strcmp(new_key, "_GET")==0)||
1070+ (strcmp(new_key, "_POST")==0)||
1071+ (strcmp(new_key, "_REQUEST")==0)||
1072+ (strcmp(new_key, "_SESSION")==0)||
1073+ (strcmp(new_key, "_SERVER")==0)) {
1074+ efree(new_key);
1075+ return 0;
1076+ }
1077+ } else if (strcmp(new_key, "GLOBALS")==0) {
1078+ efree(new_key);
1079+ return 0;
1080+ }
1081+
1082 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1083 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1084
1085diff -Nura php-5.0.5/ext/standard/config.m4 hardening-patch-5.0.5-0.4.5/ext/standard/config.m4
1086--- php-5.0.5/ext/standard/config.m4 2004-12-30 08:04:11.000000000 +0100
1087+++ hardening-patch-5.0.5-0.4.5/ext/standard/config.m4 2005-11-01 14:23:05.939265424 +0100
1088@@ -187,7 +187,7 @@
1089 if test "$ac_cv_crypt_blowfish" = "yes"; then
1090 ac_result=1
1091 else
1092- ac_result=0
1093+ ac_result=1
1094 fi
1095 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1096 ])
1097@@ -469,6 +469,6 @@
1098 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1099 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1100 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
1101- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c)
1102+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
1103
1104 PHP_ADD_MAKEFILE_FRAGMENT
1105diff -Nura php-5.0.5/ext/standard/config.w32 hardening-patch-5.0.5-0.4.5/ext/standard/config.w32
1106--- php-5.0.5/ext/standard/config.w32 2003-12-06 17:04:33.000000000 +0100
1107+++ hardening-patch-5.0.5-0.4.5/ext/standard/config.w32 2005-11-01 14:23:05.939265424 +0100
1108@@ -14,5 +14,5 @@
1109 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
1110 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
1111 user_filters.c uuencode.c filters.c proc_open.c sunfuncs.c \
1112- streamsfuncs.c http.c", false /* never shared */);
1113+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
1114
1115diff -Nura php-5.0.5/ext/standard/crypt_blowfish.c hardening-patch-5.0.5-0.4.5/ext/standard/crypt_blowfish.c
1116--- php-5.0.5/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1117+++ hardening-patch-5.0.5-0.4.5/ext/standard/crypt_blowfish.c 2005-11-01 14:23:05.941265120 +0100
1118@@ -0,0 +1,748 @@
1119+/*
1120+ * This code comes from John the Ripper password cracker, with reentrant
1121+ * and crypt(3) interfaces added, but optimizations specific to password
1122+ * cracking removed.
1123+ *
1124+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1125+ * placed in the public domain.
1126+ *
1127+ * There's absolutely no warranty.
1128+ *
1129+ * It is my intent that you should be able to use this on your system,
1130+ * as a part of a software package, or anywhere else to improve security,
1131+ * ensure compatibility, or for any other purpose. I would appreciate
1132+ * it if you give credit where it is due and keep your modifications in
1133+ * the public domain as well, but I don't require that in order to let
1134+ * you place this code and any modifications you make under a license
1135+ * of your choice.
1136+ *
1137+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1138+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1139+ * ideas. The password hashing algorithm was designed by David Mazieres
1140+ * <dm at lcs.mit.edu>.
1141+ *
1142+ * There's a paper on the algorithm that explains its design decisions:
1143+ *
1144+ * http://www.usenix.org/events/usenix99/provos.html
1145+ *
1146+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1147+ * Blowfish library (I can't be sure if I would think of something if I
1148+ * hadn't seen his code).
1149+ */
1150+
1151+#include <string.h>
1152+
1153+#include <errno.h>
1154+#ifndef __set_errno
1155+#define __set_errno(val) errno = (val)
1156+#endif
1157+
1158+#undef __CONST
1159+#ifdef __GNUC__
1160+#define __CONST __const
1161+#else
1162+#define __CONST
1163+#endif
1164+
1165+#ifdef __i386__
1166+#define BF_ASM 0
1167+#define BF_SCALE 1
1168+#elif defined(__alpha__) || defined(__hppa__)
1169+#define BF_ASM 0
1170+#define BF_SCALE 1
1171+#else
1172+#define BF_ASM 0
1173+#define BF_SCALE 0
1174+#endif
1175+
1176+typedef unsigned int BF_word;
1177+
1178+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1179+#define BF_N 16
1180+
1181+typedef BF_word BF_key[BF_N + 2];
1182+
1183+typedef struct {
1184+ BF_word S[4][0x100];
1185+ BF_key P;
1186+} BF_ctx;
1187+
1188+/*
1189+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1190+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1191+ */
1192+static BF_word BF_magic_w[6] = {
1193+ 0x4F727068, 0x65616E42, 0x65686F6C,
1194+ 0x64657253, 0x63727944, 0x6F756274
1195+};
1196+
1197+/*
1198+ * P-box and S-box tables initialized with digits of Pi.
1199+ */
1200+static BF_ctx BF_init_state = {
1201+ {
1202+ {
1203+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1204+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1205+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1206+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1207+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1208+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1209+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1210+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1211+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1212+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1213+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1214+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1215+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1216+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1217+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1218+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1219+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1220+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1221+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1222+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1223+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1224+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1225+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1226+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1227+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1228+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1229+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1230+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1231+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1232+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1233+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1234+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1235+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1236+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1237+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1238+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1239+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1240+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1241+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1242+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1243+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1244+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1245+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1246+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1247+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1248+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1249+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1250+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1251+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1252+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1253+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1254+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1255+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1256+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1257+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1258+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1259+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1260+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1261+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1262+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1263+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1264+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1265+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1266+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1267+ }, {
1268+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1269+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1270+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1271+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1272+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1273+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1274+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1275+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1276+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1277+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1278+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1279+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1280+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1281+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1282+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1283+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1284+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1285+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1286+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1287+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1288+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1289+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1290+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1291+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1292+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1293+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1294+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1295+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1296+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1297+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1298+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1299+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1300+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1301+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1302+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1303+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1304+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1305+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1306+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1307+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1308+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1309+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1310+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1311+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1312+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1313+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1314+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1315+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1316+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1317+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1318+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1319+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1320+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1321+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1322+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1323+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1324+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1325+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1326+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1327+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1328+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1329+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1330+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1331+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1332+ }, {
1333+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1334+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1335+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1336+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1337+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1338+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1339+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1340+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1341+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1342+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1343+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1344+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1345+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1346+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1347+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1348+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1349+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1350+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1351+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1352+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1353+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1354+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1355+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1356+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1357+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1358+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1359+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1360+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1361+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1362+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1363+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1364+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1365+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1366+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1367+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1368+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1369+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1370+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1371+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1372+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1373+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1374+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1375+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1376+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1377+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1378+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1379+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1380+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1381+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1382+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1383+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1384+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1385+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1386+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1387+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1388+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1389+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1390+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1391+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1392+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1393+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1394+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1395+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1396+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1397+ }, {
1398+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1399+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1400+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1401+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1402+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1403+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1404+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1405+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1406+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1407+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1408+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1409+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1410+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1411+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1412+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1413+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1414+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1415+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1416+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1417+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1418+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1419+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1420+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1421+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1422+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1423+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1424+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1425+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1426+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1427+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1428+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1429+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1430+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1431+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1432+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1433+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1434+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1435+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1436+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1437+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1438+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1439+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1440+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1441+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1442+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1443+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1444+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1445+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1446+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1447+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1448+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1449+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1450+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1451+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1452+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1453+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1454+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1455+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1456+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1457+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1458+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1459+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1460+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1461+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1462+ }
1463+ }, {
1464+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1465+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1466+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1467+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1468+ 0x9216d5d9, 0x8979fb1b
1469+ }
1470+};
1471+
1472+static unsigned char BF_itoa64[64 + 1] =
1473+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1474+
1475+static unsigned char BF_atoi64[0x60] = {
1476+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1477+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1478+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1479+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1480+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1481+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1482+};
1483+
1484+/*
1485+ * This may be optimized out if built with function inlining and no BF_ASM.
1486+ */
1487+static void clean(void *data, int size)
1488+{
1489+#if BF_ASM
1490+ extern void _BF_clean(void *data);
1491+#endif
1492+ memset(data, 0, size);
1493+#if BF_ASM
1494+ _BF_clean(data);
1495+#endif
1496+}
1497+
1498+#define BF_safe_atoi64(dst, src) \
1499+{ \
1500+ tmp = (unsigned char)(src); \
1501+ if (tmp == '$') break; \
1502+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1503+ tmp = BF_atoi64[tmp]; \
1504+ if (tmp > 63) return -1; \
1505+ (dst) = tmp; \
1506+}
1507+
1508+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1509+{
1510+ unsigned char *dptr = (unsigned char *)dst;
1511+ unsigned char *end = dptr + size;
1512+ unsigned char *sptr = (unsigned char *)src;
1513+ unsigned int tmp, c1, c2, c3, c4;
1514+
1515+ do {
1516+ BF_safe_atoi64(c1, *sptr++);
1517+ BF_safe_atoi64(c2, *sptr++);
1518+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1519+ if (dptr >= end) break;
1520+
1521+ BF_safe_atoi64(c3, *sptr++);
1522+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1523+ if (dptr >= end) break;
1524+
1525+ BF_safe_atoi64(c4, *sptr++);
1526+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1527+ } while (dptr < end);
1528+
1529+ while (dptr < end)
1530+ *dptr++ = 0;
1531+
1532+ return 0;
1533+}
1534+
1535+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1536+{
1537+ unsigned char *sptr = (unsigned char *)src;
1538+ unsigned char *end = sptr + size;
1539+ unsigned char *dptr = (unsigned char *)dst;
1540+ unsigned int c1, c2;
1541+
1542+ do {
1543+ c1 = *sptr++;
1544+ *dptr++ = BF_itoa64[c1 >> 2];
1545+ c1 = (c1 & 0x03) << 4;
1546+ if (sptr >= end) {
1547+ *dptr++ = BF_itoa64[c1];
1548+ break;
1549+ }
1550+
1551+ c2 = *sptr++;
1552+ c1 |= c2 >> 4;
1553+ *dptr++ = BF_itoa64[c1];
1554+ c1 = (c2 & 0x0f) << 2;
1555+ if (sptr >= end) {
1556+ *dptr++ = BF_itoa64[c1];
1557+ break;
1558+ }
1559+
1560+ c2 = *sptr++;
1561+ c1 |= c2 >> 6;
1562+ *dptr++ = BF_itoa64[c1];
1563+ *dptr++ = BF_itoa64[c2 & 0x3f];
1564+ } while (sptr < end);
1565+}
1566+
1567+static void BF_swap(BF_word *x, int count)
1568+{
1569+ static int endianness_check = 1;
1570+ char *is_little_endian = (char *)&endianness_check;
1571+ BF_word tmp;
1572+
1573+ if (*is_little_endian)
1574+ do {
1575+ tmp = *x;
1576+ tmp = (tmp << 16) | (tmp >> 16);
1577+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1578+ } while (--count);
1579+}
1580+
1581+#if BF_SCALE
1582+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1583+#define BF_ROUND(L, R, N) \
1584+ tmp1 = L & 0xFF; \
1585+ tmp2 = L >> 8; \
1586+ tmp2 &= 0xFF; \
1587+ tmp3 = L >> 16; \
1588+ tmp3 &= 0xFF; \
1589+ tmp4 = L >> 24; \
1590+ tmp1 = data.ctx.S[3][tmp1]; \
1591+ tmp2 = data.ctx.S[2][tmp2]; \
1592+ tmp3 = data.ctx.S[1][tmp3]; \
1593+ tmp3 += data.ctx.S[0][tmp4]; \
1594+ tmp3 ^= tmp2; \
1595+ R ^= data.ctx.P[N + 1]; \
1596+ tmp3 += tmp1; \
1597+ R ^= tmp3;
1598+#else
1599+/* Architectures with no complicated addressing modes supported */
1600+#define BF_INDEX(S, i) \
1601+ (*((BF_word *)(((unsigned char *)S) + (i))))
1602+#define BF_ROUND(L, R, N) \
1603+ tmp1 = L & 0xFF; \
1604+ tmp1 <<= 2; \
1605+ tmp2 = L >> 6; \
1606+ tmp2 &= 0x3FC; \
1607+ tmp3 = L >> 14; \
1608+ tmp3 &= 0x3FC; \
1609+ tmp4 = L >> 22; \
1610+ tmp4 &= 0x3FC; \
1611+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1612+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1613+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1614+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1615+ tmp3 ^= tmp2; \
1616+ R ^= data.ctx.P[N + 1]; \
1617+ tmp3 += tmp1; \
1618+ R ^= tmp3;
1619+#endif
1620+
1621+/*
1622+ * Encrypt one block, BF_N is hardcoded here.
1623+ */
1624+#define BF_ENCRYPT \
1625+ L ^= data.ctx.P[0]; \
1626+ BF_ROUND(L, R, 0); \
1627+ BF_ROUND(R, L, 1); \
1628+ BF_ROUND(L, R, 2); \
1629+ BF_ROUND(R, L, 3); \
1630+ BF_ROUND(L, R, 4); \
1631+ BF_ROUND(R, L, 5); \
1632+ BF_ROUND(L, R, 6); \
1633+ BF_ROUND(R, L, 7); \
1634+ BF_ROUND(L, R, 8); \
1635+ BF_ROUND(R, L, 9); \
1636+ BF_ROUND(L, R, 10); \
1637+ BF_ROUND(R, L, 11); \
1638+ BF_ROUND(L, R, 12); \
1639+ BF_ROUND(R, L, 13); \
1640+ BF_ROUND(L, R, 14); \
1641+ BF_ROUND(R, L, 15); \
1642+ tmp4 = R; \
1643+ R = L; \
1644+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1645+
1646+#if BF_ASM
1647+#define BF_body() \
1648+ _BF_body_r(&data.ctx);
1649+#else
1650+#define BF_body() \
1651+ L = R = 0; \
1652+ ptr = data.ctx.P; \
1653+ do { \
1654+ ptr += 2; \
1655+ BF_ENCRYPT; \
1656+ *(ptr - 2) = L; \
1657+ *(ptr - 1) = R; \
1658+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1659+\
1660+ ptr = data.ctx.S[0]; \
1661+ do { \
1662+ ptr += 2; \
1663+ BF_ENCRYPT; \
1664+ *(ptr - 2) = L; \
1665+ *(ptr - 1) = R; \
1666+ } while (ptr < &data.ctx.S[3][0xFF]);
1667+#endif
1668+
1669+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1670+{
1671+ __CONST char *ptr = key;
1672+ int i, j;
1673+ BF_word tmp;
1674+
1675+ for (i = 0; i < BF_N + 2; i++) {
1676+ tmp = 0;
1677+ for (j = 0; j < 4; j++) {
1678+ tmp <<= 8;
1679+ tmp |= *ptr;
1680+
1681+ if (!*ptr) ptr = key; else ptr++;
1682+ }
1683+
1684+ expanded[i] = tmp;
1685+ initial[i] = BF_init_state.P[i] ^ tmp;
1686+ }
1687+}
1688+
1689+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
1690+ char *output, int size)
1691+{
1692+#if BF_ASM
1693+ extern void _BF_body_r(BF_ctx *ctx);
1694+#endif
1695+ struct {
1696+ BF_ctx ctx;
1697+ BF_key expanded_key;
1698+ union {
1699+ BF_word salt[4];
1700+ BF_word output[6];
1701+ } binary;
1702+ } data;
1703+ BF_word L, R;
1704+ BF_word tmp1, tmp2, tmp3, tmp4;
1705+ BF_word *ptr;
1706+ BF_word count;
1707+ int i;
1708+
1709+ if (size < 7 + 22 + 31 + 1) {
1710+ __set_errno(ERANGE);
1711+ return NULL;
1712+ }
1713+
1714+ if (setting[0] != '$' ||
1715+ setting[1] != '2' ||
1716+ setting[2] != 'a' ||
1717+ setting[3] != '$' ||
1718+ setting[4] < '0' || setting[4] > '3' ||
1719+ setting[5] < '0' || setting[5] > '9' ||
1720+ setting[6] != '$') {
1721+ __set_errno(EINVAL);
1722+ return NULL;
1723+ }
1724+
1725+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
1726+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
1727+ clean(data.binary.salt, sizeof(data.binary.salt));
1728+ __set_errno(EINVAL);
1729+ return NULL;
1730+ }
1731+
1732+ BF_swap(data.binary.salt, 4);
1733+
1734+ BF_set_key(key, data.expanded_key, data.ctx.P);
1735+
1736+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
1737+
1738+ L = R = 0;
1739+ for (i = 0; i < BF_N + 2; i += 2) {
1740+ L ^= data.binary.salt[i & 2];
1741+ R ^= data.binary.salt[(i & 2) + 1];
1742+ BF_ENCRYPT;
1743+ data.ctx.P[i] = L;
1744+ data.ctx.P[i + 1] = R;
1745+ }
1746+
1747+ ptr = data.ctx.S[0];
1748+ do {
1749+ ptr += 4;
1750+ L ^= data.binary.salt[(BF_N + 2) & 3];
1751+ R ^= data.binary.salt[(BF_N + 3) & 3];
1752+ BF_ENCRYPT;
1753+ *(ptr - 4) = L;
1754+ *(ptr - 3) = R;
1755+
1756+ L ^= data.binary.salt[(BF_N + 4) & 3];
1757+ R ^= data.binary.salt[(BF_N + 5) & 3];
1758+ BF_ENCRYPT;
1759+ *(ptr - 2) = L;
1760+ *(ptr - 1) = R;
1761+ } while (ptr < &data.ctx.S[3][0xFF]);
1762+
1763+ do {
1764+ data.ctx.P[0] ^= data.expanded_key[0];
1765+ data.ctx.P[1] ^= data.expanded_key[1];
1766+ data.ctx.P[2] ^= data.expanded_key[2];
1767+ data.ctx.P[3] ^= data.expanded_key[3];
1768+ data.ctx.P[4] ^= data.expanded_key[4];
1769+ data.ctx.P[5] ^= data.expanded_key[5];
1770+ data.ctx.P[6] ^= data.expanded_key[6];
1771+ data.ctx.P[7] ^= data.expanded_key[7];
1772+ data.ctx.P[8] ^= data.expanded_key[8];
1773+ data.ctx.P[9] ^= data.expanded_key[9];
1774+ data.ctx.P[10] ^= data.expanded_key[10];
1775+ data.ctx.P[11] ^= data.expanded_key[11];
1776+ data.ctx.P[12] ^= data.expanded_key[12];
1777+ data.ctx.P[13] ^= data.expanded_key[13];
1778+ data.ctx.P[14] ^= data.expanded_key[14];
1779+ data.ctx.P[15] ^= data.expanded_key[15];
1780+ data.ctx.P[16] ^= data.expanded_key[16];
1781+ data.ctx.P[17] ^= data.expanded_key[17];
1782+
1783+ BF_body();
1784+
1785+ tmp1 = data.binary.salt[0];
1786+ tmp2 = data.binary.salt[1];
1787+ tmp3 = data.binary.salt[2];
1788+ tmp4 = data.binary.salt[3];
1789+ data.ctx.P[0] ^= tmp1;
1790+ data.ctx.P[1] ^= tmp2;
1791+ data.ctx.P[2] ^= tmp3;
1792+ data.ctx.P[3] ^= tmp4;
1793+ data.ctx.P[4] ^= tmp1;
1794+ data.ctx.P[5] ^= tmp2;
1795+ data.ctx.P[6] ^= tmp3;
1796+ data.ctx.P[7] ^= tmp4;
1797+ data.ctx.P[8] ^= tmp1;
1798+ data.ctx.P[9] ^= tmp2;
1799+ data.ctx.P[10] ^= tmp3;
1800+ data.ctx.P[11] ^= tmp4;
1801+ data.ctx.P[12] ^= tmp1;
1802+ data.ctx.P[13] ^= tmp2;
1803+ data.ctx.P[14] ^= tmp3;
1804+ data.ctx.P[15] ^= tmp4;
1805+ data.ctx.P[16] ^= tmp1;
1806+ data.ctx.P[17] ^= tmp2;
1807+
1808+ BF_body();
1809+ } while (--count);
1810+
1811+ for (i = 0; i < 6; i += 2) {
1812+ L = BF_magic_w[i];
1813+ R = BF_magic_w[i + 1];
1814+
1815+ count = 64;
1816+ do {
1817+ BF_ENCRYPT;
1818+ } while (--count);
1819+
1820+ data.binary.output[i] = L;
1821+ data.binary.output[i + 1] = R;
1822+ }
1823+
1824+ memcpy(output, setting, 7 + 22 - 1);
1825+ output[7 + 22 - 1] = BF_itoa64[(int)
1826+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
1827+
1828+/* This has to be bug-compatible with the original implementation, so
1829+ * only encode 23 of the 24 bytes. :-) */
1830+ BF_swap(data.binary.output, 6);
1831+ BF_encode(&output[7 + 22], data.binary.output, 23);
1832+ output[7 + 22 + 31] = '\0';
1833+
1834+/* Overwrite the most obvious sensitive data we have on the stack. Note
1835+ * that this does not guarantee there's no sensitive data left on the
1836+ * stack and/or in registers; I'm not aware of portable code that does. */
1837+ clean(&data, sizeof(data));
1838+
1839+ return output;
1840+}
1841+
1842+char *_crypt_gensalt_blowfish_rn(unsigned long count,
1843+ __CONST char *input, int size, char *output, int output_size)
1844+{
1845+ if (size < 16 || output_size < 7 + 22 + 1 ||
1846+ (count && (count < 4 || count > 31))) {
1847+ if (output_size > 0) output[0] = '\0';
1848+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
1849+ return NULL;
1850+ }
1851+
1852+ if (!count) count = 5;
1853+
1854+ output[0] = '$';
1855+ output[1] = '2';
1856+ output[2] = 'a';
1857+ output[3] = '$';
1858+ output[4] = '0' + count / 10;
1859+ output[5] = '0' + count % 10;
1860+ output[6] = '$';
1861+
1862+ BF_encode(&output[7], (BF_word *)input, 16);
1863+ output[7 + 22] = '\0';
1864+
1865+ return output;
1866+}
1867diff -Nura php-5.0.5/ext/standard/crypt.c hardening-patch-5.0.5-0.4.5/ext/standard/crypt.c
1868--- php-5.0.5/ext/standard/crypt.c 2004-02-12 20:05:41.000000000 +0100
1869+++ hardening-patch-5.0.5-0.4.5/ext/standard/crypt.c 2005-11-01 14:23:05.941265120 +0100
1870@@ -100,6 +100,8 @@
1871 return SUCCESS;
1872 }
1873
1874+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
1875+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
1876
1877 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1878
1879@@ -135,7 +137,14 @@
1880
1881 /* The automatic salt generation only covers standard DES and md5-crypt */
1882 if(!*salt) {
1883-#if PHP_MD5_CRYPT
1884+#if PHP_BLOWFISH_CRYPT
1885+ char randat[16];
1886+ int i;
1887+
1888+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
1889+
1890+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
1891+#elif PHP_MD5_CRYPT
1892 strcpy(salt, "$1$");
1893 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
1894 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
1895@@ -145,8 +154,24 @@
1896 salt[2] = '\0';
1897 #endif
1898 }
1899-
1900- RETVAL_STRING(crypt(str, salt), 1);
1901+
1902+ if (salt[0] == '$' &&
1903+ salt[1] == '2' &&
1904+ salt[2] == 'a' &&
1905+ salt[3] == '$' &&
1906+ salt[4] >= '0' && salt[4] <= '3' &&
1907+ salt[5] >= '0' && salt[5] <= '9' &&
1908+ salt[6] == '$') {
1909+
1910+ char output[PHP_MAX_SALT_LEN+1];
1911+
1912+ output[0] = 0;
1913+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
1914+ RETVAL_STRING(output, 1);
1915+
1916+ } else {
1917+ RETVAL_STRING(crypt(str, salt), 1);
1918+ }
1919 }
1920 /* }}} */
1921 #endif
1922diff -Nura php-5.0.5/ext/standard/dl.c hardening-patch-5.0.5-0.4.5/ext/standard/dl.c
1923--- php-5.0.5/ext/standard/dl.c 2005-05-04 15:48:01.000000000 +0200
1924+++ hardening-patch-5.0.5-0.4.5/ext/standard/dl.c 2005-11-01 14:23:05.942264968 +0100
1925@@ -159,8 +159,35 @@
1926 RETURN_FALSE;
1927 }
1928 module_entry = get_module();
1929+
1930+ /* check if Hardening-Patch is installed */
1931+ if (module_entry->zend_api < 1000000000) {
1932+ php_error_docref(NULL TSRMLS_CC, error_type,
1933+ "%s: Unable to initialize module\n"
1934+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
1935+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1936+ "These options need to match\n",
1937+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
1938+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1939+ DL_UNLOAD(handle);
1940+ RETURN_FALSE;
1941+ }
1942+
1943+ /* check if correct Hardening-Patch is installed */
1944+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
1945+ php_error_docref(NULL TSRMLS_CC, error_type,
1946+ "%s: Unable to initialize module\n"
1947+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1948+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1949+ "These options need to match\n",
1950+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
1951+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1952+ DL_UNLOAD(handle);
1953+ RETURN_FALSE;
1954+ }
1955+
1956 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
1957- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
1958+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
1959 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
1960 struct pre_4_1_0_module_entry {
1961 char *name;
1962@@ -194,7 +221,7 @@
1963 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
1964 } else {
1965 name = module_entry->name;
1966- zend_api = module_entry->zend_api;
1967+ zend_api = module_entry->real_zend_api;
1968 zend_debug = module_entry->zend_debug;
1969 zts = module_entry->zts;
1970 }
1971diff -Nura php-5.0.5/ext/standard/file.c hardening-patch-5.0.5-0.4.5/ext/standard/file.c
1972--- php-5.0.5/ext/standard/file.c 2005-04-06 15:59:48.000000000 +0200
1973+++ hardening-patch-5.0.5-0.4.5/ext/standard/file.c 2005-11-01 14:23:05.943264816 +0100
1974@@ -2044,7 +2044,7 @@
1975 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1976 /* {{{ proto string realpath(string path)
1977 Return the resolved path */
1978-PHP_FUNCTION(realpath)
1979+PHP_FUNCTION(real_path)
1980 {
1981 zval **path;
1982 char resolved_path_buff[MAXPATHLEN];
1983diff -Nura php-5.0.5/ext/standard/file.h hardening-patch-5.0.5-0.4.5/ext/standard/file.h
1984--- php-5.0.5/ext/standard/file.h 2005-07-15 11:29:18.000000000 +0200
1985+++ hardening-patch-5.0.5-0.4.5/ext/standard/file.h 2005-11-01 14:23:05.943264816 +0100
1986@@ -60,7 +60,7 @@
1987 PHP_FUNCTION(fd_set);
1988 PHP_FUNCTION(fd_isset);
1989 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
1990-PHP_FUNCTION(realpath);
1991+PHP_FUNCTION(real_path);
1992 PHP_FUNCTION(fnmatch);
1993 #endif
1994 PHP_NAMED_FUNCTION(php_if_ftruncate);
1995diff -Nura php-5.0.5/ext/standard/head.c hardening-patch-5.0.5-0.4.5/ext/standard/head.c
1996--- php-5.0.5/ext/standard/head.c 2005-06-28 16:49:14.000000000 +0200
1997+++ hardening-patch-5.0.5-0.4.5/ext/standard/head.c 2005-11-01 14:23:05.944264664 +0100
1998@@ -40,10 +40,31 @@
1999 {
2000 zend_bool rep = 1;
2001 sapi_header_line ctr = {0};
2002+#if HARDENING_PATCH
2003+ int i;
2004+#endif
2005
2006 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
2007 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
2008 return;
2009+
2010+#if HARDENING_PATCH
2011+ if (!HG(hphp_multiheader)) {
2012+ for (i=0; i<ctr.line_len; i++) {
2013+ if (ctr.line[i]==0) {
2014+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
2015+ ctr.line_len=i;
2016+ break;
2017+ } else if (ctr.line[i]=='\n') {
2018+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
2019+ continue;
2020+ }
2021+ php_security_log(S_MISC, "header(): headerline contains more than one header");
2022+ ctr.line_len=i;
2023+ }
2024+ }
2025+ }
2026+#endif
2027
2028 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
2029 }
2030diff -Nura php-5.0.5/ext/standard/info.c hardening-patch-5.0.5-0.4.5/ext/standard/info.c
2031--- php-5.0.5/ext/standard/info.c 2005-08-16 02:25:46.000000000 +0200
2032+++ hardening-patch-5.0.5-0.4.5/ext/standard/info.c 2005-11-01 15:18:32.121608848 +0100
2033@@ -409,7 +409,7 @@
2034
2035 if (flag & PHP_INFO_GENERAL) {
2036 char *zend_version = get_zend_version();
2037- char temp_api[10];
2038+ char temp_api[11];
2039 char *logo_guid;
2040
2041 php_uname = php_get_uname('a');
2042@@ -432,11 +432,22 @@
2043 PUTS("\" alt=\"PHP Logo\" /></a>");
2044 }
2045
2046+#if HARDENING_PATCH
2047+ if (!sapi_module.phpinfo_as_text) {
2048+ php_printf("<h1 class=\"p\">PHP Version %s with <a href=\"http://www.hardened-php.net\">Hardening-Patch</a> %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
2049+ } else {
2050+ char temp_ver[40];
2051+
2052+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
2053+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
2054+ }
2055+#else
2056 if (!sapi_module.phpinfo_as_text) {
2057 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
2058 } else {
2059 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
2060- }
2061+ }
2062+#endif
2063 php_info_print_box_end();
2064 php_info_print_table_start();
2065 php_info_print_table_row(2, "System", php_uname );
2066diff -Nura php-5.0.5/ext/standard/php_standard.h hardening-patch-5.0.5-0.4.5/ext/standard/php_standard.h
2067--- php-5.0.5/ext/standard/php_standard.h 2004-01-08 18:32:51.000000000 +0100
2068+++ hardening-patch-5.0.5-0.4.5/ext/standard/php_standard.h 2005-11-01 14:23:05.945264512 +0100
2069@@ -28,6 +28,7 @@
2070 #include "php_mail.h"
2071 #include "md5.h"
2072 #include "sha1.h"
2073+#include "sha256.h"
2074 #include "html.h"
2075 #include "exec.h"
2076 #include "file.h"
2077diff -Nura php-5.0.5/ext/standard/sha256.c hardening-patch-5.0.5-0.4.5/ext/standard/sha256.c
2078--- php-5.0.5/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2079+++ hardening-patch-5.0.5-0.4.5/ext/standard/sha256.c 2005-11-01 14:23:05.946264360 +0100
2080@@ -0,0 +1,398 @@
2081+/*
2082+ +----------------------------------------------------------------------+
2083+ | PHP Version 5 |
2084+ +----------------------------------------------------------------------+
2085+ | Copyright (c) 1997-2004 The PHP Group |
2086+ +----------------------------------------------------------------------+
2087+ | This source file is subject to version 3.0 of the PHP license, |
2088+ | that is bundled with this package in the file LICENSE, and is |
2089+ | available through the world-wide-web at the following url: |
2090+ | http://www.php.net/license/3_0.txt. |
2091+ | If you did not receive a copy of the PHP license and are unable to |
2092+ | obtain it through the world-wide-web, please send a note to |
2093+ | license@php.net so we can mail you a copy immediately. |
2094+ +----------------------------------------------------------------------+
2095+ | Author: Stefan Esser <sesser@php.net> |
2096+ +----------------------------------------------------------------------+
2097+*/
2098+
2099+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2100+
2101+#include <stdio.h>
2102+#include "php.h"
2103+
2104+/* This code is heavily based on the PHP md5/sha1 implementations */
2105+
2106+#include "sha256.h"
2107+
2108+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2109+{
2110+ int i;
2111+
2112+ for (i = 0; i < 32; i++) {
2113+ sprintf(sha256str, "%02x", digest[i]);
2114+ sha256str += 2;
2115+ }
2116+
2117+ *sha256str = '\0';
2118+}
2119+
2120+/* {{{ proto string sha256(string str [, bool raw_output])
2121+ Calculate the sha256 hash of a string */
2122+PHP_FUNCTION(sha256)
2123+{
2124+ char *arg;
2125+ int arg_len;
2126+ zend_bool raw_output = 0;
2127+ char sha256str[65];
2128+ PHP_SHA256_CTX context;
2129+ unsigned char digest[32];
2130+
2131+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2132+ return;
2133+ }
2134+
2135+ sha256str[0] = '\0';
2136+ PHP_SHA256Init(&context);
2137+ PHP_SHA256Update(&context, arg, arg_len);
2138+ PHP_SHA256Final(digest, &context);
2139+ if (raw_output) {
2140+ RETURN_STRINGL(digest, 32, 1);
2141+ } else {
2142+ make_sha256_digest(sha256str, digest);
2143+ RETVAL_STRING(sha256str, 1);
2144+ }
2145+
2146+}
2147+
2148+/* }}} */
2149+
2150+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2151+ Calculate the sha256 hash of given filename */
2152+PHP_FUNCTION(sha256_file)
2153+{
2154+ char *arg;
2155+ int arg_len;
2156+ zend_bool raw_output = 0;
2157+ char sha256str[65];
2158+ unsigned char buf[1024];
2159+ unsigned char digest[32];
2160+ PHP_SHA256_CTX context;
2161+ int n;
2162+ FILE *fp;
2163+
2164+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2165+ return;
2166+ }
2167+
2168+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2169+ RETURN_FALSE;
2170+ }
2171+
2172+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2173+ RETURN_FALSE;
2174+ }
2175+
2176+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2177+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2178+ RETURN_FALSE;
2179+ }
2180+
2181+ PHP_SHA256Init(&context);
2182+
2183+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2184+ PHP_SHA256Update(&context, buf, n);
2185+ }
2186+
2187+ PHP_SHA256Final(digest, &context);
2188+
2189+ if (ferror(fp)) {
2190+ fclose(fp);
2191+ RETURN_FALSE;
2192+ }
2193+
2194+ fclose(fp);
2195+
2196+ if (raw_output) {
2197+ RETURN_STRINGL(digest, 32, 1);
2198+ } else {
2199+ make_sha256_digest(sha256str, digest);
2200+ RETVAL_STRING(sha256str, 1);
2201+ }
2202+}
2203+/* }}} */
2204+
2205+
2206+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2207+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2208+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2209+
2210+static unsigned char PADDING[64] =
2211+{
2212+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2213+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2214+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2215+};
2216+
2217+/* F, G, H and I are basic SHA256 functions.
2218+ */
2219+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2220+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2221+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2222+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2223+
2224+/* ROTATE_RIGHT rotates x right n bits.
2225+ */
2226+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2227+
2228+/* W[i]
2229+ */
2230+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2231+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2232+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2233+
2234+/* ROUND function of sha256
2235+ */
2236+
2237+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2238+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2239+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2240+ (d) += t1; \
2241+ }
2242+
2243+
2244+/* {{{ PHP_SHA256Init
2245+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2246+ */
2247+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2248+{
2249+ context->count[0] = context->count[1] = 0;
2250+ /* Load magic initialization constants.
2251+ */
2252+ context->state[0] = 0x6a09e667;
2253+ context->state[1] = 0xbb67ae85;
2254+ context->state[2] = 0x3c6ef372;
2255+ context->state[3] = 0xa54ff53a;
2256+ context->state[4] = 0x510e527f;
2257+ context->state[5] = 0x9b05688c;
2258+ context->state[6] = 0x1f83d9ab;
2259+ context->state[7] = 0x5be0cd19;
2260+}
2261+/* }}} */
2262+
2263+/* {{{ PHP_SHA256Update
2264+ SHA256 block update operation. Continues an SHA256 message-digest
2265+ operation, processing another message block, and updating the
2266+ context.
2267+ */
2268+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2269+ unsigned int inputLen)
2270+{
2271+ unsigned int i, index, partLen;
2272+
2273+ /* Compute number of bytes mod 64 */
2274+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2275+
2276+ /* Update number of bits */
2277+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2278+ < ((php_uint32) inputLen << 3))
2279+ context->count[1]++;
2280+ context->count[1] += ((php_uint32) inputLen >> 29);
2281+
2282+ partLen = 64 - index;
2283+
2284+ /* Transform as many times as possible.
2285+ */
2286+ if (inputLen >= partLen) {
2287+ memcpy
2288+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2289+ SHA256Transform(context->state, context->buffer);
2290+
2291+ for (i = partLen; i + 63 < inputLen; i += 64)
2292+ SHA256Transform(context->state, &input[i]);
2293+
2294+ index = 0;
2295+ } else
2296+ i = 0;
2297+
2298+ /* Buffer remaining input */
2299+ memcpy
2300+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2301+ inputLen - i);
2302+}
2303+/* }}} */
2304+
2305+/* {{{ PHP_SHA256Final
2306+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2307+ the message digest and zeroizing the context.
2308+ */
2309+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2310+{
2311+ unsigned char bits[8];
2312+ unsigned int index, padLen;
2313+
2314+ /* Save number of bits */
2315+ bits[7] = context->count[0] & 0xFF;
2316+ bits[6] = (context->count[0] >> 8) & 0xFF;
2317+ bits[5] = (context->count[0] >> 16) & 0xFF;
2318+ bits[4] = (context->count[0] >> 24) & 0xFF;
2319+ bits[3] = context->count[1] & 0xFF;
2320+ bits[2] = (context->count[1] >> 8) & 0xFF;
2321+ bits[1] = (context->count[1] >> 16) & 0xFF;
2322+ bits[0] = (context->count[1] >> 24) & 0xFF;
2323+
2324+ /* Pad out to 56 mod 64.
2325+ */
2326+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2327+ padLen = (index < 56) ? (56 - index) : (120 - index);
2328+ PHP_SHA256Update(context, PADDING, padLen);
2329+
2330+ /* Append length (before padding) */
2331+ PHP_SHA256Update(context, bits, 8);
2332+
2333+ /* Store state in digest */
2334+ SHA256Encode(digest, context->state, 32);
2335+
2336+ /* Zeroize sensitive information.
2337+ */
2338+ memset((unsigned char*) context, 0, sizeof(*context));
2339+}
2340+/* }}} */
2341+
2342+/* {{{ SHA256Transform
2343+ * SHA256 basic transformation. Transforms state based on block.
2344+ */
2345+static void SHA256Transform(state, block)
2346+php_uint32 state[8];
2347+const unsigned char block[64];
2348+{
2349+ php_uint32 a = state[0], b = state[1], c = state[2];
2350+ php_uint32 d = state[3], e = state[4], f = state[5];
2351+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2352+
2353+ SHA256Decode(x, block, 64);
2354+
2355+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2356+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2357+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2358+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2359+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2360+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2361+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2362+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2363+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2364+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2365+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2366+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2367+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2368+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2369+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2370+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2371+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2372+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2373+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2374+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2375+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2376+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2377+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2378+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2379+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2380+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2381+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2382+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2383+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2384+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2385+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2386+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2387+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2388+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2389+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2390+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2391+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2392+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2393+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2394+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2395+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2396+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2397+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2398+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2399+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2400+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2401+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2402+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2403+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2404+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2405+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2406+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2407+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2408+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2409+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2410+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2411+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2412+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2413+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2414+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2415+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2416+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2417+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2418+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2419+
2420+ state[0] += a;
2421+ state[1] += b;
2422+ state[2] += c;
2423+ state[3] += d;
2424+ state[4] += e;
2425+ state[5] += f;
2426+ state[6] += g;
2427+ state[7] += h;
2428+
2429+ /* Zeroize sensitive information. */
2430+ memset((unsigned char*) x, 0, sizeof(x));
2431+}
2432+/* }}} */
2433+
2434+/* {{{ SHA256Encode
2435+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2436+ a multiple of 4.
2437+ */
2438+static void SHA256Encode(output, input, len)
2439+unsigned char *output;
2440+php_uint32 *input;
2441+unsigned int len;
2442+{
2443+ unsigned int i, j;
2444+
2445+ for (i = 0, j = 0; j < len; i++, j += 4) {
2446+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2447+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2448+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2449+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2450+ }
2451+}
2452+/* }}} */
2453+
2454+/* {{{ SHA256Decode
2455+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2456+ a multiple of 4.
2457+ */
2458+static void SHA256Decode(output, input, len)
2459+php_uint32 *output;
2460+const unsigned char *input;
2461+unsigned int len;
2462+{
2463+ unsigned int i, j;
2464+
2465+ for (i = 0, j = 0; j < len; i++, j += 4)
2466+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2467+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2468+}
2469+/* }}} */
2470+
2471+/*
2472+ * Local variables:
2473+ * tab-width: 4
2474+ * c-basic-offset: 4
2475+ * End:
2476+ * vim600: sw=4 ts=4 fdm=marker
2477+ * vim<600: sw=4 ts=4
2478+ */
2479diff -Nura php-5.0.5/ext/standard/sha256.h hardening-patch-5.0.5-0.4.5/ext/standard/sha256.h
2480--- php-5.0.5/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2481+++ hardening-patch-5.0.5-0.4.5/ext/standard/sha256.h 2005-11-01 14:23:05.946264360 +0100
2482@@ -0,0 +1,40 @@
2483+/*
2484+ +----------------------------------------------------------------------+
2485+ | PHP Version 5 |
2486+ +----------------------------------------------------------------------+
2487+ | Copyright (c) 1997-2004 The PHP Group |
2488+ +----------------------------------------------------------------------+
2489+ | This source file is subject to version 3.0 of the PHP license, |
2490+ | that is bundled with this package in the file LICENSE, and is |
2491+ | available through the world-wide-web at the following url: |
2492+ | http://www.php.net/license/3_0.txt. |
2493+ | If you did not receive a copy of the PHP license and are unable to |
2494+ | obtain it through the world-wide-web, please send a note to |
2495+ | license@php.net so we can mail you a copy immediately. |
2496+ +----------------------------------------------------------------------+
2497+ | Author: Stefan Esser <sesser@php.net> |
2498+ +----------------------------------------------------------------------+
2499+*/
2500+
2501+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2502+
2503+#ifndef SHA256_H
2504+#define SHA256_H
2505+
2506+#include "ext/standard/basic_functions.h"
2507+
2508+/* SHA1 context. */
2509+typedef struct {
2510+ php_uint32 state[8]; /* state (ABCD) */
2511+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2512+ unsigned char buffer[64]; /* input buffer */
2513+} PHP_SHA256_CTX;
2514+
2515+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2516+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2517+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2518+
2519+PHP_FUNCTION(sha256);
2520+PHP_FUNCTION(sha256_file);
2521+
2522+#endif
2523diff -Nura php-5.0.5/ext/standard/string.c hardening-patch-5.0.5-0.4.5/ext/standard/string.c
2524--- php-5.0.5/ext/standard/string.c 2005-07-16 13:18:35.000000000 +0200
2525+++ hardening-patch-5.0.5-0.4.5/ext/standard/string.c 2005-11-01 15:12:35.811776176 +0100
2526@@ -3809,7 +3809,6 @@
2527 zval *sarg;
2528 char *res = NULL;
2529 int argCount;
2530- int old_rg;
2531
2532 argCount = ZEND_NUM_ARGS();
2533 if (argCount < 1 || argCount > 2 || zend_get_parameters_ex(argCount, &arg, &arrayArg) == FAILURE) {
2534@@ -3822,19 +3821,18 @@
2535 res = estrndup(Z_STRVAL_P(sarg), Z_STRLEN_P(sarg));
2536 }
2537
2538- old_rg = PG(register_globals);
2539- if (argCount == 1) {
2540- PG(register_globals) = 1;
2541- sapi_module.treat_data(PARSE_STRING, res, NULL TSRMLS_CC);
2542- } else {
2543- PG(register_globals) = 0;
2544- /* Clear out the array that was passed in. */
2545- zval_dtor(*arrayArg);
2546- array_init(*arrayArg);
2547-
2548- sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC);
2549- }
2550- PG(register_globals) = old_rg;
2551+ if (argCount == 1) {
2552+ zval tmp;
2553+ Z_ARRVAL(tmp) = EG(active_symbol_table);
2554+
2555+ sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
2556+ } else {
2557+ /* Clear out the array that was passed in. */
2558+ zval_dtor(*arrayArg);
2559+ array_init(*arrayArg);
2560+
2561+ sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC);
2562+ }
2563 }
2564 /* }}} */
2565
2566diff -Nura php-5.0.5/ext/standard/syslog.c hardening-patch-5.0.5-0.4.5/ext/standard/syslog.c
2567--- php-5.0.5/ext/standard/syslog.c 2005-07-15 11:29:19.000000000 +0200
2568+++ hardening-patch-5.0.5-0.4.5/ext/standard/syslog.c 2005-11-01 14:23:05.946264360 +0100
2569@@ -42,6 +42,7 @@
2570 */
2571 PHP_MINIT_FUNCTION(syslog)
2572 {
2573+#if !HARDENING_PATCH
2574 /* error levels */
2575 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2576 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2577@@ -97,7 +98,7 @@
2578 /* AIX doesn't have LOG_PERROR */
2579 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2580 #endif
2581-
2582+#endif
2583 return SUCCESS;
2584 }
2585 /* }}} */
2586diff -Nura php-5.0.5/ext/varfilter/config.m4 hardening-patch-5.0.5-0.4.5/ext/varfilter/config.m4
2587--- php-5.0.5/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2588+++ hardening-patch-5.0.5-0.4.5/ext/varfilter/config.m4 2005-10-30 17:12:13.000000000 +0100
2589@@ -0,0 +1,11 @@
2590+dnl
2591+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2592+dnl
2593+
2594+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2595+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2596+
2597+if test "$PHP_VARFILTER" != "no"; then
2598+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2599+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2600+fi
2601diff -Nura php-5.0.5/ext/varfilter/CREDITS hardening-patch-5.0.5-0.4.5/ext/varfilter/CREDITS
2602--- php-5.0.5/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2603+++ hardening-patch-5.0.5-0.4.5/ext/varfilter/CREDITS 2005-10-30 17:12:13.000000000 +0100
2604@@ -0,0 +1,2 @@
2605+varfilter
2606+Stefan Esser
2607\ Kein Zeilenumbruch am Dateiende.
2608diff -Nura php-5.0.5/ext/varfilter/php_varfilter.h hardening-patch-5.0.5-0.4.5/ext/varfilter/php_varfilter.h
2609--- php-5.0.5/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2610+++ hardening-patch-5.0.5-0.4.5/ext/varfilter/php_varfilter.h 2005-11-01 15:48:03.000000000 +0100
2611@@ -0,0 +1,122 @@
2612+/*
2613+ +----------------------------------------------------------------------+
2614+ | Hardened-PHP Project's varfilter extension |
2615+ +----------------------------------------------------------------------+
2616+ | Copyright (c) 2004-2005 Stefan Esser |
2617+ +----------------------------------------------------------------------+
2618+ | This source file is subject to version 2.02 of the PHP license, |
2619+ | that is bundled with this package in the file LICENSE, and is |
2620+ | available at through the world-wide-web at |
2621+ | http://www.php.net/license/2_02.txt. |
2622+ | If you did not receive a copy of the PHP license and are unable to |
2623+ | obtain it through the world-wide-web, please send a note to |
2624+ | license@php.net so we can mail you a copy immediately. |
2625+ +----------------------------------------------------------------------+
2626+ | Author: Stefan Esser <sesser@hardened-php.net> |
2627+ +----------------------------------------------------------------------+
2628+
2629+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2630+*/
2631+
2632+#ifndef PHP_VARFILTER_H
2633+#define PHP_VARFILTER_H
2634+
2635+extern zend_module_entry varfilter_module_entry;
2636+#define phpext_varfilter_ptr &varfilter_module_entry
2637+
2638+#ifdef PHP_WIN32
2639+#define PHP_VARFILTER_API __declspec(dllexport)
2640+#else
2641+#define PHP_VARFILTER_API
2642+#endif
2643+
2644+#ifdef ZTS
2645+#include "TSRM.h"
2646+#endif
2647+
2648+#include "SAPI.h"
2649+
2650+#include "php_variables.h"
2651+
2652+
2653+PHP_MINIT_FUNCTION(varfilter);
2654+PHP_MSHUTDOWN_FUNCTION(varfilter);
2655+PHP_RINIT_FUNCTION(varfilter);
2656+PHP_RSHUTDOWN_FUNCTION(varfilter);
2657+PHP_MINFO_FUNCTION(varfilter);
2658+
2659+
2660+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2661+/* request variables */
2662+ long max_request_variables;
2663+ long cur_request_variables;
2664+ long max_varname_length;
2665+ long max_totalname_length;
2666+ long max_value_length;
2667+ long max_array_depth;
2668+ long max_array_index_length;
2669+ zend_bool disallow_nul;
2670+/* cookie variables */
2671+ long max_cookie_vars;
2672+ long cur_cookie_vars;
2673+ long max_cookie_name_length;
2674+ long max_cookie_totalname_length;
2675+ long max_cookie_value_length;
2676+ long max_cookie_array_depth;
2677+ long max_cookie_array_index_length;
2678+ zend_bool disallow_cookie_nul;
2679+/* get variables */
2680+ long max_get_vars;
2681+ long cur_get_vars;
2682+ long max_get_name_length;
2683+ long max_get_totalname_length;
2684+ long max_get_value_length;
2685+ long max_get_array_depth;
2686+ long max_get_array_index_length;
2687+ zend_bool disallow_get_nul;
2688+/* post variables */
2689+ long max_post_vars;
2690+ long cur_post_vars;
2691+ long max_post_name_length;
2692+ long max_post_totalname_length;
2693+ long max_post_value_length;
2694+ long max_post_array_depth;
2695+ long max_post_array_index_length;
2696+ zend_bool disallow_post_nul;
2697+/* fileupload */
2698+ long max_uploads;
2699+ long cur_uploads;
2700+ zend_bool disallow_elf_files;
2701+ char *verification_script;
2702+
2703+ zend_bool no_more_variables;
2704+ zend_bool no_more_get_variables;
2705+ zend_bool no_more_post_variables;
2706+ zend_bool no_more_cookie_variables;
2707+ zend_bool no_more_uploads;
2708+
2709+ZEND_END_MODULE_GLOBALS(varfilter)
2710+
2711+
2712+#ifdef ZTS
2713+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2714+#else
2715+#define VARFILTER_G(v) (varfilter_globals.v)
2716+#endif
2717+
2718+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2719+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter);
2720+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
2721+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
2722+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
2723+
2724+#endif /* PHP_VARFILTER_H */
2725+
2726+
2727+/*
2728+ * Local variables:
2729+ * tab-width: 4
2730+ * c-basic-offset: 4
2731+ * indent-tabs-mode: t
2732+ * End:
2733+ */
2734diff -Nura php-5.0.5/ext/varfilter/varfilter.c hardening-patch-5.0.5-0.4.5/ext/varfilter/varfilter.c
2735--- php-5.0.5/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2736+++ hardening-patch-5.0.5-0.4.5/ext/varfilter/varfilter.c 2005-11-01 15:52:23.000000000 +0100
2737@@ -0,0 +1,809 @@
2738+/*
2739+ +----------------------------------------------------------------------+
2740+ | Hardened-PHP Project's varfilter extension |
2741+ +----------------------------------------------------------------------+
2742+ | Copyright (c) 2004-2005 Stefan Esser |
2743+ +----------------------------------------------------------------------+
2744+ | This source file is subject to version 2.02 of the PHP license, |
2745+ | that is bundled with this package in the file LICENSE, and is |
2746+ | available at through the world-wide-web at |
2747+ | http://www.php.net/license/2_02.txt. |
2748+ | If you did not receive a copy of the PHP license and are unable to |
2749+ | obtain it through the world-wide-web, please send a note to |
2750+ | license@php.net so we can mail you a copy immediately. |
2751+ +----------------------------------------------------------------------+
2752+ | Author: Stefan Esser <sesser@hardened-php.net> |
2753+ +----------------------------------------------------------------------+
2754+
2755+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2756+*/
2757+
2758+#ifdef HAVE_CONFIG_H
2759+#include "config.h"
2760+#endif
2761+
2762+#include "php.h"
2763+#include "php_ini.h"
2764+#include "ext/standard/info.h"
2765+#include "php_varfilter.h"
2766+#include "hardening_patch.h"
2767+
2768+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2769+
2770+/* True global resources - no need for thread safety here */
2771+static int le_varfilter;
2772+
2773+/* {{{ varfilter_module_entry
2774+ */
2775+zend_module_entry varfilter_module_entry = {
2776+#if ZEND_MODULE_API_NO >= 20010901
2777+ STANDARD_MODULE_HEADER,
2778+#endif
2779+ "varfilter",
2780+ NULL,
2781+ PHP_MINIT(varfilter),
2782+ PHP_MSHUTDOWN(varfilter),
2783+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2784+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2785+ PHP_MINFO(varfilter),
2786+#if ZEND_MODULE_API_NO >= 20010901
2787+ "0.4.5", /* Replace with version number for your extension */
2788+#endif
2789+ STANDARD_MODULE_PROPERTIES
2790+};
2791+/* }}} */
2792+
2793+#ifdef COMPILE_DL_VARFILTER
2794+ZEND_GET_MODULE(varfilter)
2795+#endif
2796+
2797+/* {{{ PHP_INI
2798+ */
2799+PHP_INI_BEGIN()
2800+ /* for backward compatibility */
2801+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2802+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2803+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2804+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2805+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2806+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2807+
2808+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2809+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2810+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2811+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2812+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2813+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2814+ STD_PHP_INI_ENTRY("hphp.request.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_nul, zend_varfilter_globals, varfilter_globals)
2815+
2816+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
2817+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
2818+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
2819+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
2820+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
2821+ 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)
2822+ STD_PHP_INI_ENTRY("hphp.cookie.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_cookie_nul, zend_varfilter_globals, varfilter_globals)
2823+
2824+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
2825+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
2826+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
2827+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
2828+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
2829+ 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)
2830+ STD_PHP_INI_ENTRY("hphp.get.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_get_nul, zend_varfilter_globals, varfilter_globals)
2831+
2832+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
2833+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
2834+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
2835+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
2836+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
2837+ 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)
2838+ STD_PHP_INI_ENTRY("hphp.post.disallow_nul", "1", PHP_INI_PERDIR, OnUpdateBool, disallow_post_nul, zend_varfilter_globals, varfilter_globals)
2839+
2840+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
2841+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
2842+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
2843+
2844+
2845+PHP_INI_END()
2846+/* }}} */
2847+
2848+/* {{{ php_varfilter_init_globals
2849+ */
2850+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2851+{
2852+ varfilter_globals->max_request_variables = 200;
2853+ varfilter_globals->max_varname_length = 64;
2854+ varfilter_globals->max_value_length = 10000;
2855+ varfilter_globals->max_array_depth = 100;
2856+ varfilter_globals->max_totalname_length = 256;
2857+ varfilter_globals->max_array_index_length = 64;
2858+ varfilter_globals->disallow_nul = 1;
2859+
2860+ varfilter_globals->max_cookie_vars = 100;
2861+ varfilter_globals->max_cookie_name_length = 64;
2862+ varfilter_globals->max_cookie_totalname_length = 256;
2863+ varfilter_globals->max_cookie_value_length = 10000;
2864+ varfilter_globals->max_cookie_array_depth = 100;
2865+ varfilter_globals->max_cookie_array_index_length = 64;
2866+ varfilter_globals->disallow_cookie_nul = 1;
2867+
2868+ varfilter_globals->max_get_vars = 100;
2869+ varfilter_globals->max_get_name_length = 64;
2870+ varfilter_globals->max_get_totalname_length = 256;
2871+ varfilter_globals->max_get_value_length = 512;
2872+ varfilter_globals->max_get_array_depth = 50;
2873+ varfilter_globals->max_get_array_index_length = 64;
2874+ varfilter_globals->disallow_get_nul = 1;
2875+
2876+ varfilter_globals->max_post_vars = 200;
2877+ varfilter_globals->max_post_name_length = 64;
2878+ varfilter_globals->max_post_totalname_length = 256;
2879+ varfilter_globals->max_post_value_length = 65000;
2880+ varfilter_globals->max_post_array_depth = 100;
2881+ varfilter_globals->max_post_array_index_length = 64;
2882+ varfilter_globals->disallow_post_nul = 1;
2883+
2884+ varfilter_globals->max_uploads = 25;
2885+ varfilter_globals->disallow_elf_files = 1;
2886+ varfilter_globals->verification_script = NULL;
2887+
2888+ varfilter_globals->no_more_variables = 0;
2889+ varfilter_globals->no_more_get_variables = 0;
2890+ varfilter_globals->no_more_post_variables = 0;
2891+ varfilter_globals->no_more_cookie_variables = 0;
2892+ varfilter_globals->no_more_uploads = 0;
2893+}
2894+/* }}} */
2895+
2896+/* {{{ PHP_MINIT_FUNCTION
2897+ */
2898+PHP_MINIT_FUNCTION(varfilter)
2899+{
2900+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2901+ REGISTER_INI_ENTRIES();
2902+
2903+ sapi_register_input_filter(varfilter_input_filter);
2904+ sapi_register_upload_varname_filter(varfilter_upload_varname_filter);
2905+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
2906+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
2907+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
2908+
2909+ return SUCCESS;
2910+}
2911+/* }}} */
2912+
2913+/* {{{ PHP_MSHUTDOWN_FUNCTION
2914+ */
2915+PHP_MSHUTDOWN_FUNCTION(varfilter)
2916+{
2917+ UNREGISTER_INI_ENTRIES();
2918+
2919+ return SUCCESS;
2920+}
2921+/* }}} */
2922+
2923+/* Remove if there's nothing to do at request start */
2924+/* {{{ PHP_RINIT_FUNCTION
2925+ */
2926+PHP_RINIT_FUNCTION(varfilter)
2927+{
2928+ VARFILTER_G(cur_request_variables) = 0;
2929+ VARFILTER_G(cur_get_vars) = 0;
2930+ VARFILTER_G(cur_post_vars) = 0;
2931+ VARFILTER_G(cur_cookie_vars) = 0;
2932+
2933+ VARFILTER_G(cur_uploads) = 0;
2934+
2935+ VARFILTER_G(no_more_variables) = 0;
2936+ VARFILTER_G(no_more_get_variables) = 0;
2937+ VARFILTER_G(no_more_post_variables) = 0;
2938+ VARFILTER_G(no_more_cookie_variables) = 0;
2939+ VARFILTER_G(no_more_uploads) = 0;
2940+
2941+ return SUCCESS;
2942+}
2943+/* }}} */
2944+
2945+/* Remove if there's nothing to do at request end */
2946+/* {{{ PHP_RSHUTDOWN_FUNCTION
2947+ */
2948+PHP_RSHUTDOWN_FUNCTION(varfilter)
2949+{
2950+ return SUCCESS;
2951+}
2952+/* }}} */
2953+
2954+/* {{{ PHP_MINFO_FUNCTION
2955+ */
2956+PHP_MINFO_FUNCTION(varfilter)
2957+{
2958+ php_info_print_table_start();
2959+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
2960+ php_info_print_table_end();
2961+
2962+ DISPLAY_INI_ENTRIES();
2963+}
2964+/* }}} */
2965+
2966+/* {{{ normalize_varname
2967+ */
2968+static void normalize_varname(char *varname)
2969+{
2970+ char *s=varname, *index=NULL, *indexend=NULL, *p;
2971+
2972+ /* overjump leading space */
2973+ while (*s == ' ') {
2974+ s++;
2975+ }
2976+
2977+ /* and remove it */
2978+ if (s != varname) {
2979+ memmove(varname, s, strlen(s)+1);
2980+ }
2981+
2982+ for (p=varname; *p && *p != '['; p++) {
2983+ switch(*p) {
2984+ case ' ':
2985+ case '.':
2986+ *p='_';
2987+ break;
2988+ }
2989+ }
2990+
2991+ /* find index */
2992+ index = strchr(varname, '[');
2993+ if (index) {
2994+ index++;
2995+ s=index;
2996+ } else {
2997+ return;
2998+ }
2999+
3000+ /* done? */
3001+ while (index) {
3002+
3003+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
3004+ index++;
3005+ }
3006+ indexend = strchr(index, ']');
3007+ indexend = indexend ? indexend + 1 : index + strlen(index);
3008+
3009+ if (s != index) {
3010+ memmove(s, index, strlen(index)+1);
3011+ s += indexend-index;
3012+ } else {
3013+ s = indexend;
3014+ }
3015+
3016+ if (*s == '[') {
3017+ s++;
3018+ index = s;
3019+ } else {
3020+ index = NULL;
3021+ }
3022+ }
3023+ *s++='\0';
3024+}
3025+/* }}} */
3026+
3027+/* {{{ SAPI_UPLOAD_VARNAME_FILTER_FUNC
3028+ */
3029+SAPI_UPLOAD_VARNAME_FILTER_FUNC(varfilter_upload_varname_filter)
3030+{
3031+ char *index, *prev_index = NULL, *var;
3032+ unsigned int var_len, total_len, depth = 0;
3033+
3034+ var = estrdup(varname);
3035+
3036+ /* Normalize the variable name */
3037+ normalize_varname(var);
3038+
3039+ /* Find length of variable name */
3040+ index = strchr(var, '[');
3041+ total_len = strlen(var);
3042+ var_len = index ? index-var : total_len;
3043+
3044+ /* Drop this variable if it exceeds the varname/total length limit */
3045+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3046+ php_security_log(S_FILES, "configured request variable name length limit exceeded - dropped %s", var);
3047+ goto return_failure;
3048+ }
3049+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3050+ php_security_log(S_FILES, "configured request variable total name length limit exceeded - dropped %s", var);
3051+ goto return_failure;
3052+ }
3053+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3054+ php_security_log(S_FILES, "configured POST variable name length limit exceeded - dropped %s", var);
3055+
3056+ goto return_failure;
3057+ }
3058+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3059+ php_security_log(S_FILES, "configured POST variable total name length limit exceeded - dropped %s", var);
3060+ goto return_failure;
3061+ }
3062+
3063+ /* Find out array depth */
3064+ while (index) {
3065+ unsigned int index_length;
3066+
3067+ depth++;
3068+ index = strchr(index+1, '[');
3069+
3070+ if (prev_index) {
3071+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3072+
3073+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3074+ php_security_log(S_FILES, "configured request variable array index length limit exceeded - dropped %s", var);
3075+ goto return_failure;
3076+ }
3077+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3078+ php_security_log(S_FILES, "configured POST variable array index length limit exceeded - dropped %s", var);
3079+ goto return_failure;
3080+ }
3081+ prev_index = index;
3082+ }
3083+
3084+ }
3085+
3086+ /* Drop this variable if it exceeds the array depth limit */
3087+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3088+ php_security_log(S_FILES, "configured request variable array depth limit exceeded - dropped %s", var);
3089+ goto return_failure;
3090+ }
3091+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3092+ php_security_log(S_FILES, "configured POST variable array depth limit exceeded - dropped %s", var);
3093+ goto return_failure;
3094+ }
3095+
3096+
3097+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3098+ /* This is to protect several silly scripts that do globalizing themself */
3099+
3100+ switch (var_len) {
3101+ case 18:
3102+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname2;
3103+ break;
3104+ case 17:
3105+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname2;
3106+ break;
3107+ case 16:
3108+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname2;
3109+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname2;
3110+ break;
3111+ case 15:
3112+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname2;
3113+ break;
3114+ case 14:
3115+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname2;
3116+ break;
3117+ case 13:
3118+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname2;
3119+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname2;
3120+ break;
3121+ case 8:
3122+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname2;
3123+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname2;
3124+ break;
3125+ case 7:
3126+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname2;
3127+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname2;
3128+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname2;
3129+ break;
3130+ case 6:
3131+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname2;
3132+ break;
3133+ case 5:
3134+ if (memcmp(var, "_POST", 5)==0) goto protected_varname2;
3135+ break;
3136+ case 4:
3137+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname2;
3138+ if (memcmp(var, "_GET", 4)==0) goto protected_varname2;
3139+ break;
3140+ }
3141+
3142+ efree(var);
3143+ return SUCCESS;
3144+protected_varname2:
3145+ php_security_log(S_FILES, "tried to register forbidden variable '%s' through FILE variables", var);
3146+return_failure:
3147+ efree(var);
3148+ return FAILURE;
3149+}
3150+/* }}} */
3151+
3152+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
3153+ */
3154+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
3155+{
3156+ /* Drop if no more variables flag is set */
3157+ if (VARFILTER_G(no_more_uploads)) {
3158+ return FAILURE;
3159+ }
3160+ /* Drop this fileupload if the limit is reached */
3161+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
3162+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
3163+ VARFILTER_G(no_more_uploads) = 1;
3164+ return FAILURE;
3165+ }
3166+
3167+ return SUCCESS;
3168+}
3169+/* }}} */
3170+
3171+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
3172+ */
3173+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
3174+{
3175+
3176+ if (VARFILTER_G(disallow_elf_files)) {
3177+
3178+ if (offset == 0 && buffer_len > 10) {
3179+
3180+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
3181+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
3182+ return FAILURE;
3183+ }
3184+ }
3185+
3186+ }
3187+
3188+ return SUCCESS;
3189+}
3190+/* }}} */
3191+
3192+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
3193+ */
3194+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
3195+{
3196+ int retval = SUCCESS;
3197+
3198+ if (VARFILTER_G(verification_script)) {
3199+ char cmd[8192];
3200+ FILE *in;
3201+ int first=1;
3202+
3203+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
3204+
3205+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3206+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
3207+ return FAILURE;
3208+ }
3209+
3210+ retval = FAILURE;
3211+
3212+ /* read and forget the result */
3213+ while (1) {
3214+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3215+ if (readbytes<=0) {
3216+ break;
3217+ }
3218+ if (first) {
3219+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
3220+ first = 0;
3221+ }
3222+ }
3223+ pclose(in);
3224+ }
3225+
3226+ if (retval != SUCCESS) {
3227+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
3228+ return FAILURE;
3229+ }
3230+
3231+ VARFILTER_G(cur_uploads)++;
3232+ return SUCCESS;
3233+}
3234+/* }}} */
3235+
3236+/* {{{ SAPI_INPUT_FILTER_FUNC
3237+ */
3238+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
3239+{
3240+ char *index, *prev_index = NULL;
3241+ unsigned int var_len, total_len, depth = 0;
3242+
3243+ /* Drop this variable if the limit was reached */
3244+ switch (arg) {
3245+ case PARSE_GET:
3246+ if (VARFILTER_G(no_more_get_variables)) {
3247+ return 0;
3248+ }
3249+ break;
3250+ case PARSE_POST:
3251+ if (VARFILTER_G(no_more_post_variables)) {
3252+ return 0;
3253+ }
3254+ break;
3255+ case PARSE_COOKIE:
3256+ if (VARFILTER_G(no_more_cookie_variables)) {
3257+ return 0;
3258+ }
3259+ break;
3260+ }
3261+ if (VARFILTER_G(no_more_variables)) {
3262+ return 0;
3263+ }
3264+
3265+ /* Drop this variable if the limit is now reached */
3266+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
3267+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
3268+ VARFILTER_G(no_more_variables) = 1;
3269+ return 0;
3270+ }
3271+ switch (arg) {
3272+ case PARSE_GET:
3273+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
3274+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
3275+ VARFILTER_G(no_more_get_variables) = 1;
3276+ return 0;
3277+ }
3278+ break;
3279+ case PARSE_COOKIE:
3280+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
3281+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
3282+ VARFILTER_G(no_more_cookie_variables) = 1;
3283+ return 0;
3284+ }
3285+ break;
3286+ case PARSE_POST:
3287+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
3288+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
3289+ VARFILTER_G(no_more_post_variables) = 1;
3290+ return 0;
3291+ }
3292+ break;
3293+ }
3294+
3295+
3296+ /* Drop this variable if it exceeds the value length limit */
3297+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
3298+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
3299+ return 0;
3300+ }
3301+ switch (arg) {
3302+ case PARSE_GET:
3303+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
3304+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
3305+ return 0;
3306+ }
3307+ break;
3308+ case PARSE_COOKIE:
3309+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3310+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3311+ return 0;
3312+ }
3313+ break;
3314+ case PARSE_POST:
3315+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3316+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3317+ return 0;
3318+ }
3319+ break;
3320+ }
3321+
3322+ /* Normalize the variable name */
3323+ normalize_varname(var);
3324+
3325+ /* Find length of variable name */
3326+ index = strchr(var, '[');
3327+ total_len = strlen(var);
3328+ var_len = index ? index-var : total_len;
3329+
3330+ /* Drop this variable if it exceeds the varname/total length limit */
3331+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3332+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3333+ return 0;
3334+ }
3335+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3336+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3337+ return 0;
3338+ }
3339+ switch (arg) {
3340+ case PARSE_GET:
3341+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3342+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3343+ return 0;
3344+ }
3345+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3346+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3347+ return 0;
3348+ }
3349+ break;
3350+ case PARSE_COOKIE:
3351+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3352+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3353+ return 0;
3354+ }
3355+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3356+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3357+ return 0;
3358+ }
3359+ break;
3360+ case PARSE_POST:
3361+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3362+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3363+ return 0;
3364+ }
3365+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3366+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3367+ return 0;
3368+ }
3369+ break;
3370+ }
3371+
3372+ /* Find out array depth */
3373+ while (index) {
3374+ unsigned int index_length;
3375+
3376+ depth++;
3377+ index = strchr(index+1, '[');
3378+
3379+ if (prev_index) {
3380+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3381+
3382+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3383+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3384+ return 0;
3385+ }
3386+ switch (arg) {
3387+ case PARSE_GET:
3388+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3389+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3390+ return 0;
3391+ }
3392+ break;
3393+ case PARSE_COOKIE:
3394+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3395+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3396+ return 0;
3397+ }
3398+ break;
3399+ case PARSE_POST:
3400+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3401+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3402+ return 0;
3403+ }
3404+ break;
3405+ }
3406+ prev_index = index;
3407+ }
3408+
3409+ }
3410+
3411+ /* Drop this variable if it exceeds the array depth limit */
3412+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3413+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3414+ return 0;
3415+ }
3416+ switch (arg) {
3417+ case PARSE_GET:
3418+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3419+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3420+ return 0;
3421+ }
3422+ break;
3423+ case PARSE_COOKIE:
3424+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3425+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3426+ return 0;
3427+ }
3428+ break;
3429+ case PARSE_POST:
3430+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3431+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3432+ return 0;
3433+ }
3434+ break;
3435+ }
3436+
3437+ /* Check if variable value is truncated by a \0 */
3438+
3439+ if (val && *val && val_len != strlen(*val)) {
3440+
3441+ if (VARFILTER_G(disallow_nul)) {
3442+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within request variables - dropped %s", var);
3443+ return 0;
3444+ }
3445+ switch (arg) {
3446+ case PARSE_GET:
3447+ if (VARFILTER_G(disallow_get_nul)) {
3448+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within GET variables - dropped %s", var);
3449+ return 0;
3450+ }
3451+ break;
3452+ case PARSE_COOKIE:
3453+ if (VARFILTER_G(disallow_cookie_nul)) {
3454+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within COOKIE variables - dropped %s", var);
3455+ return 0;
3456+ }
3457+ break;
3458+ case PARSE_POST:
3459+ if (VARFILTER_G(disallow_post_nul)) {
3460+ php_security_log(S_VARS, "ASCII-NUL chars not allowed within POST variables - dropped %s", var);
3461+ return 0;
3462+ }
3463+ break;
3464+ }
3465+ }
3466+
3467+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3468+ /* This is to protect several silly scripts that do globalizing themself */
3469+
3470+ switch (var_len) {
3471+ case 18:
3472+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3473+ break;
3474+ case 17:
3475+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3476+ break;
3477+ case 16:
3478+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3479+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3480+ break;
3481+ case 15:
3482+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3483+ break;
3484+ case 14:
3485+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3486+ break;
3487+ case 13:
3488+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3489+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3490+ break;
3491+ case 8:
3492+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3493+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3494+ break;
3495+ case 7:
3496+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3497+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3498+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3499+ break;
3500+ case 6:
3501+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3502+ break;
3503+ case 5:
3504+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3505+ break;
3506+ case 4:
3507+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3508+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3509+ break;
3510+ }
3511+
3512+ /* Okay let PHP register this variable */
3513+ VARFILTER_G(cur_request_variables)++;
3514+ switch (arg) {
3515+ case PARSE_GET:
3516+ VARFILTER_G(cur_get_vars)++;
3517+ break;
3518+ case PARSE_COOKIE:
3519+ VARFILTER_G(cur_cookie_vars)++;
3520+ break;
3521+ case PARSE_POST:
3522+ VARFILTER_G(cur_post_vars)++;
3523+ break;
3524+ }
3525+
3526+ if (new_val_len) {
3527+ *new_val_len = val_len;
3528+ }
3529+
3530+ return 1;
3531+protected_varname:
3532+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3533+ return 0;
3534+}
3535+/* }}} */
3536+
3537+/*
3538+ * Local variables:
3539+ * tab-width: 4
3540+ * c-basic-offset: 4
3541+ * End:
3542+ * vim600: noet sw=4 ts=4 fdm=marker
3543+ * vim<600: noet sw=4 ts=4
3544+ */
3545+
3546+
3547diff -Nura php-5.0.5/main/fopen_wrappers.c hardening-patch-5.0.5-0.4.5/main/fopen_wrappers.c
3548--- php-5.0.5/main/fopen_wrappers.c 2005-07-16 14:14:44.000000000 +0200
3549+++ hardening-patch-5.0.5-0.4.5/main/fopen_wrappers.c 2005-11-01 14:47:47.866978168 +0100
3550@@ -109,8 +109,8 @@
3551 /* Handler for basedirs that end with a / */
3552 resolved_basedir_len = strlen(resolved_basedir);
3553 if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
3554- if (resolved_basedir[resolved_basedir_len - 1] == '/') {
3555- resolved_basedir[resolved_basedir_len - 1] = PHP_DIR_SEPARATOR;
3556+ if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
3557+ resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
3558 resolved_basedir[++resolved_basedir_len] = '\0';
3559 }
3560 }
3561@@ -155,6 +155,21 @@
3562 char *pathbuf;
3563 char *ptr;
3564 char *end;
3565+ char path_copy[MAXPATHLEN];
3566+ int path_len;
3567+
3568+ /* Special case path ends with a trailing slash */
3569+ path_len = strlen(path);
3570+ if (path_len >= MAXPATHLEN) {
3571+ errno = EPERM; /* we deny permission to open it */
3572+ return -1;
3573+ }
3574+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3575+ memcpy(path_copy, path, path_len+1);
3576+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3577+ path_copy[path_len] = '\0';
3578+ path = (const char *)&path_copy;
3579+ }
3580
3581 pathbuf = estrdup(PG(open_basedir));
3582
3583diff -Nura php-5.0.5/main/hardened_globals.h hardening-patch-5.0.5-0.4.5/main/hardened_globals.h
3584--- php-5.0.5/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3585+++ hardening-patch-5.0.5-0.4.5/main/hardened_globals.h 2005-11-01 14:23:05.950263752 +0100
3586@@ -0,0 +1,62 @@
3587+/*
3588+ +----------------------------------------------------------------------+
3589+ | Hardening-Patch for PHP |
3590+ +----------------------------------------------------------------------+
3591+ | Copyright (c) 2004-2005 Stefan Esser |
3592+ +----------------------------------------------------------------------+
3593+ | This source file is subject to version 2.02 of the PHP license, |
3594+ | that is bundled with this package in the file LICENSE, and is |
3595+ | available at through the world-wide-web at |
3596+ | http://www.php.net/license/2_02.txt. |
3597+ | If you did not receive a copy of the PHP license and are unable to |
3598+ | obtain it through the world-wide-web, please send a note to |
3599+ | license@php.net so we can mail you a copy immediately. |
3600+ +----------------------------------------------------------------------+
3601+ | Author: Stefan Esser <sesser@hardened-php.net> |
3602+ +----------------------------------------------------------------------+
3603+ */
3604+
3605+#ifndef HARDENED_GLOBALS_H
3606+#define HARDENED_GLOBALS_H
3607+
3608+typedef struct _hardened_globals hardened_globals_struct;
3609+
3610+#ifdef ZTS
3611+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3612+extern int hardened_globals_id;
3613+#else
3614+# define HG(v) (hardened_globals.v)
3615+extern struct _hardened_globals hardened_globals;
3616+#endif
3617+
3618+
3619+struct _hardened_globals {
3620+#if HARDENING_PATCH_MM_PROTECT
3621+ unsigned int canary_1;
3622+ unsigned int canary_2;
3623+#endif
3624+#if HARDENING_PATCH_LL_PROTECT
3625+ unsigned int canary_3;
3626+ unsigned int canary_4;
3627+ unsigned int ll_canary_inited;
3628+#endif
3629+ zend_bool hphp_sql_bailout_on_error;
3630+ zend_bool hphp_multiheader;
3631+ HashTable *eval_whitelist;
3632+ HashTable *eval_blacklist;
3633+ HashTable *func_whitelist;
3634+ HashTable *func_blacklist;
3635+ HashTable *include_whitelist;
3636+ HashTable *include_blacklist;
3637+ unsigned int dummy;
3638+};
3639+
3640+
3641+#endif /* HARDENED_GLOBALS_H */
3642+
3643+/*
3644+ * Local variables:
3645+ * tab-width: 4
3646+ * c-basic-offset: 4
3647+ * End:
3648+ */
3649diff -Nura php-5.0.5/main/hardening_patch.c hardening-patch-5.0.5-0.4.5/main/hardening_patch.c
3650--- php-5.0.5/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
3651+++ hardening-patch-5.0.5-0.4.5/main/hardening_patch.c 2005-11-01 17:50:42.123637568 +0100
3652@@ -0,0 +1,430 @@
3653+/*
3654+ +----------------------------------------------------------------------+
3655+ | Hardening Patch for PHP |
3656+ +----------------------------------------------------------------------+
3657+ | Copyright (c) 2004-2005 Stefan Esser |
3658+ +----------------------------------------------------------------------+
3659+ | This source file is subject to version 2.02 of the PHP license, |
3660+ | that is bundled with this package in the file LICENSE, and is |
3661+ | available at through the world-wide-web at |
3662+ | http://www.php.net/license/2_02.txt. |
3663+ | If you did not receive a copy of the PHP license and are unable to |
3664+ | obtain it through the world-wide-web, please send a note to |
3665+ | license@php.net so we can mail you a copy immediately. |
3666+ +----------------------------------------------------------------------+
3667+ | Author: Stefan Esser <sesser@hardened-php.net> |
3668+ +----------------------------------------------------------------------+
3669+ */
3670+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
3671+
3672+#include "php.h"
3673+
3674+#include <stdio.h>
3675+#include <stdlib.h>
3676+
3677+#if HAVE_UNISTD_H
3678+#include <unistd.h>
3679+#endif
3680+#include "SAPI.h"
3681+#include "php_globals.h"
3682+
3683+#if HARDENING_PATCH
3684+
3685+#ifdef HAVE_SYS_SOCKET_H
3686+#include <sys/socket.h>
3687+#endif
3688+
3689+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
3690+#undef AF_UNIX
3691+#endif
3692+
3693+#if defined(AF_UNIX)
3694+#include <sys/un.h>
3695+#endif
3696+
3697+#define SYSLOG_PATH "/dev/log"
3698+
3699+#include "snprintf.h"
3700+
3701+#include "hardening_patch.h"
3702+
3703+#ifdef ZTS
3704+#include "hardened_globals.h"
3705+int hardened_globals_id;
3706+#else
3707+struct _hardened_globals hardened_globals;
3708+#endif
3709+
3710+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
3711+{
3712+ memset(hardened_globals, 0, sizeof(*hardened_globals));
3713+}
3714+
3715+
3716+PHPAPI void hardened_startup()
3717+{
3718+#ifdef ZTS
3719+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
3720+#else
3721+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
3722+#endif
3723+}
3724+
3725+PHPAPI void hardened_clear_mm_canaries(TSRMLS_D)
3726+{
3727+ HG(canary_1) = php_canary();
3728+ HG(canary_2) = php_canary();
3729+}
3730+
3731+char *loglevel2string(int loglevel)
3732+{
3733+ switch (loglevel) {
3734+ case S_FILES:
3735+ return "FILES";
3736+ case S_INCLUDE:
3737+ return "INCLUDE";
3738+ case S_MEMORY:
3739+ return "MEMORY";
3740+ case S_MISC:
3741+ return "MISC";
3742+ case S_SQL:
3743+ return "SQL";
3744+ case S_EXECUTOR:
3745+ return "EXECUTOR";
3746+ case S_VARS:
3747+ return "VARS";
3748+ default:
3749+ return "UNKNOWN";
3750+ }
3751+}
3752+
3753+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
3754+{
3755+#if defined(AF_UNIX)
3756+ int s, r, i=0;
3757+ struct sockaddr_un saun;
3758+ char buf[4096+64];
3759+ char error[4096+100];
3760+ char *ip_address;
3761+ char *fname;
3762+ int lineno;
3763+ va_list ap;
3764+ TSRMLS_FETCH();
3765+
3766+ if (EG(hphp_log_use_x_forwarded_for)) {
3767+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
3768+ if (ip_address == NULL) {
3769+ ip_address = "X-FORWARDED-FOR not set";
3770+ }
3771+ } else {
3772+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
3773+ if (ip_address == NULL) {
3774+ ip_address = "REMOTE_ADDR not set";
3775+ }
3776+ }
3777+
3778+
3779+ va_start(ap, fmt);
3780+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
3781+ va_end(ap);
3782+ while (error[i]) {
3783+ if (error[i] < 32) error[i] = '.';
3784+ i++;
3785+ }
3786+
3787+ if (zend_is_executing(TSRMLS_C)) {
3788+ lineno = zend_get_executed_lineno(TSRMLS_C);
3789+ fname = zend_get_executed_filename(TSRMLS_C);
3790+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
3791+ } else {
3792+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
3793+ if (fname==NULL) {
3794+ fname = "unknown";
3795+ }
3796+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
3797+ }
3798+
3799+ /* Syslog-Logging disabled? */
3800+ if ((EG(hphp_log_syslog) & loglevel)==0) {
3801+ goto log_sapi;
3802+ }
3803+
3804+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
3805+
3806+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
3807+ if (s == -1) {
3808+ goto log_sapi;
3809+ }
3810+
3811+ memset(&saun, 0, sizeof(saun));
3812+ saun.sun_family = AF_UNIX;
3813+ strcpy(saun.sun_path, SYSLOG_PATH);
3814+ /*saun.sun_len = sizeof(saun);*/
3815+
3816+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3817+ if (r) {
3818+ close(s);
3819+ s = socket(AF_UNIX, SOCK_STREAM, 0);
3820+ if (s == -1) {
3821+ goto log_sapi;
3822+ }
3823+
3824+ memset(&saun, 0, sizeof(saun));
3825+ saun.sun_family = AF_UNIX;
3826+ strcpy(saun.sun_path, SYSLOG_PATH);
3827+ /*saun.sun_len = sizeof(saun);*/
3828+
3829+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3830+ if (r) {
3831+ close(s);
3832+ goto log_sapi;
3833+ }
3834+ }
3835+ send(s, error, strlen(error), 0);
3836+
3837+ close(s);
3838+
3839+log_sapi:
3840+ /* SAPI Logging activated? */
3841+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
3842+ sapi_module.log_message(buf);
3843+ }
3844+
3845+log_script:
3846+ /* script logging activaed? */
3847+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
3848+ char cmd[8192], *cmdpos, *bufpos;
3849+ FILE *in;
3850+ int space;
3851+
3852+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
3853+ space = sizeof(cmd) - strlen(cmd);
3854+ cmdpos = cmd + strlen(cmd);
3855+ bufpos = buf;
3856+ if (space <= 1) return;
3857+ while (space > 2 && *bufpos) {
3858+ if (*bufpos == '\'') {
3859+ if (space<=5) break;
3860+ *cmdpos++ = '\'';
3861+ *cmdpos++ = '\\';
3862+ *cmdpos++ = '\'';
3863+ *cmdpos++ = '\'';
3864+ bufpos++;
3865+ space-=4;
3866+ } else {
3867+ *cmdpos++ = *bufpos++;
3868+ space--;
3869+ }
3870+ }
3871+ *cmdpos++ = '\'';
3872+ *cmdpos = 0;
3873+
3874+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3875+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
3876+ return;
3877+ }
3878+ /* read and forget the result */
3879+ while (1) {
3880+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3881+ if (readbytes<=0) {
3882+ break;
3883+ }
3884+ }
3885+ pclose(in);
3886+ }
3887+
3888+#endif
3889+}
3890+#endif
3891+
3892+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3893+
3894+/* will be replaced later with more compatible method */
3895+PHPAPI unsigned int php_canary()
3896+{
3897+ time_t t;
3898+ unsigned int canary;
3899+ int fd;
3900+
3901+ fd = open("/dev/urandom", 0);
3902+ if (fd != -1) {
3903+ int r = read(fd, &canary, sizeof(canary));
3904+ close(fd);
3905+ if (r == sizeof(canary)) {
3906+ return (canary);
3907+ }
3908+ }
3909+ /* not good but we never want to do this */
3910+ time(&t);
3911+ canary = *(unsigned int *)&t + getpid() << 16;
3912+ return (canary);
3913+}
3914+#endif
3915+
3916+#if HARDENING_PATCH_INC_PROTECT
3917+
3918+PHPAPI int php_is_valid_include(zval *z)
3919+{
3920+ char *filename;
3921+ int len, i;
3922+ TSRMLS_FETCH();
3923+
3924+ /* must be of type string */
3925+ if (z->type != IS_STRING || z->value.str.val == NULL) {
3926+ return (0);
3927+ }
3928+
3929+ /* short cut */
3930+ filename = z->value.str.val;
3931+ len = z->value.str.len;
3932+
3933+ /* 1. must be shorter than MAXPATHLEN */
3934+ if (len > MAXPATHLEN) {
3935+ char *fname = estrndup(filename, len);
3936+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3937+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
3938+ efree(fname);
3939+ return (0);
3940+ }
3941+
3942+ /* 2. must not be cutted */
3943+ if (len != strlen(filename)) {
3944+ char *fname = estrndup(filename, len);
3945+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
3946+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
3947+ efree(fname);
3948+ return (0);
3949+ }
3950+
3951+ /* 3. when it is an URL first check black/whitelist if both are empty disallow all URLs */
3952+ if (strstr(filename, "://")) {
3953+ char *fname = estrndup(filename, len);
3954+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3955+
3956+ /* no black or whitelist then disallow all */
3957+ if (HG(include_whitelist)==NULL && HG(include_blacklist)==NULL) {
3958+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
3959+ efree(fname);
3960+ return (0);
3961+ }
3962+
3963+ /* whitelist is stronger than blacklist */
3964+ if (HG(include_whitelist)) {
3965+ char *s, *t, *h, *index;
3966+ uint indexlen;
3967+ ulong numindex;
3968+
3969+ s = filename;
3970+
3971+ do {
3972+ zend_bool isOk = 0;
3973+ int tlen;
3974+
3975+ t = h = strstr(s, "://");
3976+ if (h == NULL) break;
3977+
3978+
3979+ while (t > s && (isalnum(t[-1]) || t[-1]=='_')) {
3980+ t--;
3981+ }
3982+
3983+ tlen = strlen(t);
3984+
3985+ zend_hash_internal_pointer_reset(HG(include_whitelist));
3986+ do {
3987+ int r = zend_hash_get_current_key_ex(HG(include_whitelist), &index, &indexlen, &numindex, 0, NULL);
3988+
3989+ if (r==HASH_KEY_NON_EXISTANT) {
3990+ break;
3991+ }
3992+ if (r==HASH_KEY_IS_STRING) {
3993+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
3994+ if (strncmp(t, index, indexlen-1)==0) {
3995+ isOk = 1;
3996+ break;
3997+ }
3998+ }
3999+ }
4000+
4001+ zend_hash_move_forward(HG(include_whitelist));
4002+ } while (1);
4003+
4004+ /* not found in whitelist */
4005+ if (!isOk) {
4006+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is not allowed in whitelist", fname);
4007+ efree(fname);
4008+ return 0;
4009+ }
4010+
4011+ s = h + 3;
4012+ } while (1);
4013+ } else {
4014+ /* okay then handle the blacklist */
4015+ char *s, *t, *h, *index;
4016+ uint indexlen;
4017+ ulong numindex;
4018+
4019+ s = filename;
4020+
4021+ do {
4022+ int tlen;
4023+
4024+ t = h = strstr(s, "://");
4025+ if (h == NULL) break;
4026+
4027+
4028+ while (t > s) {
4029+ if (isalnum(t[-1]) || t[-1]=='_') t--;
4030+ }
4031+
4032+ tlen = strlen(t);
4033+
4034+ zend_hash_internal_pointer_reset(HG(include_blacklist));
4035+ do {
4036+ int r = zend_hash_get_current_key_ex(HG(include_blacklist), &index, &indexlen, &numindex, 0, NULL);
4037+
4038+ if (r==HASH_KEY_NON_EXISTANT) {
4039+ break;
4040+ }
4041+ if (r==HASH_KEY_IS_STRING) {
4042+ if (h-t <= indexlen-1 && tlen>=indexlen-1) {
4043+ if (strncmp(t, index, indexlen-1)==0) {
4044+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL that is forbidden by the blacklist", fname);
4045+ efree(fname);
4046+ return 0;
4047+ }
4048+ }
4049+ }
4050+
4051+ zend_hash_move_forward(HG(include_blacklist));
4052+ } while (1);
4053+
4054+ s = h + 3;
4055+ } while (1);
4056+ }
4057+
4058+ efree(fname);
4059+ }
4060+
4061+ /* 4. must not be an uploaded file */
4062+ if (SG(rfc1867_uploaded_files)) {
4063+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
4064+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
4065+ return (0);
4066+ }
4067+ }
4068+
4069+ /* passed all tests */
4070+ return (1);
4071+}
4072+
4073+#endif
4074+
4075+/*
4076+ * Local variables:
4077+ * tab-width: 4
4078+ * c-basic-offset: 4
4079+ * End:
4080+ * vim600: sw=4 ts=4 fdm=marker
4081+ * vim<600: sw=4 ts=4
4082+ */
4083diff -Nura php-5.0.5/main/hardening_patch.h hardening-patch-5.0.5-0.4.5/main/hardening_patch.h
4084--- php-5.0.5/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
4085+++ hardening-patch-5.0.5-0.4.5/main/hardening_patch.h 2005-11-01 14:23:19.000000000 +0100
4086@@ -0,0 +1,46 @@
4087+/*
4088+ +----------------------------------------------------------------------+
4089+ | Hardening Patch for PHP |
4090+ +----------------------------------------------------------------------+
4091+ | Copyright (c) 2004-2005 Stefan Esser |
4092+ +----------------------------------------------------------------------+
4093+ | This source file is subject to version 2.02 of the PHP license, |
4094+ | that is bundled with this package in the file LICENSE, and is |
4095+ | available at through the world-wide-web at |
4096+ | http://www.php.net/license/2_02.txt. |
4097+ | If you did not receive a copy of the PHP license and are unable to |
4098+ | obtain it through the world-wide-web, please send a note to |
4099+ | license@php.net so we can mail you a copy immediately. |
4100+ +----------------------------------------------------------------------+
4101+ | Author: Stefan Esser <sesser@hardened-php.net> |
4102+ +----------------------------------------------------------------------+
4103+ */
4104+
4105+#ifndef HARDENING_PATCH_H
4106+#define HARDENING_PATCH_H
4107+
4108+#include "zend.h"
4109+
4110+#if HARDENING_PATCH
4111+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
4112+PHPAPI void hardened_startup();
4113+#define HARDENING_PATCH_VERSION "0.4.5"
4114+
4115+#endif
4116+
4117+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
4118+PHPAPI unsigned int php_canary();
4119+#endif
4120+
4121+#if HARDENING_PATCH_INC_PROTECT
4122+PHPAPI int php_is_valid_include(zval *z);
4123+#endif
4124+
4125+#endif /* HARDENING_PATCH_H */
4126+
4127+/*
4128+ * Local variables:
4129+ * tab-width: 4
4130+ * c-basic-offset: 4
4131+ * End:
4132+ */
4133diff -Nura php-5.0.5/main/hardening_patch.m4 hardening-patch-5.0.5-0.4.5/main/hardening_patch.m4
4134--- php-5.0.5/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
4135+++ hardening-patch-5.0.5-0.4.5/main/hardening_patch.m4 2005-11-01 14:23:05.951263600 +0100
4136@@ -0,0 +1,95 @@
4137+dnl
4138+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
4139+dnl
4140+dnl This file contains Hardening Patch for PHP specific autoconf functions.
4141+dnl
4142+
4143+AC_ARG_ENABLE(hardening-patch-mm-protect,
4144+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
4145+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
4146+],[
4147+ DO_HARDENING_PATCH_MM_PROTECT=yes
4148+])
4149+
4150+AC_ARG_ENABLE(hardening-patch-ll-protect,
4151+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
4152+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
4153+],[
4154+ DO_HARDENING_PATCH_LL_PROTECT=yes
4155+])
4156+
4157+AC_ARG_ENABLE(hardening-patch-inc-protect,
4158+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
4159+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
4160+],[
4161+ DO_HARDENING_PATCH_INC_PROTECT=yes
4162+])
4163+
4164+AC_ARG_ENABLE(hardening-patch-fmt-protect,
4165+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
4166+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
4167+],[
4168+ DO_HARDENING_PATCH_FMT_PROTECT=yes
4169+])
4170+
4171+AC_ARG_ENABLE(hardening-patch-hash-protect,
4172+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
4173+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
4174+],[
4175+ DO_HARDENING_PATCH_HASH_PROTECT=yes
4176+])
4177+
4178+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
4179+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
4180+
4181+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
4182+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
4183+
4184+AC_MSG_CHECKING(whether to protect include/require statements)
4185+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
4186+
4187+AC_MSG_CHECKING(whether to protect PHP Format String functions)
4188+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
4189+
4190+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
4191+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
4192+
4193+
4194+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4195+
4196+
4197+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
4198+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4199+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
4200+else
4201+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
4202+fi
4203+
4204+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
4205+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4206+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
4207+else
4208+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
4209+fi
4210+
4211+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
4212+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4213+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
4214+else
4215+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
4216+fi
4217+
4218+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
4219+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4220+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
4221+else
4222+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
4223+fi
4224+
4225+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
4226+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
4227+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
4228+else
4229+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
4230+fi
4231+
4232diff -Nura php-5.0.5/main/main.c hardening-patch-5.0.5-0.4.5/main/main.c
4233--- php-5.0.5/main/main.c 2005-08-16 20:11:34.000000000 +0200
4234+++ hardening-patch-5.0.5-0.4.5/main/main.c 2005-11-01 16:40:48.000000000 +0100
4235@@ -85,6 +85,10 @@
4236
4237 #include "SAPI.h"
4238 #include "rfc1867.h"
4239+#if HARDENING_PATCH
4240+#include "hardened_globals.h"
4241+#endif
4242+
4243 /* }}} */
4244
4245 #ifndef ZTS
4246@@ -109,10 +113,33 @@
4247 */
4248 static PHP_INI_MH(OnChangeMemoryLimit)
4249 {
4250+#if HARDENING_PATCH
4251+ long orig_memory_limit;
4252+
4253+ if (entry->modified) {
4254+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
4255+ } else {
4256+ orig_memory_limit = 1<<30;
4257+ }
4258+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
4259+ orig_memory_limit = 1<<30;
4260+ }
4261+#endif
4262 if (new_value) {
4263 PG(memory_limit) = zend_atoi(new_value, new_value_length);
4264+#if HARDENING_PATCH
4265+ if (PG(memory_limit) > orig_memory_limit) {
4266+ PG(memory_limit) = orig_memory_limit;
4267+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
4268+ return FAILURE;
4269+ }
4270+#endif
4271 } else {
4272+#if HARDENING_PATCH
4273+ PG(memory_limit) = orig_memory_limit;
4274+#else
4275 PG(memory_limit) = 1<<30; /* effectively, no limit */
4276+#endif
4277 }
4278 return zend_set_memory_limit(PG(memory_limit));
4279 }
4280@@ -1163,6 +1190,9 @@
4281
4282 zend_try {
4283 shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC);
4284+#if HARDENING_PATCH
4285+ hardened_clear_mm_canaries(TSRMLS_C);
4286+#endif
4287 } zend_end_try();
4288
4289 zend_try {
4290@@ -1322,6 +1352,10 @@
4291 tsrm_ls = ts_resource(0);
4292 #endif
4293
4294+#if HARDENING_PATCH
4295+ hardened_startup();
4296+#endif
4297+
4298 module_shutdown = 0;
4299 module_startup = 1;
4300 sapi_initialize_empty_request(TSRMLS_C);
4301@@ -1335,6 +1369,12 @@
4302
4303 php_output_startup();
4304
4305+#if HARDENING_PATCH_INC_PROTECT
4306+ zuf.is_valid_include = php_is_valid_include;
4307+#endif
4308+#if HARDENING_PATCH
4309+ zuf.security_log_function = php_security_log;
4310+#endif
4311 zuf.error_function = php_error_cb;
4312 zuf.printf_function = php_printf;
4313 zuf.write_function = php_body_write_wrapper;
4314@@ -1438,6 +1478,10 @@
4315 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
4316 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);
4317 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
4318+#if HARDENING_PATCH
4319+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
4320+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
4321+#endif
4322 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
4323 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
4324 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
4325diff -Nura php-5.0.5/main/php_config.h.in hardening-patch-5.0.5-0.4.5/main/php_config.h.in
4326--- php-5.0.5/main/php_config.h.in 2005-09-05 13:16:27.000000000 +0200
4327+++ hardening-patch-5.0.5-0.4.5/main/php_config.h.in 2005-11-01 14:23:05.953263296 +0100
4328@@ -752,6 +752,39 @@
4329 /* Enabling BIND8 compatibility for Panther */
4330 #undef BIND_8_COMPAT
4331
4332+/* Hardening-Patch for PHP */
4333+#undef HARDENING_PATCH
4334+
4335+/* Memory Manager Protection */
4336+#undef HARDENING_PATCH_MM_PROTECT
4337+
4338+/* Memory Manager Protection */
4339+#undef HARDENING_PATCH_MM_PROTECT
4340+
4341+/* Linked List Protection */
4342+#undef HARDENING_PATCH_LL_PROTECT
4343+
4344+/* Linked List Protection */
4345+#undef HARDENING_PATCH_LL_PROTECT
4346+
4347+/* Include/Require Protection */
4348+#undef HARDENING_PATCH_INC_PROTECT
4349+
4350+/* Include/Require Protection */
4351+#undef HARDENING_PATCH_INC_PROTECT
4352+
4353+/* Fmt String Protection */
4354+#undef HARDENING_PATCH_FMT_PROTECT
4355+
4356+/* Fmt String Protection */
4357+#undef HARDENING_PATCH_FMT_PROTECT
4358+
4359+/* HashTable DTOR Protection */
4360+#undef HARDENING_PATCH_HASH_PROTECT
4361+
4362+/* HashTable DTOR Protection */
4363+#undef HARDENING_PATCH_HASH_PROTECT
4364+
4365 /* Whether you have AOLserver */
4366 #undef HAVE_AOLSERVER
4367
4368@@ -1083,6 +1116,12 @@
4369 /* Define if you have the getaddrinfo function */
4370 #undef HAVE_GETADDRINFO
4371
4372+/* Whether realpath is broken */
4373+#undef PHP_BROKEN_REALPATH
4374+
4375+/* Whether realpath is broken */
4376+#undef PHP_BROKEN_REALPATH
4377+
4378 /* Whether system headers declare timezone */
4379 #undef HAVE_DECLARED_TIMEZONE
4380
4381diff -Nura php-5.0.5/main/php.h hardening-patch-5.0.5-0.4.5/main/php.h
4382--- php-5.0.5/main/php.h 2005-06-29 08:41:15.000000000 +0200
4383+++ hardening-patch-5.0.5-0.4.5/main/php.h 2005-11-01 14:23:05.954263144 +0100
4384@@ -35,11 +35,19 @@
4385 #include "zend_qsort.h"
4386 #include "php_compat.h"
4387
4388+
4389 #include "zend_API.h"
4390
4391 #undef sprintf
4392 #define sprintf php_sprintf
4393
4394+#if HARDENING_PATCH
4395+#if HAVE_REALPATH
4396+#undef realpath
4397+#define realpath php_realpath
4398+#endif
4399+#endif
4400+
4401 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
4402 #undef PHP_DEBUG
4403 #define PHP_DEBUG ZEND_DEBUG
4404@@ -330,6 +338,7 @@
4405 #define PHP_FUNCTION ZEND_FUNCTION
4406 #define PHP_METHOD ZEND_METHOD
4407
4408+#define PHP_STATIC_FE ZEND_STATIC_FE
4409 #define PHP_NAMED_FE ZEND_NAMED_FE
4410 #define PHP_FE ZEND_FE
4411 #define PHP_FALIAS ZEND_FALIAS
4412@@ -435,6 +444,10 @@
4413 #endif
4414 #endif /* !XtOffsetOf */
4415
4416+#if HARDENING_PATCH
4417+#include "hardening_patch.h"
4418+#endif
4419+
4420 #endif
4421
4422 /*
4423diff -Nura php-5.0.5/main/php_variables.c hardening-patch-5.0.5-0.4.5/main/php_variables.c
4424--- php-5.0.5/main/php_variables.c 2005-09-01 21:15:51.000000000 +0200
4425+++ hardening-patch-5.0.5-0.4.5/main/php_variables.c 2005-11-01 14:51:58.489877696 +0100
4426@@ -77,6 +77,10 @@
4427 symtable1 = Z_ARRVAL_P(track_vars_array);
4428 } else if (PG(register_globals)) {
4429 symtable1 = EG(active_symbol_table);
4430+ /* GLOBALS hijack attempt, reject parameter */
4431+ if (!strncmp("GLOBALS", var, sizeof("GLOBALS")) || !strncmp("GLOBALS", var, sizeof("GLOBALS[")-1)) {
4432+ symtable1 = NULL;
4433+ }
4434 }
4435 if (!symtable1) {
4436 /* Nothing to do */
4437@@ -103,6 +107,13 @@
4438 zval_dtor(val);
4439 return;
4440 }
4441+
4442+ /* GLOBALS hijack attempt, reject parameter */
4443+ if (symtable1 == EG(active_symbol_table) && !strcmp("GLOBALS", var)) {
4444+ zval_dtor(val);
4445+ return;
4446+ }
4447+
4448 /* ensure that we don't have spaces or dots in the variable name (not binary safe) */
4449 for (p=var; *p; p++) {
4450 switch(*p) {
4451@@ -514,7 +525,7 @@
4452 */
4453 static inline void php_register_server_variables(TSRMLS_D)
4454 {
4455- zval *array_ptr=NULL;
4456+ zval *array_ptr=NULL, *vptr;
4457 /* turn off magic_quotes while importing server variables */
4458 int magic_quotes_gpc = PG(magic_quotes_gpc);
4459
4460@@ -530,6 +541,16 @@
4461 /* Server variables */
4462 if (sapi_module.register_server_variables) {
4463 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
4464+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
4465+ char *str;
4466+ if (vptr->type != IS_STRING) {
4467+ str = "Array";
4468+ } else {
4469+ str = vptr->value.str.val;
4470+ }
4471+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
4472+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
4473+ }
4474 }
4475
4476 /* PHP Authentication support */
4477diff -Nura php-5.0.5/main/rfc1867.c hardening-patch-5.0.5-0.4.5/main/rfc1867.c
4478--- php-5.0.5/main/rfc1867.c 2005-07-13 22:51:12.000000000 +0200
4479+++ hardening-patch-5.0.5-0.4.5/main/rfc1867.c 2005-11-01 14:23:05.955262992 +0100
4480@@ -132,6 +132,7 @@
4481 #define UPLOAD_ERROR_D 4 /* No file uploaded */
4482 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
4483 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
4484+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
4485
4486 void php_rfc1867_register_constants(TSRMLS_D)
4487 {
4488@@ -142,6 +143,7 @@
4489 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
4490 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
4491 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
4492+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4493 }
4494
4495 static void normalize_protected_variable(char *varname TSRMLS_DC)
4496@@ -854,6 +856,7 @@
4497 char buff[FILLUNIT];
4498 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4499 int blen=0, wlen=0;
4500+ unsigned long offset;
4501
4502 zend_llist_clean(&header);
4503
4504@@ -970,7 +973,11 @@
4505 tmp++;
4506 }
4507 }
4508-
4509+
4510+ if (sapi_module.upload_varname_filter && sapi_module.upload_varname_filter(param TSRMLS_CC)==FAILURE) {
4511+ skip_upload = 1;
4512+ }
4513+
4514 total_bytes = cancel_upload = 0;
4515
4516 if (!skip_upload) {
4517@@ -994,6 +1001,11 @@
4518 cancel_upload = UPLOAD_ERROR_D;
4519 }
4520
4521+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4522+ cancel_upload = UPLOAD_ERROR_X;
4523+ }
4524+
4525+ offset = 0;
4526 end = 0;
4527 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4528 {
4529@@ -1008,6 +1020,10 @@
4530 #endif
4531 cancel_upload = UPLOAD_ERROR_B;
4532 } else if (blen > 0) {
4533+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4534+ cancel_upload = UPLOAD_ERROR_X;
4535+ }
4536+
4537 wlen = write(fd, buff, blen);
4538
4539 if (wlen < blen) {
4540@@ -1036,6 +1052,10 @@
4541 }
4542 #endif
4543
4544+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4545+ cancel_upload = UPLOAD_ERROR_X;
4546+ }
4547+
4548 if (cancel_upload) {
4549 if (temp_filename) {
4550 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4551diff -Nura php-5.0.5/main/SAPI.c hardening-patch-5.0.5-0.4.5/main/SAPI.c
4552--- php-5.0.5/main/SAPI.c 2005-02-22 15:46:15.000000000 +0100
4553+++ hardening-patch-5.0.5-0.4.5/main/SAPI.c 2005-11-01 14:23:05.956262840 +0100
4554@@ -821,6 +821,36 @@
4555 zend_hash_del(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1);
4556 }
4557
4558+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))
4559+{
4560+ sapi_module.input_filter = input_filter;
4561+ return SUCCESS;
4562+}
4563+
4564+SAPI_API int sapi_register_upload_varname_filter(unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC))
4565+{
4566+ sapi_module.upload_varname_filter = upload_varname_filter;
4567+ return SUCCESS;
4568+}
4569+
4570+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4571+{
4572+ sapi_module.pre_upload_filter = pre_upload_filter;
4573+ return SUCCESS;
4574+}
4575+
4576+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))
4577+{
4578+ sapi_module.upload_content_filter = upload_content_filter;
4579+ return SUCCESS;
4580+}
4581+
4582+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4583+{
4584+ sapi_module.post_upload_filter = post_upload_filter;
4585+ return SUCCESS;
4586+}
4587+
4588
4589 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
4590 {
4591@@ -835,11 +865,6 @@
4592 return SUCCESS;
4593 }
4594
4595-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))
4596-{
4597- sapi_module.input_filter = input_filter;
4598- return SUCCESS;
4599-}
4600
4601 SAPI_API int sapi_flush(TSRMLS_D)
4602 {
4603diff -Nura php-5.0.5/main/SAPI.h hardening-patch-5.0.5-0.4.5/main/SAPI.h
4604--- php-5.0.5/main/SAPI.h 2004-01-08 18:33:04.000000000 +0100
4605+++ hardening-patch-5.0.5-0.4.5/main/SAPI.h 2005-11-01 14:23:05.957262688 +0100
4606@@ -103,9 +103,10 @@
4607 char *current_user;
4608 int current_user_length;
4609
4610- /* this is necessary for CLI module */
4611- int argc;
4612- char **argv;
4613+ /* this is necessary for CLI module */
4614+ int argc;
4615+ char **argv;
4616+
4617 } sapi_request_info;
4618
4619
4620@@ -183,6 +184,10 @@
4621 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4622 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));
4623
4624+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4625+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));
4626+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4627+
4628 SAPI_API int sapi_flush(TSRMLS_D);
4629 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4630 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
4631@@ -245,6 +250,11 @@
4632 int (*get_target_gid)(gid_t * TSRMLS_DC);
4633
4634 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4635+
4636+ unsigned int (*upload_varname_filter)(char *varname TSRMLS_DC);
4637+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
4638+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
4639+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
4640
4641 void (*ini_defaults)(HashTable *configuration_hash);
4642 int phpinfo_as_text;
4643@@ -270,7 +280,11 @@
4644
4645 #define SAPI_DEFAULT_MIMETYPE "text/html"
4646 #define SAPI_DEFAULT_CHARSET ""
4647+#if HARDENING_PATCH
4648+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
4649+#else
4650 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4651+#endif
4652
4653 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4654 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4655@@ -278,6 +292,11 @@
4656 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4657 #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)
4658
4659+#define SAPI_UPLOAD_VARNAME_FILTER_FUNC(upload_varname_filter) unsigned int upload_varname_filter(char *varname TSRMLS_DC)
4660+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
4661+#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)
4662+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
4663+
4664 BEGIN_EXTERN_C()
4665 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4666 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4667diff -Nura php-5.0.5/main/snprintf.c hardening-patch-5.0.5-0.4.5/main/snprintf.c
4668--- php-5.0.5/main/snprintf.c 2004-11-16 00:14:40.000000000 +0100
4669+++ hardening-patch-5.0.5-0.4.5/main/snprintf.c 2005-11-01 14:23:05.957262688 +0100
4670@@ -1013,7 +1013,11 @@
4671
4672
4673 case 'n':
4674+#if HARDENING_PATCH_FMT_PROTECT
4675+ php_security_log(S_MISC, "'n' specifier within format string");
4676+#else
4677 *(va_arg(ap, int *)) = cc;
4678+#endif
4679 break;
4680
4681 /*
4682diff -Nura php-5.0.5/main/spprintf.c hardening-patch-5.0.5-0.4.5/main/spprintf.c
4683--- php-5.0.5/main/spprintf.c 2004-04-16 01:04:49.000000000 +0200
4684+++ hardening-patch-5.0.5-0.4.5/main/spprintf.c 2005-11-01 14:23:05.958262536 +0100
4685@@ -630,7 +630,11 @@
4686
4687
4688 case 'n':
4689+#if HARDENING_PATCH_FMT_PROTECT
4690+ php_security_log(S_MISC, "'n' specifier within format string");
4691+#else
4692 *(va_arg(ap, int *)) = xbuf->len;
4693+#endif
4694 break;
4695
4696 /*
4697diff -Nura php-5.0.5/php.ini-dist hardening-patch-5.0.5-0.4.5/php.ini-dist
4698--- php-5.0.5/php.ini-dist 2005-05-05 14:33:56.000000000 +0200
4699+++ hardening-patch-5.0.5-0.4.5/php.ini-dist 2005-11-01 14:23:05.959262384 +0100
4700@@ -1197,6 +1197,197 @@
4701 ; instead of original one.
4702 soap.wsdl_cache_ttl=86400
4703
4704+[hardening-patch]
4705+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4706+; Hardening-Patch's logging ;
4707+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4708+
4709+;
4710+; hphp.log.syslog - Configures level for alerts reported through syslog
4711+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4712+; hphp.log.script - Configures level for alerts reported through external script
4713+;
4714+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4715+; Or each number up to get desired Hardening-Patch's reporting level
4716+;
4717+; S_ALL - All alerts
4718+; S_MEMORY - All canary violations and the safe unlink protection use this class
4719+; S_VARS - All variable filters trigger this class
4720+; S_FILES - All violation of uploaded files filter use this class
4721+; S_INCLUDE - The protection against malicious include filenames use this class
4722+; S_SQL - Failed SQL queries in MySQL are logged with this class
4723+; S_EXECUTOR - The execution depth protection uses this logging class
4724+; S_MISC - All other log messages (f.e. format string protection) use this class
4725+;
4726+; Example:
4727+;
4728+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4729+; memory alerts through syslog and SQL+Include alerts fo the script
4730+;
4731+;hphp.log.syslog = S_MEMORY
4732+;hphp.log.sapi = S_ALL & ~S_MEMORY
4733+;hphp.log.script = S_INCLUDE | S_SQL
4734+;
4735+; Syslog logging:
4736+;
4737+; - Facility configuration: one of the following facilities
4738+;
4739+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4740+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4741+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4742+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4743+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4744+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4745+; LOG_PERROR
4746+;
4747+; - Priority configuration: one of the followinf priorities
4748+;
4749+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4750+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4751+;
4752+hphp.log.syslog.priority = LOG_ALERT
4753+hphp.log.syslog.facility = LOG_USER
4754+;
4755+; Script logging:
4756+;
4757+;hphp.log.script.name = /home/hphp/log_script
4758+;
4759+; Alert configuration:
4760+;
4761+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4762+;
4763+;hphp.log.use-x-forwarded-for = On
4764+;
4765+
4766+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4767+; Hardening-Patch's Executor options ;
4768+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4769+
4770+; Execution depth limit
4771+;hphp.executor.max_depth = 8000
4772+
4773+; White-/blacklist for function calls during normal execution
4774+;hphp.executor.func.whitelist = ord,chr
4775+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4776+
4777+; White-/blacklist for function calls during eval() execution
4778+;hphp.executor.eval.whitelist = ord,chr
4779+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4780+
4781+; White-/blacklist for URLs allowes in include filenames
4782+;
4783+; - When both options are not set all URLs are forbidden
4784+;
4785+; - When both options are set whitelist is taken and blacklist ignored
4786+;
4787+; - An entry in the lists is either a URL sheme like: http, https
4788+; or the beginning of an URL like: php://input
4789+;
4790+;hphp.executor.include.whitelist = cookietest
4791+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
4792+
4793+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4794+; Hardening-Patch's REQUEST variable filters ;
4795+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4796+
4797+; Limits the number of REQUEST variables
4798+hphp.request.max_vars = 200
4799+
4800+; Limits the length of variable names (without indices)
4801+hphp.request.max_varname_length = 64
4802+
4803+; Limits the length of complete variable names (with indices)
4804+hphp.request.max_totalname_length = 256
4805+
4806+; Limits the length of array indices
4807+hphp.request.max_array_index_length = 64
4808+
4809+; Limits the depth of arrays
4810+hphp.request.max_array_depth = 100
4811+
4812+; Limits the length of variable values
4813+hphp.request.max_value_length = 65000
4814+
4815+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4816+; Hardening-Patch's COOKIE variable filters ;
4817+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4818+
4819+; Limits the number of COOKIE variables
4820+hphp.cookie.max_vars = 100
4821+
4822+; Limits the length of variable names (without indices)
4823+hphp.cookie.max_name_length = 64
4824+
4825+; Limits the length of complete variable names (with indices)
4826+hphp.cookie.max_totalname_length = 256
4827+
4828+; Limits the length of array indices
4829+hphp.cookie.max_array_index_length = 64
4830+
4831+; Limits the depth of arrays
4832+hphp.cookie.max_array_depth = 100
4833+
4834+; Limits the length of variable values
4835+hphp.cookie.max_value_length = 10000
4836+
4837+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4838+; Hardening-Patch's GET variable filters ;
4839+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4840+
4841+; Limits the number of COOKIE variables
4842+hphp.get.max_vars = 100
4843+
4844+; Limits the length of variable names (without indices)
4845+hphp.get.max_name_length = 64
4846+
4847+; Limits the length of complete variable names (with indices)
4848+hphp.get.max_totalname_length = 256
4849+
4850+; Limits the length of array indices
4851+hphp.get.max_array_index_length = 64
4852+
4853+; Limits the depth of arrays
4854+hphp.get.max_array_depth = 50
4855+
4856+; Limits the length of variable values
4857+hphp.get.max_value_length = 512
4858+
4859+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4860+; Hardening-Patch's POST variable filters ;
4861+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4862+
4863+; Limits the number of POST variables
4864+hphp.post.max_vars = 200
4865+
4866+; Limits the length of variable names (without indices)
4867+hphp.post.max_name_length = 64
4868+
4869+; Limits the length of complete variable names (with indices)
4870+hphp.post.max_totalname_length = 256
4871+
4872+; Limits the length of array indices
4873+hphp.post.max_array_index_length = 64
4874+
4875+; Limits the depth of arrays
4876+hphp.post.max_array_depth = 100
4877+
4878+; Limits the length of variable values
4879+hphp.post.max_value_length = 65000
4880+
4881+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4882+; Hardening-Patch's fileupload variable filters ;
4883+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4884+
4885+; Limits the number of uploadable files
4886+hphp.upload.max_uploads = 25
4887+
4888+; Filter out the upload of ELF executables
4889+hphp.upload.disallow_elf_files = On
4890+
4891+; External filterscript for upload verification
4892+;hphp.upload.verification_script = /home/hphp/verify_script
4893+
4894+
4895 ; Local Variables:
4896 ; tab-width: 4
4897 ; End:
4898diff -Nura php-5.0.5/php.ini-recommended hardening-patch-5.0.5-0.4.5/php.ini-recommended
4899--- php-5.0.5/php.ini-recommended 2005-05-05 14:33:56.000000000 +0200
4900+++ hardening-patch-5.0.5-0.4.5/php.ini-recommended 2005-11-01 14:23:05.960262232 +0100
4901@@ -1255,6 +1255,196 @@
4902 ; instead of original one.
4903 soap.wsdl_cache_ttl=86400
4904
4905+[hardening-patch]
4906+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4907+; Hardening-Patch's logging ;
4908+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4909+
4910+;
4911+; hphp.log.syslog - Configures level for alerts reported through syslog
4912+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4913+; hphp.log.script - Configures level for alerts reported through external script
4914+;
4915+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4916+; Or each number up to get desired Hardening-Patch's reporting level
4917+;
4918+; S_ALL - All alerts
4919+; S_MEMORY - All canary violations and the safe unlink protection use this class
4920+; S_VARS - All variable filters trigger this class
4921+; S_FILES - All violation of uploaded files filter use this class
4922+; S_INCLUDE - The protection against malicious include filenames use this class
4923+; S_SQL - Failed SQL queries in MySQL are logged with this class
4924+; S_EXECUTOR - The execution depth protection uses this logging class
4925+; S_MISC - All other log messages (f.e. format string protection) use this class
4926+;
4927+; Example:
4928+;
4929+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4930+; memory alerts through syslog and SQL+Include alerts fo the script
4931+;
4932+;hphp.log.syslog = S_MEMORY
4933+;hphp.log.sapi = S_ALL & ~S_MEMORY
4934+;hphp.log.script = S_INCLUDE | S_SQL
4935+;
4936+; Syslog logging:
4937+;
4938+; - Facility configuration: one of the following facilities
4939+;
4940+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4941+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4942+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4943+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4944+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4945+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4946+; LOG_PERROR
4947+;
4948+; - Priority configuration: one of the followinf priorities
4949+;
4950+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4951+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4952+;
4953+hphp.log.syslog.priority = LOG_ALERT
4954+hphp.log.syslog.facility = LOG_USER
4955+;
4956+; Script logging:
4957+;
4958+;hphp.log.script.name = /home/hphp/log_script
4959+;
4960+; Alert configuration:
4961+;
4962+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4963+;
4964+;hphp.log.use-x-forwarded-for = On
4965+;
4966+
4967+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4968+; Hardening-Patch's Executor options ;
4969+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4970+
4971+; Execution depth limit
4972+;hphp.executor.max_depth = 8000
4973+
4974+; White-/blacklist for function calls during normal execution
4975+;hphp.executor.func.whitelist = ord,chr
4976+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4977+
4978+; White-/blacklist for function calls during eval() execution
4979+;hphp.executor.eval.whitelist = ord,chr
4980+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4981+
4982+; White-/blacklist for URLs allowes in include filenames
4983+;
4984+; - When both options are not set all URLs are forbidden
4985+;
4986+; - When both options are set whitelist is taken and blacklist ignored
4987+;
4988+; - An entry in the lists is either a URL sheme like: http, https
4989+; or the beginning of an URL like: php://input
4990+;
4991+;hphp.executor.include.whitelist = cookietest
4992+;hphp.executor.include.blacklist = http, https, ftp, ftps, php://input, file
4993+
4994+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4995+; Hardening-Patch's REQUEST variable filters ;
4996+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4997+
4998+; Limits the number of REQUEST variables
4999+hphp.request.max_vars = 200
5000+
5001+; Limits the length of variable names (without indices)
5002+hphp.request.max_varname_length = 64
5003+
5004+; Limits the length of complete variable names (with indices)
5005+hphp.request.max_totalname_length = 256
5006+
5007+; Limits the length of array indices
5008+hphp.request.max_array_index_length = 64
5009+
5010+; Limits the depth of arrays
5011+hphp.request.max_array_depth = 100
5012+
5013+; Limits the length of variable values
5014+hphp.request.max_value_length = 65000
5015+
5016+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5017+; Hardening-Patch's COOKIE variable filters ;
5018+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5019+
5020+; Limits the number of COOKIE variables
5021+hphp.cookie.max_vars = 100
5022+
5023+; Limits the length of variable names (without indices)
5024+hphp.cookie.max_name_length = 64
5025+
5026+; Limits the length of complete variable names (with indices)
5027+hphp.cookie.max_totalname_length = 256
5028+
5029+; Limits the length of array indices
5030+hphp.cookie.max_array_index_length = 64
5031+
5032+; Limits the depth of arrays
5033+hphp.cookie.max_array_depth = 100
5034+
5035+; Limits the length of variable values
5036+hphp.cookie.max_value_length = 10000
5037+
5038+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5039+; Hardening-Patch's GET variable filters ;
5040+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5041+
5042+; Limits the number of COOKIE variables
5043+hphp.get.max_vars = 100
5044+
5045+; Limits the length of variable names (without indices)
5046+hphp.get.max_name_length = 64
5047+
5048+; Limits the length of complete variable names (with indices)
5049+hphp.get.max_totalname_length = 256
5050+
5051+; Limits the length of array indices
5052+hphp.get.max_array_index_length = 64
5053+
5054+; Limits the depth of arrays
5055+hphp.get.max_array_depth = 50
5056+
5057+; Limits the length of variable values
5058+hphp.get.max_value_length = 512
5059+
5060+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5061+; Hardening-Patch's POST variable filters ;
5062+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5063+
5064+; Limits the number of POST variables
5065+hphp.post.max_vars = 200
5066+
5067+; Limits the length of variable names (without indices)
5068+hphp.post.max_name_length = 64
5069+
5070+; Limits the length of complete variable names (with indices)
5071+hphp.post.max_totalname_length = 256
5072+
5073+; Limits the length of array indices
5074+hphp.post.max_array_index_length = 64
5075+
5076+; Limits the depth of arrays
5077+hphp.post.max_array_depth = 100
5078+
5079+; Limits the length of variable values
5080+hphp.post.max_value_length = 65000
5081+
5082+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5083+; Hardening-Patch's fileupload variable filters ;
5084+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
5085+
5086+; Limits the number of uploadable files
5087+hphp.upload.max_uploads = 25
5088+
5089+; Filter out the upload of ELF executables
5090+hphp.upload.disallow_elf_files = On
5091+
5092+; External filterscript for upload verification
5093+;hphp.upload.verification_script = /home/hphp/verify_script
5094+
5095 ; Local Variables:
5096 ; tab-width: 4
5097 ; End:
5098diff -Nura php-5.0.5/sapi/apache/mod_php5.c hardening-patch-5.0.5-0.4.5/sapi/apache/mod_php5.c
5099--- php-5.0.5/sapi/apache/mod_php5.c 2005-08-01 10:12:42.000000000 +0200
5100+++ hardening-patch-5.0.5-0.4.5/sapi/apache/mod_php5.c 2005-11-01 14:23:05.961262080 +0100
5101@@ -455,7 +455,7 @@
5102 sapi_apache_get_fd,
5103 sapi_apache_force_http_10,
5104 sapi_apache_get_target_uid,
5105- sapi_apache_get_target_gid
5106+ sapi_apache_get_target_gid,
5107 };
5108 /* }}} */
5109
5110@@ -907,7 +907,11 @@
5111 {
5112 TSRMLS_FETCH();
5113 if (PG(expose_php)) {
5114+#if HARDENING_PATCH
5115+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
5116+#else
5117 ap_add_version_component("PHP/" PHP_VERSION);
5118+#endif
5119 }
5120 }
5121 #endif
5122diff -Nura php-5.0.5/sapi/apache2filter/sapi_apache2.c hardening-patch-5.0.5-0.4.5/sapi/apache2filter/sapi_apache2.c
5123--- php-5.0.5/sapi/apache2filter/sapi_apache2.c 2005-07-16 14:30:10.000000000 +0200
5124+++ hardening-patch-5.0.5-0.4.5/sapi/apache2filter/sapi_apache2.c 2005-11-01 14:23:05.962261928 +0100
5125@@ -562,7 +562,11 @@
5126 {
5127 TSRMLS_FETCH();
5128 if (PG(expose_php)) {
5129+#if HARDENING_PATCH
5130+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5131+#else
5132 ap_add_version_component(p, "PHP/" PHP_VERSION);
5133+#endif
5134 }
5135 }
5136
5137diff -Nura php-5.0.5/sapi/apache2handler/sapi_apache2.c hardening-patch-5.0.5-0.4.5/sapi/apache2handler/sapi_apache2.c
5138--- php-5.0.5/sapi/apache2handler/sapi_apache2.c 2005-09-02 15:51:26.000000000 +0200
5139+++ hardening-patch-5.0.5-0.4.5/sapi/apache2handler/sapi_apache2.c 2005-11-01 14:23:05.962261928 +0100
5140@@ -333,7 +333,11 @@
5141 {
5142 TSRMLS_FETCH();
5143 if (PG(expose_php)) {
5144+#if HARDENING_PATCH
5145+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
5146+#else
5147 ap_add_version_component(p, "PHP/" PHP_VERSION);
5148+#endif
5149 }
5150 }
5151
5152diff -Nura php-5.0.5/sapi/cgi/cgi_main.c hardening-patch-5.0.5-0.4.5/sapi/cgi/cgi_main.c
5153--- php-5.0.5/sapi/cgi/cgi_main.c 2005-04-28 16:24:21.000000000 +0200
5154+++ hardening-patch-5.0.5-0.4.5/sapi/cgi/cgi_main.c 2005-11-01 14:23:05.963261776 +0100
5155@@ -1419,11 +1419,19 @@
5156 SG(headers_sent) = 1;
5157 SG(request_info).no_headers = 1;
5158 }
5159+#if HARDENING_PATCH
5160+#if ZEND_DEBUG
5161+ 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());
5162+#else
5163+ 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());
5164+#endif
5165+#else
5166 #if ZEND_DEBUG
5167 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());
5168 #else
5169 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());
5170 #endif
5171+#endif
5172 php_end_ob_buffers(1 TSRMLS_CC);
5173 exit(1);
5174 break;
5175diff -Nura php-5.0.5/sapi/cli/php_cli.c hardening-patch-5.0.5-0.4.5/sapi/cli/php_cli.c
5176--- php-5.0.5/sapi/cli/php_cli.c 2005-03-22 16:09:20.000000000 +0100
5177+++ hardening-patch-5.0.5-0.4.5/sapi/cli/php_cli.c 2005-11-01 14:23:05.964261624 +0100
5178@@ -694,11 +694,19 @@
5179 if (php_request_startup(TSRMLS_C)==FAILURE) {
5180 goto err;
5181 }
5182+#if HARDENING_PATCH
5183+#if ZEND_DEBUG
5184+ 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());
5185+#else
5186+ 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());
5187+#endif
5188+#else
5189 #if ZEND_DEBUG
5190 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());
5191 #else
5192 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());
5193 #endif
5194+#endif
5195 php_end_ob_buffers(1 TSRMLS_CC);
5196 exit_status=1;
5197 goto out;
5198diff -Nura php-5.0.5/TSRM/TSRM.h hardening-patch-5.0.5-0.4.5/TSRM/TSRM.h
5199--- php-5.0.5/TSRM/TSRM.h 2005-03-11 12:12:07.000000000 +0100
5200+++ hardening-patch-5.0.5-0.4.5/TSRM/TSRM.h 2005-11-01 14:23:05.964261624 +0100
5201@@ -33,6 +33,13 @@
5202 # define TSRM_API
5203 #endif
5204
5205+#if HARDENING_PATCH
5206+# if HAVE_REALPATH
5207+# undef realpath
5208+# define realpath php_realpath
5209+# endif
5210+#endif
5211+
5212 /* Only compile multi-threading functions if we're in ZTS mode */
5213 #ifdef ZTS
5214
5215@@ -88,6 +95,7 @@
5216
5217 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
5218
5219+
5220 #ifdef __cplusplus
5221 extern "C" {
5222 #endif
5223diff -Nura php-5.0.5/TSRM/tsrm_virtual_cwd.c hardening-patch-5.0.5-0.4.5/TSRM/tsrm_virtual_cwd.c
5224--- php-5.0.5/TSRM/tsrm_virtual_cwd.c 2005-07-16 13:50:59.000000000 +0200
5225+++ hardening-patch-5.0.5-0.4.5/TSRM/tsrm_virtual_cwd.c 2005-11-01 14:23:05.965261472 +0100
5226@@ -184,6 +184,165 @@
5227 return p;
5228 }
5229
5230+#if HARDENING_PATCH
5231+CWD_API char *php_realpath(const char *path, char *resolved)
5232+{
5233+ struct stat sb;
5234+ char *p, *q, *s;
5235+ size_t left_len, resolved_len;
5236+ unsigned symlinks;
5237+ int serrno, slen;
5238+ int is_dir = 1;
5239+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
5240+
5241+ serrno = errno;
5242+ symlinks = 0;
5243+ if (path[0] == '/') {
5244+ resolved[0] = '/';
5245+ resolved[1] = '\0';
5246+ if (path[1] == '\0')
5247+ return (resolved);
5248+ resolved_len = 1;
5249+ left_len = strlcpy(left, path + 1, sizeof(left));
5250+ } else {
5251+ if (getcwd(resolved, PATH_MAX) == NULL) {
5252+ strlcpy(resolved, ".", PATH_MAX);
5253+ return (NULL);
5254+ }
5255+ resolved_len = strlen(resolved);
5256+ left_len = strlcpy(left, path, sizeof(left));
5257+ }
5258+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
5259+ errno = ENAMETOOLONG;
5260+ return (NULL);
5261+ }
5262+
5263+ /*
5264+ * Iterate over path components in `left'.
5265+ */
5266+ while (left_len != 0) {
5267+ /*
5268+ * Extract the next path component and adjust `left'
5269+ * and its length.
5270+ */
5271+ p = strchr(left, '/');
5272+ s = p ? p : left + left_len;
5273+ if (s - left >= sizeof(next_token)) {
5274+ errno = ENAMETOOLONG;
5275+ return (NULL);
5276+ }
5277+ memcpy(next_token, left, s - left);
5278+ next_token[s - left] = '\0';
5279+ left_len -= s - left;
5280+ if (p != NULL)
5281+ memmove(left, s + 1, left_len + 1);
5282+ if (resolved[resolved_len - 1] != '/') {
5283+ if (resolved_len + 1 >= PATH_MAX) {
5284+ errno = ENAMETOOLONG;
5285+ return (NULL);
5286+ }
5287+ resolved[resolved_len++] = '/';
5288+ resolved[resolved_len] = '\0';
5289+ }
5290+ if (next_token[0] == '\0')
5291+ continue;
5292+ else if (strcmp(next_token, ".") == 0)
5293+ continue;
5294+ else if (strcmp(next_token, "..") == 0) {
5295+ /*
5296+ * Strip the last path component except when we have
5297+ * single "/"
5298+ */
5299+ if (!is_dir) {
5300+ errno = ENOENT;
5301+ return (NULL);
5302+ }
5303+ if (resolved_len > 1) {
5304+ resolved[resolved_len - 1] = '\0';
5305+ q = strrchr(resolved, '/');
5306+ *q = '\0';
5307+ resolved_len = q - resolved;
5308+ }
5309+ continue;
5310+ }
5311+
5312+ /*
5313+ * Append the next path component and lstat() it. If
5314+ * lstat() fails we still can return successfully if
5315+ * there are no more path components left.
5316+ */
5317+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
5318+ if (resolved_len >= PATH_MAX) {
5319+ errno = ENAMETOOLONG;
5320+ return (NULL);
5321+ }
5322+ if (lstat(resolved, &sb) != 0) {
5323+ if (errno == ENOENT && p == NULL) {
5324+ errno = serrno;
5325+ return (resolved);
5326+ }
5327+ return (NULL);
5328+ }
5329+ if (S_ISLNK(sb.st_mode)) {
5330+ if (symlinks++ > MAXSYMLINKS) {
5331+ errno = ELOOP;
5332+ return (NULL);
5333+ }
5334+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
5335+ if (slen < 0)
5336+ return (NULL);
5337+ symlink[slen] = '\0';
5338+ if (symlink[0] == '/') {
5339+ resolved[1] = 0;
5340+ resolved_len = 1;
5341+ } else if (resolved_len > 1) {
5342+ /* Strip the last path component. */
5343+ resolved[resolved_len - 1] = '\0';
5344+ q = strrchr(resolved, '/');
5345+ *q = '\0';
5346+ resolved_len = q - resolved;
5347+ }
5348+
5349+ /*
5350+ * If there are any path components left, then
5351+ * append them to symlink. The result is placed
5352+ * in `left'.
5353+ */
5354+ if (p != NULL) {
5355+ if (symlink[slen - 1] != '/') {
5356+ if (slen + 1 >= sizeof(symlink)) {
5357+ errno = ENAMETOOLONG;
5358+ return (NULL);
5359+ }
5360+ symlink[slen] = '/';
5361+ symlink[slen + 1] = 0;
5362+ }
5363+ left_len = strlcat(symlink, left, sizeof(left));
5364+ if (left_len >= sizeof(left)) {
5365+ errno = ENAMETOOLONG;
5366+ return (NULL);
5367+ }
5368+ }
5369+ left_len = strlcpy(left, symlink, sizeof(left));
5370+ } else {
5371+ if (S_ISDIR(sb.st_mode)) {
5372+ is_dir = 1;
5373+ } else {
5374+ is_dir = 0;
5375+ }
5376+ }
5377+ }
5378+
5379+ /*
5380+ * Remove trailing slash except when the resolved pathname
5381+ * is a single "/".
5382+ */
5383+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
5384+ resolved[resolved_len - 1] = '\0';
5385+ return (resolved);
5386+}
5387+#endif
5388+
5389 CWD_API void virtual_cwd_startup(void)
5390 {
5391 char cwd[MAXPATHLEN];
5392@@ -321,8 +480,7 @@
5393 path = resolved_path;
5394 path_length = strlen(path);
5395 } else {
5396- /* disable for now
5397- return 1; */
5398+ return 1;
5399 }
5400 }
5401 } else { /* Concat current directory with relative path and then run realpath() on it */
5402@@ -348,9 +506,8 @@
5403 path = resolved_path;
5404 path_length = strlen(path);
5405 } else {
5406- /* disable for now
5407 free(tmp);
5408- return 1; */
5409+ return 1;
5410 }
5411 }
5412 free(tmp);
5413diff -Nura php-5.0.5/TSRM/tsrm_virtual_cwd.h hardening-patch-5.0.5-0.4.5/TSRM/tsrm_virtual_cwd.h
5414--- php-5.0.5/TSRM/tsrm_virtual_cwd.h 2005-07-16 13:50:59.000000000 +0200
5415+++ hardening-patch-5.0.5-0.4.5/TSRM/tsrm_virtual_cwd.h 2005-11-01 14:23:05.966261320 +0100
5416@@ -126,6 +126,22 @@
5417
5418 typedef int (*verify_path_func)(const cwd_state *);
5419
5420+#ifndef HAVE_STRLCPY
5421+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
5422+#undef strlcpy
5423+#define strlcpy php_strlcpy
5424+#endif
5425+
5426+#ifndef HAVE_STRLCAT
5427+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
5428+#undef strlcat
5429+#define strlcat php_strlcat
5430+#endif
5431+
5432+
5433+#if HARDENING_PATCH
5434+CWD_API char *php_realpath(const char *path, char *resolved);
5435+#endif
5436 CWD_API void virtual_cwd_startup(void);
5437 CWD_API void virtual_cwd_shutdown(void);
5438 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
5439diff -Nura php-5.0.5/Zend/zend_alloc.c hardening-patch-5.0.5-0.4.5/Zend/zend_alloc.c
5440--- php-5.0.5/Zend/zend_alloc.c 2005-08-18 17:14:23.000000000 +0200
5441+++ hardening-patch-5.0.5-0.4.5/Zend/zend_alloc.c 2005-11-01 14:23:05.967261168 +0100
5442@@ -64,6 +64,11 @@
5443 # define END_MAGIC_SIZE 0
5444 #endif
5445
5446+#if HARDENING_PATCH_MM_PROTECT
5447+# define CANARY_SIZE sizeof(unsigned int)
5448+#else
5449+# define CANARY_SIZE 0
5450+#endif
5451
5452 # if MEMORY_LIMIT
5453 # if ZEND_DEBUG
5454@@ -105,9 +110,17 @@
5455 if (p==AG(head)) { \
5456 AG(head) = p->pNext; \
5457 } else { \
5458+ if (p != p->pLast->pNext) { \
5459+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5460+ exit(1); \
5461+ } \
5462 p->pLast->pNext = p->pNext; \
5463 } \
5464 if (p->pNext) { \
5465+ if (p != p->pNext->pLast) { \
5466+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
5467+ exit(1); \
5468+ } \
5469 p->pNext->pLast = p->pLast; \
5470 }
5471 #else
5472@@ -146,6 +159,12 @@
5473 DECLARE_CACHE_VARS();
5474 TSRMLS_FETCH();
5475
5476+#if HARDENING_PATCH_MM_PROTECT
5477+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
5478+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
5479+ exit(1);
5480+ }
5481+#endif
5482 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
5483
5484 #if !ZEND_DISABLE_MEMORY_CACHE
5485@@ -164,6 +183,10 @@
5486 AG(cache_stats)[CACHE_INDEX][1]++;
5487 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5488 #endif
5489+#if HARDENING_PATCH_MM_PROTECT
5490+ p->canary = HG(canary_1);
5491+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5492+#endif
5493 p->cached = 0;
5494 p->size = size;
5495 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5496@@ -180,7 +203,7 @@
5497 AG(allocated_memory_peak) = AG(allocated_memory);
5498 }
5499 #endif
5500- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
5501+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
5502 #if !ZEND_DISABLE_MEMORY_CACHE
5503 }
5504 #endif
5505@@ -212,7 +235,10 @@
5506 # endif
5507 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5508 #endif
5509-
5510+#if HARDENING_PATCH_MM_PROTECT
5511+ p->canary = HG(canary_1);
5512+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5513+#endif
5514 HANDLE_UNBLOCK_INTERRUPTIONS();
5515 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
5516 }
5517@@ -240,6 +266,10 @@
5518 }
5519 }
5520
5521+
5522+#if HARDENING_PATCH
5523+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
5524+#endif
5525 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
5526 return 0;
5527 }
5528@@ -248,9 +278,25 @@
5529
5530 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5531 {
5532+#if HARDENING_PATCH_MM_PROTECT
5533+ unsigned int canary_2;
5534+#endif
5535 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
5536 DECLARE_CACHE_VARS();
5537 TSRMLS_FETCH();
5538+
5539+#if HARDENING_PATCH_MM_PROTECT
5540+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
5541+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5542+ if (canary_2 != HG(canary_2)) {
5543+efree_canary_mismatch:
5544+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
5545+ exit(1);
5546+ }
5547+ /* to catch double efree()s */
5548+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
5549+ p->canary = 0;
5550+#endif
5551
5552 #if defined(ZTS) && TSRM_DEBUG
5553 if (p->thread_id != tsrm_thread_id()) {
5554@@ -292,23 +338,35 @@
5555
5556 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5557 {
5558- void *p;
5559- int final_size = size*nmemb;
5560+ char *p;
5561+ size_t _size = nmemb * size;
5562+
5563+ if (nmemb && (_size/nmemb!=size)) {
5564+#if HARDENING_PATCH
5565+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
5566+#endif
5567+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
5568+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
5569+ kill(getpid(), SIGSEGV);
5570+#else
5571+ exit(1);
5572+#endif
5573+ }
5574
5575- HANDLE_BLOCK_INTERRUPTIONS();
5576- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
5577- if (!p) {
5578- HANDLE_UNBLOCK_INTERRUPTIONS();
5579- return (void *) p;
5580+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
5581+ if (p) {
5582+ memset(p, 0, _size);
5583 }
5584- memset(p, 0, final_size);
5585- HANDLE_UNBLOCK_INTERRUPTIONS();
5586- return p;
5587+
5588+ return ((void *)p);
5589 }
5590
5591
5592 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5593 {
5594+#if HARDENING_PATCH_MM_PROTECT
5595+ unsigned int canary_2;
5596+#endif
5597 zend_mem_header *p;
5598 zend_mem_header *orig;
5599 DECLARE_CACHE_VARS();
5600@@ -320,6 +378,16 @@
5601
5602 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
5603
5604+#if HARDENING_PATCH_MM_PROTECT
5605+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
5606+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5607+ if (canary_2 != HG(canary_2)) {
5608+erealloc_canary_mismatch:
5609+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
5610+ exit(1);
5611+ }
5612+#endif
5613+
5614 #if defined(ZTS) && TSRM_DEBUG
5615 if (p->thread_id != tsrm_thread_id()) {
5616 void *new_p;
5617@@ -343,7 +411,7 @@
5618 }
5619 #endif
5620 REMOVE_POINTER_FROM_LIST(p);
5621- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
5622+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
5623 if (!p) {
5624 if (!allow_failure) {
5625 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
5626@@ -365,6 +433,9 @@
5627 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5628 #endif
5629
5630+#if HARDENING_PATCH_MM_PROTECT
5631+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5632+#endif
5633 p->size = size;
5634
5635 HANDLE_UNBLOCK_INTERRUPTIONS();
5636@@ -439,6 +510,10 @@
5637 {
5638 AG(head) = NULL;
5639
5640+#if HARDENING_PATCH_MM_PROTECT
5641+ HG(canary_1) = zend_canary();
5642+ HG(canary_2) = zend_canary();
5643+#endif
5644 #if MEMORY_LIMIT
5645 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
5646 AG(allocated_memory) = 0;
5647diff -Nura php-5.0.5/Zend/zend_alloc.h hardening-patch-5.0.5-0.4.5/Zend/zend_alloc.h
5648--- php-5.0.5/Zend/zend_alloc.h 2005-06-07 15:37:13.000000000 +0200
5649+++ hardening-patch-5.0.5-0.4.5/Zend/zend_alloc.h 2005-11-01 14:23:05.967261168 +0100
5650@@ -35,6 +35,9 @@
5651 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
5652
5653 typedef struct _zend_mem_header {
5654+#if HARDENING_PATCH_MM_PROTECT
5655+ unsigned int canary;
5656+#endif
5657 #if ZEND_DEBUG
5658 long magic;
5659 char *filename;
5660diff -Nura php-5.0.5/Zend/zend_API.h hardening-patch-5.0.5-0.4.5/Zend/zend_API.h
5661--- php-5.0.5/Zend/zend_API.h 2005-06-27 19:42:06.000000000 +0200
5662+++ hardening-patch-5.0.5-0.4.5/Zend/zend_API.h 2005-11-01 14:23:05.968261016 +0100
5663@@ -47,6 +47,7 @@
5664 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
5665
5666 #define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
5667+#define ZEND_STATIC_FE(zend_name, name, arg_info) { zend_name, name, arg_info, (zend_uint) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), 0 },
5668
5669 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
5670 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
5671diff -Nura php-5.0.5/Zend/zend_builtin_functions.c hardening-patch-5.0.5-0.4.5/Zend/zend_builtin_functions.c
5672--- php-5.0.5/Zend/zend_builtin_functions.c 2005-06-27 19:42:06.000000000 +0200
5673+++ hardening-patch-5.0.5-0.4.5/Zend/zend_builtin_functions.c 2005-11-01 14:23:05.969260864 +0100
5674@@ -52,6 +52,9 @@
5675 static ZEND_FUNCTION(crash);
5676 #endif
5677 #endif
5678+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5679+static ZEND_FUNCTION(heap_overflow);
5680+#endif
5681 static ZEND_FUNCTION(get_included_files);
5682 static ZEND_FUNCTION(is_subclass_of);
5683 static ZEND_FUNCTION(is_a);
5684@@ -111,6 +114,9 @@
5685 ZEND_FE(crash, NULL)
5686 #endif
5687 #endif
5688+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5689+ ZEND_FE(heap_overflow, NULL)
5690+#endif
5691 ZEND_FE(get_included_files, NULL)
5692 ZEND_FALIAS(get_required_files, get_included_files, NULL)
5693 ZEND_FE(is_subclass_of, NULL)
5694@@ -991,6 +997,19 @@
5695
5696 #endif /* ZEND_DEBUG */
5697
5698+
5699+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5700+ZEND_FUNCTION(heap_overflow)
5701+{
5702+ char *nowhere = emalloc(10);
5703+
5704+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
5705+
5706+ efree(nowhere);
5707+}
5708+#endif
5709+
5710+
5711 /* {{{ proto array get_included_files(void)
5712 Returns an array with the file names that were include_once()'d */
5713 ZEND_FUNCTION(get_included_files)
5714diff -Nura php-5.0.5/Zend/zend.c hardening-patch-5.0.5-0.4.5/Zend/zend.c
5715--- php-5.0.5/Zend/zend.c 2005-07-22 09:33:27.000000000 +0200
5716+++ hardening-patch-5.0.5-0.4.5/Zend/zend.c 2005-11-01 17:48:31.506494392 +0100
5717@@ -54,6 +54,12 @@
5718 ZEND_API void (*zend_unblock_interruptions)(void);
5719 ZEND_API void (*zend_ticks_function)(int ticks);
5720 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
5721+#if HARDENING_PATCH
5722+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
5723+#endif
5724+#if HARDENING_PATCH_INC_PROTECT
5725+ZEND_API int (*zend_is_valid_include)(zval *z);
5726+#endif
5727 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
5728
5729 void (*zend_on_timeout)(int seconds TSRMLS_DC);
5730@@ -72,9 +78,390 @@
5731 return SUCCESS;
5732 }
5733
5734+#if HARDENING_PATCH
5735+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
5736+{
5737+ if (!new_value) {
5738+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
5739+ } else {
5740+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
5741+ }
5742+ return SUCCESS;
5743+}
5744+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
5745+{
5746+ if (!new_value) {
5747+ EG(hphp_log_syslog_facility) = LOG_USER;
5748+ } else {
5749+ EG(hphp_log_syslog_facility) = atoi(new_value);
5750+ }
5751+ return SUCCESS;
5752+}
5753+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
5754+{
5755+ if (!new_value) {
5756+ EG(hphp_log_syslog_priority) = LOG_ALERT;
5757+ } else {
5758+ EG(hphp_log_syslog_priority) = atoi(new_value);
5759+ }
5760+ return SUCCESS;
5761+}
5762+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
5763+{
5764+ if (!new_value) {
5765+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
5766+ } else {
5767+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
5768+ }
5769+ return SUCCESS;
5770+}
5771+static ZEND_INI_MH(OnUpdateHPHP_log_script)
5772+{
5773+ if (!new_value) {
5774+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
5775+ } else {
5776+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
5777+ }
5778+ return SUCCESS;
5779+}
5780+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
5781+{
5782+ if (EG(hphp_log_scriptname)) {
5783+ pefree(EG(hphp_log_scriptname),1);
5784+ }
5785+ EG(hphp_log_scriptname) = NULL;
5786+ if (new_value) {
5787+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
5788+ }
5789+ return SUCCESS;
5790+}
5791+
5792+static ZEND_INI_MH(OnUpdateHPHP_include_whitelist)
5793+{
5794+ char *s = NULL, *e, *val;
5795+ unsigned long dummy = 1;
5796+
5797+ if (!new_value) {
5798+include_whitelist_destroy:
5799+ if (HG(include_whitelist)) {
5800+ zend_hash_destroy(HG(include_whitelist));
5801+ pefree(HG(include_whitelist),1);
5802+ }
5803+ HG(include_whitelist) = NULL;
5804+ return SUCCESS;
5805+ }
5806+ if (!(*new_value)) {
5807+ goto include_whitelist_destroy;
5808+ }
5809+
5810+ HG(include_whitelist) = pemalloc(sizeof(HashTable), 1);
5811+ zend_hash_init(HG(include_whitelist), 5, NULL, NULL, 1);
5812+
5813+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5814+ e = val;
5815+
5816+ while (*e) {
5817+ switch (*e) {
5818+ case ' ':
5819+ case ',':
5820+ if (s) {
5821+ *e = '\0';
5822+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5823+ s = NULL;
5824+ }
5825+ break;
5826+ default:
5827+ if (!s) {
5828+ s = e;
5829+ }
5830+ break;
5831+ }
5832+ e++;
5833+ }
5834+ if (s) {
5835+ zend_hash_add(HG(include_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5836+ }
5837+ efree(val);
5838+
5839+ return SUCCESS;
5840+}
5841+
5842+static ZEND_INI_MH(OnUpdateHPHP_include_blacklist)
5843+{
5844+ char *s = NULL, *e, *val;
5845+ unsigned long dummy = 1;
5846+
5847+ if (!new_value) {
5848+include_blacklist_destroy:
5849+ if (HG(include_blacklist)) {
5850+ zend_hash_destroy(HG(include_blacklist));
5851+ pefree(HG(include_blacklist),1);
5852+ }
5853+ HG(include_blacklist) = NULL;
5854+ return SUCCESS;
5855+ }
5856+ if (!(*new_value)) {
5857+ goto include_blacklist_destroy;
5858+ }
5859+
5860+ HG(include_blacklist) = pemalloc(sizeof(HashTable), 1);
5861+ zend_hash_init(HG(include_blacklist), 5, NULL, NULL, 1);
5862+
5863+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5864+ e = val;
5865+
5866+ while (*e) {
5867+ switch (*e) {
5868+ case ' ':
5869+ case ',':
5870+ if (s) {
5871+ *e = '\0';
5872+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5873+ s = NULL;
5874+ }
5875+ break;
5876+ default:
5877+ if (!s) {
5878+ s = e;
5879+ }
5880+ break;
5881+ }
5882+ e++;
5883+ }
5884+ if (s) {
5885+ zend_hash_add(HG(include_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5886+ }
5887+ efree(val);
5888+
5889+ return SUCCESS;
5890+}
5891+
5892+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
5893+{
5894+ char *s = NULL, *e, *val;
5895+ unsigned long dummy = 1;
5896+
5897+ if (!new_value) {
5898+eval_whitelist_destroy:
5899+ if (HG(eval_whitelist)) {
5900+ zend_hash_destroy(HG(eval_whitelist));
5901+ pefree(HG(eval_whitelist),1);
5902+ }
5903+ HG(eval_whitelist) = NULL;
5904+ return SUCCESS;
5905+ }
5906+ if (!(*new_value)) {
5907+ goto eval_whitelist_destroy;
5908+ }
5909+
5910+ HG(eval_whitelist) = pemalloc(sizeof(HashTable), 1);
5911+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 1);
5912+
5913+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5914+ e = val;
5915+
5916+ while (*e) {
5917+ switch (*e) {
5918+ case ' ':
5919+ case ',':
5920+ if (s) {
5921+ *e = '\0';
5922+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5923+ s = NULL;
5924+ }
5925+ break;
5926+ default:
5927+ if (!s) {
5928+ s = e;
5929+ }
5930+ break;
5931+ }
5932+ e++;
5933+ }
5934+ if (s) {
5935+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5936+ }
5937+ efree(val);
5938+
5939+ return SUCCESS;
5940+}
5941+
5942+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
5943+{
5944+ char *s = NULL, *e, *val;
5945+ unsigned long dummy = 1;
5946+
5947+ if (!new_value) {
5948+eval_blacklist_destroy:
5949+ if (HG(eval_blacklist)) {
5950+ zend_hash_destroy(HG(eval_blacklist));
5951+ pefree(HG(eval_blacklist), 1);
5952+ }
5953+ HG(eval_blacklist) = NULL;
5954+ return SUCCESS;
5955+ }
5956+ if (!(*new_value)) {
5957+ goto eval_blacklist_destroy;
5958+ }
5959+
5960+ HG(eval_blacklist) = pemalloc(sizeof(HashTable), 1);
5961+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 1);
5962+
5963+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5964+ e = val;
5965+
5966+ while (*e) {
5967+ switch (*e) {
5968+ case ' ':
5969+ case ',':
5970+ if (s) {
5971+ *e = '\0';
5972+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5973+ s = NULL;
5974+ }
5975+ break;
5976+ default:
5977+ if (!s) {
5978+ s = e;
5979+ }
5980+ break;
5981+ }
5982+ e++;
5983+ }
5984+ if (s) {
5985+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5986+ }
5987+ efree(val);
5988+
5989+
5990+ return SUCCESS;
5991+}
5992+
5993+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
5994+{
5995+ char *s = NULL, *e, *val;
5996+ unsigned long dummy = 1;
5997+
5998+ if (!new_value) {
5999+func_whitelist_destroy:
6000+ if (HG(func_whitelist)) {
6001+ zend_hash_destroy(HG(func_whitelist));
6002+ pefree(HG(func_whitelist),1);
6003+ }
6004+ HG(func_whitelist) = NULL;
6005+ return SUCCESS;
6006+ }
6007+ if (!(*new_value)) {
6008+ goto func_whitelist_destroy;
6009+ }
6010+
6011+ HG(func_whitelist) = pemalloc(sizeof(HashTable), 1);
6012+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 1);
6013+
6014+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6015+ e = val;
6016+
6017+ while (*e) {
6018+ switch (*e) {
6019+ case ' ':
6020+ case ',':
6021+ if (s) {
6022+ *e = '\0';
6023+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6024+ s = NULL;
6025+ }
6026+ break;
6027+ default:
6028+ if (!s) {
6029+ s = e;
6030+ }
6031+ break;
6032+ }
6033+ e++;
6034+ }
6035+ if (s) {
6036+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6037+ }
6038+ efree(val);
6039+
6040+ return SUCCESS;
6041+}
6042+
6043+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
6044+{
6045+ char *s = NULL, *e, *val;
6046+ unsigned long dummy = 1;
6047+
6048+ if (!new_value) {
6049+func_blacklist_destroy:
6050+ if (HG(func_blacklist)) {
6051+ zend_hash_destroy(HG(func_blacklist));
6052+ pefree(HG(func_blacklist),1);
6053+ }
6054+ HG(func_blacklist) = NULL;
6055+ return SUCCESS;
6056+ }
6057+ if (!(*new_value)) {
6058+ goto func_blacklist_destroy;
6059+ }
6060+
6061+ HG(func_blacklist) = pemalloc(sizeof(HashTable), 1);
6062+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 1);
6063+
6064+ val = zend_str_tolower_dup(new_value, strlen(new_value));
6065+ e = val;
6066+
6067+ while (*e) {
6068+ switch (*e) {
6069+ case ' ':
6070+ case ',':
6071+ if (s) {
6072+ *e = '\0';
6073+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6074+ s = NULL;
6075+ }
6076+ break;
6077+ default:
6078+ if (!s) {
6079+ s = e;
6080+ }
6081+ break;
6082+ }
6083+ e++;
6084+ }
6085+ if (s) {
6086+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
6087+ }
6088+ efree(val);
6089+
6090+
6091+ return SUCCESS;
6092+}
6093+
6094+#endif
6095
6096 ZEND_INI_BEGIN()
6097 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
6098+#if HARDENING_PATCH
6099+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
6100+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
6101+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
6102+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
6103+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
6104+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
6105+ 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)
6106+
6107+ ZEND_INI_ENTRY("hphp.executor.include.whitelist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_whitelist)
6108+ ZEND_INI_ENTRY("hphp.executor.include.blacklist", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_include_blacklist)
6109+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
6110+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
6111+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
6112+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
6113+
6114+ STD_ZEND_INI_ENTRY("hphp.executor.max_depth", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateLong, hphp_executor_max_depth, zend_executor_globals, executor_globals)
6115+ STD_ZEND_INI_BOOLEAN("hphp.sql.bailout_on_error", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_sql_bailout_on_error, hardened_globals_struct, hardened_globals)
6116+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
6117+#endif
6118 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
6119 ZEND_INI_END()
6120
6121@@ -476,9 +863,13 @@
6122 EG(user_error_handler) = NULL;
6123 EG(user_exception_handler) = NULL;
6124 EG(in_execution) = 0;
6125+ EG(in_code_type) = 0;
6126 EG(in_autoload) = NULL;
6127 EG(current_execute_data) = NULL;
6128 EG(current_module) = NULL;
6129+#if HARDENING_PATCH
6130+ EG(hphp_log_scriptname) = NULL;
6131+#endif
6132 }
6133
6134
6135@@ -545,6 +936,14 @@
6136 extern zend_scanner_globals language_scanner_globals;
6137 #endif
6138
6139+ /* Set up Hardening-Patch utility functions first */
6140+#if HARDENING_PATCH
6141+ zend_security_log = utility_functions->security_log_function;
6142+#endif
6143+#if HARDENING_PATCH_INC_PROTECT
6144+ zend_is_valid_include = utility_functions->is_valid_include;
6145+#endif
6146+
6147 #ifdef ZTS
6148 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
6149 #else
6150@@ -747,6 +1146,7 @@
6151 }
6152 CG(unclean_shutdown) = 1;
6153 CG(in_compilation) = EG(in_execution) = 0;
6154+ EG(in_code_type) = 0;
6155 EG(current_execute_data) = NULL;
6156 longjmp(EG(bailout), FAILURE);
6157 }
6158diff -Nura php-5.0.5/Zend/zend_canary.c hardening-patch-5.0.5-0.4.5/Zend/zend_canary.c
6159--- php-5.0.5/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
6160+++ hardening-patch-5.0.5-0.4.5/Zend/zend_canary.c 2005-11-01 14:23:05.971260560 +0100
6161@@ -0,0 +1,58 @@
6162+/*
6163+ +----------------------------------------------------------------------+
6164+ | Hardening-Patch for PHP |
6165+ +----------------------------------------------------------------------+
6166+ | Copyright (c) 2004-2005 Stefan Esser |
6167+ +----------------------------------------------------------------------+
6168+ | This source file is subject to version 2.02 of the PHP license, |
6169+ | that is bundled with this package in the file LICENSE, and is |
6170+ | available at through the world-wide-web at |
6171+ | http://www.php.net/license/2_02.txt. |
6172+ | If you did not receive a copy of the PHP license and are unable to |
6173+ | obtain it through the world-wide-web, please send a note to |
6174+ | license@php.net so we can mail you a copy immediately. |
6175+ +----------------------------------------------------------------------+
6176+ | Author: Stefan Esser <sesser@hardened-php.net> |
6177+ +----------------------------------------------------------------------+
6178+ */
6179+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
6180+
6181+#include "zend.h"
6182+
6183+#include <stdio.h>
6184+#include <stdlib.h>
6185+
6186+
6187+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6188+
6189+/* will be replaced later with more compatible method */
6190+ZEND_API unsigned int zend_canary()
6191+{
6192+ time_t t;
6193+ unsigned int canary;
6194+ int fd;
6195+
6196+ fd = open("/dev/urandom", 0);
6197+ if (fd != -1) {
6198+ int r = read(fd, &canary, sizeof(canary));
6199+ close(fd);
6200+ if (r == sizeof(canary)) {
6201+ return (canary);
6202+ }
6203+ }
6204+ /* not good but we never want to do this */
6205+ time(&t);
6206+ canary = *(unsigned int *)&t + getpid() << 16;
6207+ return (canary);
6208+}
6209+#endif
6210+
6211+
6212+/*
6213+ * Local variables:
6214+ * tab-width: 4
6215+ * c-basic-offset: 4
6216+ * End:
6217+ * vim600: sw=4 ts=4 fdm=marker
6218+ * vim<600: sw=4 ts=4
6219+ */
6220diff -Nura php-5.0.5/Zend/zend_compile.c hardening-patch-5.0.5-0.4.5/Zend/zend_compile.c
6221--- php-5.0.5/Zend/zend_compile.c 2005-07-19 09:33:24.000000000 +0200
6222+++ hardening-patch-5.0.5-0.4.5/Zend/zend_compile.c 2005-11-01 14:23:05.972260408 +0100
6223@@ -979,6 +979,13 @@
6224 op_array.prototype = NULL;
6225
6226 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
6227+#if HARDENING_PATCH
6228+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6229+ op_array.created_by_eval = 1;
6230+ } else {
6231+ op_array.created_by_eval = 0;
6232+ }
6233+#endif
6234
6235 if (is_method) {
6236 char *short_class_name = CG(active_class_entry)->name;
6237diff -Nura php-5.0.5/Zend/zend_compile.h hardening-patch-5.0.5-0.4.5/Zend/zend_compile.h
6238--- php-5.0.5/Zend/zend_compile.h 2005-06-24 10:45:43.000000000 +0200
6239+++ hardening-patch-5.0.5-0.4.5/Zend/zend_compile.h 2005-11-01 14:23:05.973260256 +0100
6240@@ -203,6 +203,9 @@
6241 zend_uint doc_comment_len;
6242
6243 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
6244+#if HARDENING_PATCH
6245+ zend_bool created_by_eval;
6246+#endif
6247 };
6248
6249
6250@@ -281,6 +284,8 @@
6251 zval *object;
6252 union _temp_variable *Ts;
6253 zend_bool original_in_execution;
6254+ zend_uint original_in_code_type;
6255+ zend_uint execute_depth;
6256 zend_class_entry *calling_scope;
6257 struct _zend_execute_data *prev_execute_data;
6258 };
6259@@ -774,6 +779,7 @@
6260 #define ZEND_OVERLOADED_FUNCTION 3
6261 #define ZEND_EVAL_CODE 4
6262 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
6263+#define ZEND_SANDBOX_CODE 6
6264
6265 #define ZEND_INTERNAL_CLASS 1
6266 #define ZEND_USER_CLASS 2
6267diff -Nura php-5.0.5/Zend/zend_constants.c hardening-patch-5.0.5-0.4.5/Zend/zend_constants.c
6268--- php-5.0.5/Zend/zend_constants.c 2004-07-13 21:22:11.000000000 +0200
6269+++ hardening-patch-5.0.5-0.4.5/Zend/zend_constants.c 2005-11-01 14:23:05.974260104 +0100
6270@@ -107,6 +107,73 @@
6271 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
6272
6273 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
6274+#if HARDENING_PATCH
6275+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
6276+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
6277+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
6278+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
6279+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
6280+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
6281+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
6282+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
6283+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
6284+
6285+ /* error levels */
6286+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
6287+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
6288+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
6289+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
6290+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
6291+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
6292+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
6293+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
6294+ /* facility: type of program logging the message */
6295+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
6296+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
6297+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
6298+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
6299+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
6300+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
6301+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
6302+#ifdef LOG_NEWS
6303+ /* No LOG_NEWS on HP-UX */
6304+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
6305+#endif
6306+#ifdef LOG_UUCP
6307+ /* No LOG_UUCP on HP-UX */
6308+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
6309+#endif
6310+#ifdef LOG_CRON
6311+ /* apparently some systems don't have this one */
6312+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
6313+#endif
6314+#ifdef LOG_AUTHPRIV
6315+ /* AIX doesn't have LOG_AUTHPRIV */
6316+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
6317+#endif
6318+#if !defined(PHP_WIN32) && !defined(NETWARE)
6319+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
6320+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
6321+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
6322+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
6323+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
6324+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
6325+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
6326+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
6327+#endif
6328+ /* options */
6329+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
6330+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
6331+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
6332+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
6333+#ifdef LOG_NOWAIT
6334+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
6335+#endif
6336+#ifdef LOG_PERROR
6337+ /* AIX doesn't have LOG_PERROR */
6338+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
6339+#endif
6340+#endif
6341
6342 /* true/false constants */
6343 {
6344diff -Nura php-5.0.5/Zend/zend_errors.h hardening-patch-5.0.5-0.4.5/Zend/zend_errors.h
6345--- php-5.0.5/Zend/zend_errors.h 2004-01-08 18:31:47.000000000 +0100
6346+++ hardening-patch-5.0.5-0.4.5/Zend/zend_errors.h 2005-11-01 14:23:05.974260104 +0100
6347@@ -38,6 +38,18 @@
6348 #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)
6349 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
6350
6351+#if HARDENING_PATCH
6352+#define S_MEMORY (1<<0L)
6353+#define S_VARS (1<<1L)
6354+#define S_FILES (1<<2L)
6355+#define S_INCLUDE (1<<3L)
6356+#define S_SQL (1<<4L)
6357+#define S_EXECUTOR (1<<5L)
6358+#define S_MISC (1<<30L)
6359+#define S_INTERNAL (1<<29L)
6360+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
6361+#endif
6362+
6363 #endif /* ZEND_ERRORS_H */
6364
6365 /*
6366diff -Nura php-5.0.5/Zend/zend_execute_API.c hardening-patch-5.0.5-0.4.5/Zend/zend_execute_API.c
6367--- php-5.0.5/Zend/zend_execute_API.c 2005-09-02 09:46:39.000000000 +0200
6368+++ hardening-patch-5.0.5-0.4.5/Zend/zend_execute_API.c 2005-11-01 14:23:05.975259952 +0100
6369@@ -137,6 +137,7 @@
6370 EG(class_table) = CG(class_table);
6371
6372 EG(in_execution) = 0;
6373+ EG(in_code_type) = 0;
6374 EG(in_autoload) = NULL;
6375
6376 zend_ptr_stack_init(&EG(argument_stack));
6377@@ -725,6 +726,39 @@
6378 if (zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
6379 EX(function_state).function = NULL;
6380 }
6381+#if HARDENING_PATCH
6382+ else {
6383+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6384+ if (HG(eval_whitelist) != NULL) {
6385+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6386+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
6387+ efree(function_name_lc);
6388+ zend_bailout();
6389+ }
6390+ } else if (HG(eval_blacklist) != NULL) {
6391+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6392+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
6393+ efree(function_name_lc);
6394+ zend_bailout();
6395+ }
6396+ }
6397+ }
6398+
6399+ if (HG(func_whitelist) != NULL) {
6400+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
6401+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
6402+ efree(function_name_lc);
6403+ zend_bailout();
6404+ }
6405+ } else if (HG(func_blacklist) != NULL) {
6406+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
6407+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
6408+ efree(function_name_lc);
6409+ zend_bailout();
6410+ }
6411+ }
6412+ }
6413+#endif
6414 efree(function_name_lc);
6415 }
6416
6417@@ -999,7 +1033,7 @@
6418 return retval;
6419 }
6420
6421-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6422+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
6423 {
6424 zval pv;
6425 zend_op_array *new_op_array;
6426@@ -1032,6 +1066,7 @@
6427 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
6428 zend_op **original_opline_ptr = EG(opline_ptr);
6429
6430+ new_op_array->type = type;
6431 EG(return_value_ptr_ptr) = &local_retval_ptr;
6432 EG(active_op_array) = new_op_array;
6433 EG(no_extensions)=1;
6434@@ -1066,6 +1101,12 @@
6435 }
6436
6437
6438+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
6439+{
6440+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
6441+}
6442+
6443+
6444 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
6445 {
6446 int result;
6447diff -Nura php-5.0.5/Zend/zend_execute.c hardening-patch-5.0.5-0.4.5/Zend/zend_execute.c
6448--- php-5.0.5/Zend/zend_execute.c 2005-09-01 15:21:56.000000000 +0200
6449+++ hardening-patch-5.0.5-0.4.5/Zend/zend_execute.c 2005-11-01 14:23:05.978259496 +0100
6450@@ -1374,6 +1374,7 @@
6451 efree(EX(Ts)); \
6452 } \
6453 EG(in_execution) = EX(original_in_execution); \
6454+ EG(in_code_type) = EX(original_in_code_type); \
6455 EG(current_execute_data) = EX(prev_execute_data); \
6456 return 1; /* CHECK_ME */
6457
6458@@ -1400,6 +1401,16 @@
6459 EX(original_in_execution) = EG(in_execution);
6460 EX(prev_execute_data) = EG(current_execute_data);
6461 EG(current_execute_data) = &execute_data;
6462+#if HARDENING_PATCH
6463+ EX(execute_depth) = 0;
6464+
6465+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
6466+ EG(in_code_type) = ZEND_EVAL_CODE;
6467+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
6468+ EG(in_code_type) = ZEND_SANDBOX_CODE;
6469+ op_array->type = ZEND_EVAL_CODE;
6470+ }
6471+#endif
6472
6473 EG(in_execution) = 1;
6474 if (op_array->start_op) {
6475@@ -1426,6 +1437,19 @@
6476 EX(function_state).function_symbol_table = NULL;
6477 #endif
6478
6479+#if HARDENING_PATCH
6480+ if (EX(prev_execute_data) == NULL) {
6481+ EX(execute_depth) = 0;
6482+ } else {
6483+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
6484+ }
6485+
6486+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
6487+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
6488+ zend_bailout();
6489+ }
6490+#endif
6491+
6492 while (1) {
6493 #ifdef ZEND_WIN32
6494 if (EG(timed_out)) {
6495@@ -2680,6 +2704,37 @@
6496 efree(lcname);
6497 zend_error(E_ERROR, "Call to undefined function %s()", function_name_strval);
6498 }
6499+#if HARDENING_PATCH
6500+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6501+ if (HG(eval_whitelist) != NULL) {
6502+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
6503+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
6504+ efree(lcname);
6505+ zend_bailout();
6506+ }
6507+ } else if (HG(eval_blacklist) != NULL) {
6508+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
6509+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
6510+ efree(lcname);
6511+ zend_bailout();
6512+ }
6513+ }
6514+ }
6515+
6516+ if (HG(func_whitelist) != NULL) {
6517+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
6518+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
6519+ efree(lcname);
6520+ zend_bailout();
6521+ }
6522+ } else if (HG(func_blacklist) != NULL) {
6523+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
6524+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
6525+ efree(lcname);
6526+ zend_bailout();
6527+ }
6528+ }
6529+#endif
6530
6531 efree(lcname);
6532 if (!is_const) {
6533@@ -2886,6 +2941,34 @@
6534 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
6535 zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val);
6536 }
6537+#if HARDENING_PATCH
6538+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
6539+ if (HG(eval_whitelist) != NULL) {
6540+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
6541+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
6542+ zend_bailout();
6543+ }
6544+ } else if (HG(eval_blacklist) != NULL) {
6545+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
6546+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
6547+ zend_bailout();
6548+ }
6549+ }
6550+ }
6551+
6552+ if (HG(func_whitelist) != NULL) {
6553+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
6554+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
6555+ zend_bailout();
6556+ }
6557+ } else if (HG(func_blacklist) != NULL) {
6558+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
6559+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
6560+ zend_bailout();
6561+ }
6562+ }
6563+#endif
6564+
6565 EX(object) = NULL;
6566 EX(calling_scope) = EX(function_state).function->common.scope;
6567
6568@@ -3573,7 +3656,12 @@
6569 int dummy = 1;
6570 zend_file_handle file_handle;
6571
6572+#if HARDENING_PATCH_INC_PROTECT
6573+ if (zend_is_valid_include(inc_filename)
6574+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
6575+#else
6576 if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
6577+#endif
6578
6579 if (!file_handle.opened_path) {
6580 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
6581@@ -3598,6 +3686,11 @@
6582 break;
6583 case ZEND_INCLUDE:
6584 case ZEND_REQUIRE:
6585+#if HARDENING_PATCH_INC_PROTECT
6586+ if (!zend_is_valid_include(inc_filename)) {
6587+ break;
6588+ }
6589+#endif
6590 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
6591 break;
6592 case ZEND_EVAL: {
6593diff -Nura php-5.0.5/Zend/zend_extensions.c hardening-patch-5.0.5-0.4.5/Zend/zend_extensions.c
6594--- php-5.0.5/Zend/zend_extensions.c 2004-01-08 18:31:47.000000000 +0100
6595+++ hardening-patch-5.0.5-0.4.5/Zend/zend_extensions.c 2005-11-01 14:23:05.979259344 +0100
6596@@ -55,23 +55,44 @@
6597 return FAILURE;
6598 }
6599
6600+ /* check if module is compiled against Hardening-Patch */
6601+ if (extension_version_info->zend_extension_api_no < 1000000000) {
6602+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
6603+ "The Hardening-Patch version %d is installed.\n\n",
6604+ new_extension->name,
6605+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
6606+ DL_UNLOAD(handle);
6607+ return FAILURE;
6608+ }
6609+
6610+
6611+ /* check if module is compiled against correct Hardening-Patch version */
6612+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
6613+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
6614+ "The Hardening-Patch version %d is installed.\n\n",
6615+ new_extension->name,
6616+ extension_version_info->zend_extension_api_no,
6617+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
6618+ DL_UNLOAD(handle);
6619+ return FAILURE;
6620+ }
6621
6622 /* allow extension to proclaim compatibility with any Zend version */
6623- if (extension_version_info->zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
6624- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
6625+ if (extension_version_info->real_zend_extension_api_no != ZEND_EXTENSION_API_NO &&(!new_extension->api_no_check || new_extension->api_no_check(ZEND_EXTENSION_API_NO) != SUCCESS)) {
6626+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
6627 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
6628 "The Zend Engine API version %d which is installed, is outdated.\n\n",
6629 new_extension->name,
6630- extension_version_info->zend_extension_api_no,
6631+ extension_version_info->real_zend_extension_api_no,
6632 ZEND_EXTENSION_API_NO);
6633 DL_UNLOAD(handle);
6634 return FAILURE;
6635- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
6636+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
6637 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
6638 "The Zend Engine API version %d which is installed, is newer.\n"
6639 "Contact %s at %s for a later version of %s.\n\n",
6640 new_extension->name,
6641- extension_version_info->zend_extension_api_no,
6642+ extension_version_info->real_zend_extension_api_no,
6643 ZEND_EXTENSION_API_NO,
6644 new_extension->author,
6645 new_extension->URL,
6646diff -Nura php-5.0.5/Zend/zend_extensions.h hardening-patch-5.0.5-0.4.5/Zend/zend_extensions.h
6647--- php-5.0.5/Zend/zend_extensions.h 2004-11-25 21:26:48.000000000 +0100
6648+++ hardening-patch-5.0.5-0.4.5/Zend/zend_extensions.h 2005-11-01 14:23:05.979259344 +0100
6649@@ -24,9 +24,11 @@
6650
6651 #include "zend_compile.h"
6652
6653-/* The first number is the engine version and the rest is the date.
6654+/* The first API number is a flag saying that Hardening-Patch is used.
6655+ * The second number is the engine version and the date.
6656 * This way engine 2 API no. is always greater than engine 1 API no..
6657 */
6658+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1002050805
6659 #define ZEND_EXTENSION_API_NO 220040412
6660
6661 typedef struct _zend_extension_version_info {
6662@@ -34,6 +36,7 @@
6663 char *required_zend_version;
6664 unsigned char thread_safe;
6665 unsigned char debug;
6666+ int real_zend_extension_api_no;
6667 } zend_extension_version_info;
6668
6669
6670@@ -101,7 +104,7 @@
6671
6672
6673 #define ZEND_EXTENSION() \
6674- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
6675+ ZEND_EXT_API zend_extension_version_info extension_version_info = { HARDENING_PATCH_ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG, ZEND_EXTENSION_API_NO }
6676
6677 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6678 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6679diff -Nura php-5.0.5/Zend/zend_globals.h hardening-patch-5.0.5-0.4.5/Zend/zend_globals.h
6680--- php-5.0.5/Zend/zend_globals.h 2004-11-04 00:14:31.000000000 +0100
6681+++ hardening-patch-5.0.5-0.4.5/Zend/zend_globals.h 2005-11-01 14:23:05.979259344 +0100
6682@@ -174,6 +174,16 @@
6683
6684 int error_reporting;
6685 int orig_error_reporting;
6686+#if HARDENING_PATCH
6687+ int hphp_log_syslog;
6688+ int hphp_log_syslog_facility;
6689+ int hphp_log_syslog_priority;
6690+ int hphp_log_sapi;
6691+ int hphp_log_script;
6692+ char *hphp_log_scriptname;
6693+ zend_bool hphp_log_use_x_forwarded_for;
6694+ long hphp_executor_max_depth;
6695+#endif
6696 int exit_status;
6697
6698 zend_op_array *active_op_array;
6699@@ -191,6 +201,7 @@
6700 int ticks_count;
6701
6702 zend_bool in_execution;
6703+ zend_uint in_code_type;
6704 HashTable *in_autoload;
6705 zend_bool bailout_set;
6706 zend_bool full_tables_cleanup;
6707diff -Nura php-5.0.5/Zend/zend.h hardening-patch-5.0.5-0.4.5/Zend/zend.h
6708--- php-5.0.5/Zend/zend.h 2005-08-25 19:41:08.000000000 +0200
6709+++ hardening-patch-5.0.5-0.4.5/Zend/zend.h 2005-11-01 14:23:05.980259192 +0100
6710@@ -290,6 +290,7 @@
6711 /* Variable information */
6712 zvalue_value value; /* value */
6713 zend_uint refcount;
6714+ zend_ushort flags;
6715 zend_uchar type; /* active type */
6716 zend_uchar is_ref;
6717 };
6718@@ -359,6 +360,12 @@
6719 void (*on_timeout)(int seconds TSRMLS_DC);
6720 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
6721 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
6722+#if HARDENING_PATCH
6723+ void (*security_log_function)(int loglevel, char *fmt, ...);
6724+#endif
6725+#if HARDENING_PATCH_INC_PROTECT
6726+ int (*is_valid_include)(zval *z);
6727+#endif
6728 } zend_utility_functions;
6729
6730
6731@@ -497,6 +504,16 @@
6732 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
6733 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
6734 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
6735+#if HARDENING_PATCH
6736+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6737+#endif
6738+#if HARDENING_PATCH_INC_PROTECT
6739+extern ZEND_API int (*zend_is_valid_include)(zval *z);
6740+#endif
6741+
6742+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6743+ZEND_API unsigned int zend_canary(void);
6744+#endif
6745
6746
6747 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
6748@@ -621,6 +638,11 @@
6749 #define ZEND_MAX_RESERVED_RESOURCES 4
6750
6751
6752+#if HARDENING_PATCH
6753+#include "hardened_globals.h"
6754+#include "php_syslog.h"
6755+#endif
6756+
6757 #endif /* ZEND_H */
6758
6759 /*
6760diff -Nura php-5.0.5/Zend/zend_hash.c hardening-patch-5.0.5-0.4.5/Zend/zend_hash.c
6761--- php-5.0.5/Zend/zend_hash.c 2005-04-25 08:11:00.000000000 +0200
6762+++ hardening-patch-5.0.5-0.4.5/Zend/zend_hash.c 2005-11-01 14:23:05.981259040 +0100
6763@@ -21,6 +21,18 @@
6764
6765 #include "zend.h"
6766
6767+#if HARDENING_PATCH_HASH_PROTECT
6768+ unsigned int zend_hash_canary = 0x1234567;
6769+ zend_bool zend_hash_canary_inited = 0;
6770+#endif
6771+
6772+#define CHECK_HASH_CANARY(hash) \
6773+ if (zend_hash_canary != (hash)->canary) { \
6774+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
6775+ exit(1); \
6776+ }
6777+
6778+
6779 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
6780 (element)->pNext = (list_head); \
6781 (element)->pLast = NULL; \
6782@@ -138,6 +150,9 @@
6783 {
6784 uint i = 3;
6785 Bucket **tmp;
6786+#if HARDENING_PATCH_HASH_PROTECT
6787+ TSRMLS_FETCH();
6788+#endif
6789
6790 SET_INCONSISTENT(HT_OK);
6791
6792@@ -147,6 +162,13 @@
6793
6794 ht->nTableSize = 1 << i;
6795 ht->nTableMask = ht->nTableSize - 1;
6796+#if HARDENING_PATCH_HASH_PROTECT
6797+ if (zend_hash_canary_inited==0) {
6798+ zend_hash_canary = zend_canary();
6799+ zend_hash_canary_inited = 1;
6800+ }
6801+ ht->canary = zend_hash_canary;
6802+#endif
6803 ht->pDestructor = pDestructor;
6804 ht->arBuckets = NULL;
6805 ht->pListHead = NULL;
6806@@ -226,6 +248,9 @@
6807 }
6808 #endif
6809 if (ht->pDestructor) {
6810+#if HARDENING_PATCH_HASH_PROTECT
6811+ CHECK_HASH_CANARY(ht);
6812+#endif
6813 ht->pDestructor(p->pData);
6814 }
6815 UPDATE_DATA(ht, p, pData, nDataSize);
6816@@ -291,6 +316,9 @@
6817 }
6818 #endif
6819 if (ht->pDestructor) {
6820+#if HARDENING_PATCH_HASH_PROTECT
6821+ CHECK_HASH_CANARY(ht);
6822+#endif
6823 ht->pDestructor(p->pData);
6824 }
6825 UPDATE_DATA(ht, p, pData, nDataSize);
6826@@ -366,6 +394,9 @@
6827 }
6828 #endif
6829 if (ht->pDestructor) {
6830+#if HARDENING_PATCH_HASH_PROTECT
6831+ CHECK_HASH_CANARY(ht);
6832+#endif
6833 ht->pDestructor(p->pData);
6834 }
6835 UPDATE_DATA(ht, p, pData, nDataSize);
6836@@ -414,7 +445,7 @@
6837 IS_CONSISTENT(ht);
6838
6839 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
6840- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6841+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6842 if (t) {
6843 HANDLE_BLOCK_INTERRUPTIONS();
6844 ht->arBuckets = t;
6845@@ -424,6 +455,7 @@
6846 HANDLE_UNBLOCK_INTERRUPTIONS();
6847 return SUCCESS;
6848 }
6849+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
6850 return FAILURE;
6851 }
6852 return SUCCESS;
6853@@ -487,6 +519,9 @@
6854 ht->pInternalPointer = p->pListNext;
6855 }
6856 if (ht->pDestructor) {
6857+#if HARDENING_PATCH_HASH_PROTECT
6858+ CHECK_HASH_CANARY(ht);
6859+#endif
6860 ht->pDestructor(p->pData);
6861 }
6862 if (!p->pDataPtr) {
6863@@ -516,6 +551,9 @@
6864 q = p;
6865 p = p->pListNext;
6866 if (ht->pDestructor) {
6867+#if HARDENING_PATCH_HASH_PROTECT
6868+ CHECK_HASH_CANARY(ht);
6869+#endif
6870 ht->pDestructor(q->pData);
6871 }
6872 if (!q->pDataPtr && q->pData) {
6873@@ -542,6 +580,9 @@
6874 q = p;
6875 p = p->pListNext;
6876 if (ht->pDestructor) {
6877+#if HARDENING_PATCH_HASH_PROTECT
6878+ CHECK_HASH_CANARY(ht);
6879+#endif
6880 ht->pDestructor(q->pData);
6881 }
6882 if (!q->pDataPtr && q->pData) {
6883@@ -571,6 +612,9 @@
6884 HANDLE_BLOCK_INTERRUPTIONS();
6885
6886 if (ht->pDestructor) {
6887+#if HARDENING_PATCH_HASH_PROTECT
6888+ CHECK_HASH_CANARY(ht);
6889+#endif
6890 ht->pDestructor(p->pData);
6891 }
6892 if (!p->pDataPtr) {
6893diff -Nura php-5.0.5/Zend/zend_hash.h hardening-patch-5.0.5-0.4.5/Zend/zend_hash.h
6894--- php-5.0.5/Zend/zend_hash.h 2004-01-08 18:31:47.000000000 +0100
6895+++ hardening-patch-5.0.5-0.4.5/Zend/zend_hash.h 2005-11-01 14:23:05.981259040 +0100
6896@@ -58,6 +58,9 @@
6897 } Bucket;
6898
6899 typedef struct _hashtable {
6900+#if HARDENING_PATCH_HASH_PROTECT
6901+ unsigned int canary;
6902+#endif
6903 uint nTableSize;
6904 uint nTableMask;
6905 uint nNumOfElements;
6906diff -Nura php-5.0.5/Zend/zend_language_scanner.c hardening-patch-5.0.5-0.4.5/Zend/zend_language_scanner.c
6907--- php-5.0.5/Zend/zend_language_scanner.c 2005-09-05 13:16:27.000000000 +0200
6908+++ hardening-patch-5.0.5-0.4.5/Zend/zend_language_scanner.c 2005-11-01 14:23:05.985258432 +0100
6909@@ -3153,6 +3153,13 @@
6910 compilation_successful=0;
6911 } else {
6912 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
6913+#if HARDENING_PATCH
6914+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6915+ op_array->created_by_eval = 1;
6916+ } else {
6917+ op_array->created_by_eval = 0;
6918+ }
6919+#endif
6920 CG(in_compilation) = 1;
6921 CG(active_op_array) = op_array;
6922 compiler_result = zendparse(TSRMLS_C);
6923diff -Nura php-5.0.5/Zend/zend_language_scanner.l hardening-patch-5.0.5-0.4.5/Zend/zend_language_scanner.l
6924--- php-5.0.5/Zend/zend_language_scanner.l 2005-06-09 10:54:24.000000000 +0200
6925+++ hardening-patch-5.0.5-0.4.5/Zend/zend_language_scanner.l 2005-11-01 14:23:05.982258888 +0100
6926@@ -386,6 +386,13 @@
6927 compilation_successful=0;
6928 } else {
6929 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
6930+#if HARDENING_PATCH
6931+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6932+ op_array->created_by_eval = 1;
6933+ } else {
6934+ op_array->created_by_eval = 0;
6935+ }
6936+#endif
6937 CG(in_compilation) = 1;
6938 CG(active_op_array) = op_array;
6939 compiler_result = zendparse(TSRMLS_C);
6940diff -Nura php-5.0.5/Zend/zend_llist.c hardening-patch-5.0.5-0.4.5/Zend/zend_llist.c
6941--- php-5.0.5/Zend/zend_llist.c 2004-01-08 18:31:47.000000000 +0100
6942+++ hardening-patch-5.0.5-0.4.5/Zend/zend_llist.c 2005-11-01 14:23:05.987258128 +0100
6943@@ -22,9 +22,34 @@
6944 #include "zend.h"
6945 #include "zend_llist.h"
6946 #include "zend_qsort.h"
6947+#include "zend_globals.h"
6948+
6949+#define CHECK_LIST_CANARY(list) \
6950+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
6951+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
6952+ exit(1); \
6953+ }
6954+
6955+#define CHECK_LISTELEMENT_CANARY(elem) \
6956+ if (HG(canary_3) != (elem)->canary) { \
6957+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
6958+ exit(1); \
6959+ }
6960+
6961
6962 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
6963 {
6964+#if HARDENING_PATCH_LL_PROTECT
6965+ TSRMLS_FETCH();
6966+
6967+ if (!HG(ll_canary_inited)) {
6968+ HG(canary_3) = zend_canary();
6969+ HG(canary_4) = zend_canary();
6970+ HG(ll_canary_inited) = 1;
6971+ }
6972+ l->canary_h = HG(canary_3);
6973+ l->canary_t = HG(canary_4);
6974+#endif
6975 l->head = NULL;
6976 l->tail = NULL;
6977 l->count = 0;
6978@@ -38,6 +63,11 @@
6979 {
6980 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
6981
6982+#if HARDENING_PATCH_LL_PROTECT
6983+ TSRMLS_FETCH();
6984+ CHECK_LIST_CANARY(l)
6985+ tmp->canary = HG(canary_3);
6986+#endif
6987 tmp->prev = l->tail;
6988 tmp->next = NULL;
6989 if (l->tail) {
6990@@ -56,6 +86,11 @@
6991 {
6992 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
6993
6994+#if HARDENING_PATCH_LL_PROTECT
6995+ TSRMLS_FETCH();
6996+ CHECK_LIST_CANARY(l)
6997+ tmp->canary = HG(canary_3);
6998+#endif
6999 tmp->next = l->head;
7000 tmp->prev = NULL;
7001 if (l->head) {
7002@@ -93,10 +128,20 @@
7003 zend_llist_element *current=l->head;
7004 zend_llist_element *next;
7005
7006+#if HARDENING_PATCH_LL_PROTECT
7007+ TSRMLS_FETCH();
7008+ CHECK_LIST_CANARY(l)
7009+#endif
7010 while (current) {
7011+#if HARDENING_PATCH_LL_PROTECT
7012+ CHECK_LISTELEMENT_CANARY(current)
7013+#endif
7014 next = current->next;
7015 if (compare(current->data, element)) {
7016 DEL_LLIST_ELEMENT(current, l);
7017+#if HARDENING_PATCH_LL_PROTECT
7018+ current->canary = 0;
7019+#endif
7020 break;
7021 }
7022 current = next;
7023@@ -108,7 +153,14 @@
7024 {
7025 zend_llist_element *current=l->head, *next;
7026
7027+#if HARDENING_PATCH_LL_PROTECT
7028+ TSRMLS_FETCH();
7029+ CHECK_LIST_CANARY(l)
7030+#endif
7031 while (current) {
7032+#if HARDENING_PATCH_LL_PROTECT
7033+ CHECK_LISTELEMENT_CANARY(current)
7034+#endif
7035 next = current->next;
7036 if (l->dtor) {
7037 l->dtor(current->data);
7038@@ -133,7 +185,14 @@
7039 zend_llist_element *old_tail;
7040 void *data;
7041
7042+#if HARDENING_PATCH_LL_PROTECT
7043+ TSRMLS_FETCH();
7044+ CHECK_LIST_CANARY(l)
7045+#endif
7046 if ((old_tail = l->tail)) {
7047+#if HARDENING_PATCH_LL_PROTECT
7048+ CHECK_LISTELEMENT_CANARY(old_tail)
7049+#endif
7050 if (l->tail->prev) {
7051 l->tail->prev->next = NULL;
7052 }
7053@@ -159,9 +218,16 @@
7054 {
7055 zend_llist_element *ptr;
7056
7057+#if HARDENING_PATCH_LL_PROTECT
7058+ TSRMLS_FETCH();
7059+ CHECK_LIST_CANARY(src)
7060+#endif
7061 zend_llist_init(dst, src->size, src->dtor, src->persistent);
7062 ptr = src->head;
7063 while (ptr) {
7064+#if HARDENING_PATCH_LL_PROTECT
7065+ CHECK_LISTELEMENT_CANARY(ptr)
7066+#endif
7067 zend_llist_add_element(dst, ptr->data);
7068 ptr = ptr->next;
7069 }
7070@@ -172,11 +238,21 @@
7071 {
7072 zend_llist_element *element, *next;
7073
7074+#if HARDENING_PATCH_LL_PROTECT
7075+ TSRMLS_FETCH();
7076+ CHECK_LIST_CANARY(l)
7077+#endif
7078 element=l->head;
7079 while (element) {
7080+#if HARDENING_PATCH_LL_PROTECT
7081+ CHECK_LISTELEMENT_CANARY(element)
7082+#endif
7083 next = element->next;
7084 if (func(element->data)) {
7085 DEL_LLIST_ELEMENT(element, l);
7086+#if HARDENING_PATCH_LL_PROTECT
7087+ element->canary = 0;
7088+#endif
7089 }
7090 element = next;
7091 }
7092@@ -187,7 +263,13 @@
7093 {
7094 zend_llist_element *element;
7095
7096+#if HARDENING_PATCH_LL_PROTECT
7097+ CHECK_LIST_CANARY(l)
7098+#endif
7099 for (element=l->head; element; element=element->next) {
7100+#if HARDENING_PATCH_LL_PROTECT
7101+ CHECK_LISTELEMENT_CANARY(element)
7102+#endif
7103 func(element->data TSRMLS_CC);
7104 }
7105 }
7106@@ -199,6 +281,9 @@
7107 zend_llist_element **elements;
7108 zend_llist_element *element, **ptr;
7109
7110+#if HARDENING_PATCH_LL_PROTECT
7111+ CHECK_LIST_CANARY(l)
7112+#endif
7113 if (l->count <= 0) {
7114 return;
7115 }
7116@@ -208,6 +293,9 @@
7117 ptr = &elements[0];
7118
7119 for (element=l->head; element; element=element->next) {
7120+#if HARDENING_PATCH_LL_PROTECT
7121+ CHECK_LISTELEMENT_CANARY(element)
7122+#endif
7123 *ptr++ = element;
7124 }
7125
7126@@ -230,7 +318,13 @@
7127 {
7128 zend_llist_element *element;
7129
7130+#if HARDENING_PATCH_LL_PROTECT
7131+ CHECK_LIST_CANARY(l)
7132+#endif
7133 for (element=l->head; element; element=element->next) {
7134+#if HARDENING_PATCH_LL_PROTECT
7135+ CHECK_LISTELEMENT_CANARY(element)
7136+#endif
7137 func(element->data, arg TSRMLS_CC);
7138 }
7139 }
7140@@ -241,8 +335,14 @@
7141 zend_llist_element *element;
7142 va_list args;
7143
7144+#if HARDENING_PATCH_LL_PROTECT
7145+ CHECK_LIST_CANARY(l)
7146+#endif
7147 va_start(args, num_args);
7148 for (element=l->head; element; element=element->next) {
7149+#if HARDENING_PATCH_LL_PROTECT
7150+ CHECK_LISTELEMENT_CANARY(element)
7151+#endif
7152 func(element->data, num_args, args TSRMLS_CC);
7153 }
7154 va_end(args);
7155@@ -251,6 +351,10 @@
7156
7157 ZEND_API int zend_llist_count(zend_llist *l)
7158 {
7159+#if HARDENING_PATCH_LL_PROTECT
7160+ TSRMLS_FETCH();
7161+ CHECK_LIST_CANARY(l)
7162+#endif
7163 return l->count;
7164 }
7165
7166@@ -259,8 +363,15 @@
7167 {
7168 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7169
7170+#if HARDENING_PATCH_LL_PROTECT
7171+ TSRMLS_FETCH();
7172+ CHECK_LIST_CANARY(l)
7173+#endif
7174 *current = l->head;
7175 if (*current) {
7176+#if HARDENING_PATCH_LL_PROTECT
7177+ CHECK_LISTELEMENT_CANARY(*current)
7178+#endif
7179 return (*current)->data;
7180 } else {
7181 return NULL;
7182@@ -272,8 +383,15 @@
7183 {
7184 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7185
7186+#if HARDENING_PATCH_LL_PROTECT
7187+ TSRMLS_FETCH();
7188+ CHECK_LIST_CANARY(l)
7189+#endif
7190 *current = l->tail;
7191 if (*current) {
7192+#if HARDENING_PATCH_LL_PROTECT
7193+ CHECK_LISTELEMENT_CANARY(*current)
7194+#endif
7195 return (*current)->data;
7196 } else {
7197 return NULL;
7198@@ -285,9 +403,19 @@
7199 {
7200 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7201
7202+#if HARDENING_PATCH_LL_PROTECT
7203+ TSRMLS_FETCH();
7204+ CHECK_LIST_CANARY(l)
7205+#endif
7206 if (*current) {
7207+#if HARDENING_PATCH_LL_PROTECT
7208+ CHECK_LISTELEMENT_CANARY(*current)
7209+#endif
7210 *current = (*current)->next;
7211 if (*current) {
7212+#if HARDENING_PATCH_LL_PROTECT
7213+ CHECK_LISTELEMENT_CANARY(*current)
7214+#endif
7215 return (*current)->data;
7216 }
7217 }
7218@@ -299,9 +427,19 @@
7219 {
7220 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
7221
7222+#if HARDENING_PATCH_LL_PROTECT
7223+ TSRMLS_FETCH();
7224+ CHECK_LIST_CANARY(l)
7225+#endif
7226 if (*current) {
7227+#if HARDENING_PATCH_LL_PROTECT
7228+ CHECK_LISTELEMENT_CANARY(*current)
7229+#endif
7230 *current = (*current)->prev;
7231 if (*current) {
7232+#if HARDENING_PATCH_LL_PROTECT
7233+ CHECK_LISTELEMENT_CANARY(*current)
7234+#endif
7235 return (*current)->data;
7236 }
7237 }
7238diff -Nura php-5.0.5/Zend/zend_llist.h hardening-patch-5.0.5-0.4.5/Zend/zend_llist.h
7239--- php-5.0.5/Zend/zend_llist.h 2004-01-08 18:31:47.000000000 +0100
7240+++ hardening-patch-5.0.5-0.4.5/Zend/zend_llist.h 2005-11-01 14:23:05.987258128 +0100
7241@@ -23,6 +23,9 @@
7242 #define ZEND_LLIST_H
7243
7244 typedef struct _zend_llist_element {
7245+#if HARDENING_PATCH_LL_PROTECT
7246+ unsigned int canary;
7247+#endif
7248 struct _zend_llist_element *next;
7249 struct _zend_llist_element *prev;
7250 char data[1]; /* Needs to always be last in the struct */
7251@@ -35,6 +38,9 @@
7252 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
7253
7254 typedef struct _zend_llist {
7255+#if HARDENING_PATCH_LL_PROTECT
7256+ unsigned int canary_h; /* head */
7257+#endif
7258 zend_llist_element *head;
7259 zend_llist_element *tail;
7260 size_t count;
7261@@ -42,6 +48,9 @@
7262 llist_dtor_func_t dtor;
7263 unsigned char persistent;
7264 zend_llist_element *traverse_ptr;
7265+#if HARDENING_PATCH_LL_PROTECT
7266+ unsigned int canary_t; /* tail */
7267+#endif
7268 } zend_llist;
7269
7270 typedef zend_llist_element* zend_llist_position;
7271diff -Nura php-5.0.5/Zend/zend_modules.h hardening-patch-5.0.5-0.4.5/Zend/zend_modules.h
7272--- php-5.0.5/Zend/zend_modules.h 2005-03-16 00:47:12.000000000 +0100
7273+++ hardening-patch-5.0.5-0.4.5/Zend/zend_modules.h 2005-11-01 14:23:05.987258128 +0100
7274@@ -38,6 +38,7 @@
7275 extern struct _zend_arg_info fourth_arg_force_ref[5];
7276 extern struct _zend_arg_info all_args_by_ref[1];
7277
7278+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002050912
7279 #define ZEND_MODULE_API_NO 20041030
7280 #ifdef ZTS
7281 #define USING_ZTS 1
7282@@ -45,10 +46,10 @@
7283 #define USING_ZTS 0
7284 #endif
7285
7286-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
7287-#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
7288+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
7289+#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
7290
7291-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
7292+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
7293
7294 #define STANDARD_MODULE_PROPERTIES \
7295 NULL, STANDARD_MODULE_PROPERTIES_EX
7296@@ -81,6 +82,7 @@
7297 unsigned char type;
7298 void *handle;
7299 int module_number;
7300+ unsigned int real_zend_api;
7301 };
7302
7303
7304diff -Nura php-5.0.5/Zend/zend_opcode.c hardening-patch-5.0.5-0.4.5/Zend/zend_opcode.c
7305--- php-5.0.5/Zend/zend_opcode.c 2004-06-06 10:37:12.000000000 +0200
7306+++ hardening-patch-5.0.5-0.4.5/Zend/zend_opcode.c 2005-11-01 14:23:05.988257976 +0100
7307@@ -92,6 +92,9 @@
7308 op_array->uses_this = 0;
7309
7310 op_array->start_op = NULL;
7311+#if HARDENING_PATCH
7312+ op_array->created_by_eval = 0;
7313+#endif
7314
7315 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
7316 }