summaryrefslogtreecommitdiff
path: root/0.4.2/hardening-patch-5.0.5-0.4.2.patch
diff options
context:
space:
mode:
Diffstat (limited to '0.4.2/hardening-patch-5.0.5-0.4.2.patch')
-rw-r--r--0.4.2/hardening-patch-5.0.5-0.4.2.patch6671
1 files changed, 6671 insertions, 0 deletions
diff --git a/0.4.2/hardening-patch-5.0.5-0.4.2.patch b/0.4.2/hardening-patch-5.0.5-0.4.2.patch
new file mode 100644
index 0000000..f7f11b5
--- /dev/null
+++ b/0.4.2/hardening-patch-5.0.5-0.4.2.patch
@@ -0,0 +1,6671 @@
1diff -Nura php-5.0.5/acinclude.m4 hardening-patch-5.0.5-0.4.2/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.2/acinclude.m4 2005-09-07 13:49:17.000000000 +0200
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.2/configure
42--- php-5.0.5/configure 2005-09-05 13:16:17.000000000 +0200
43+++ hardening-patch-5.0.5-0.4.2/configure 2005-09-07 14:19:05.000000000 +0200
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.2/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.2/configure.in 2005-09-07 13:49:17.000000000 +0200
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/fbsql/php_fbsql.c hardening-patch-5.0.5-0.4.2/ext/fbsql/php_fbsql.c
659--- php-5.0.5/ext/fbsql/php_fbsql.c 2005-02-09 20:32:45.000000000 +0100
660+++ hardening-patch-5.0.5-0.4.2/ext/fbsql/php_fbsql.c 2005-09-07 13:49:17.000000000 +0200
661@@ -1852,8 +1852,24 @@
662 }
663 else if (fbcmdErrorsFound(md))
664 {
665+#if HARDENING_PATCH
666+ char* query_copy;
667+ int i;
668+#endif
669 FBCErrorMetaData* emd = fbcdcErrorMetaData(c, md);
670 char* emg = fbcemdAllErrorMessages(emd);
671+#if HARDENING_PATCH
672+ query_copy=estrdup(query_copy);
673+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
674+ php_security_log(S_SQL, "fbsql error: %s - query: %s", emg, query_copy);
675+ efree(query_copy);
676+ if (HG(hphp_sql_bailout_on_error)) {
677+ free(emg);
678+ fbcemdRelease(emd);
679+ result = 0;
680+ zend_bailout();
681+ }
682+#endif
683 if (FB_SQL_G(generateWarnings))
684 {
685 if (emg)
686diff -Nura php-5.0.5/ext/mysql/php_mysql.c hardening-patch-5.0.5-0.4.2/ext/mysql/php_mysql.c
687--- php-5.0.5/ext/mysql/php_mysql.c 2005-04-08 00:23:28.000000000 +0200
688+++ hardening-patch-5.0.5-0.4.2/ext/mysql/php_mysql.c 2005-09-07 13:49:17.000000000 +0200
689@@ -1224,6 +1224,8 @@
690 {
691 php_mysql_conn *mysql;
692 MYSQL_RES *mysql_result;
693+ char *copy_query;
694+ int i;
695
696 ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
697
698@@ -1274,6 +1276,13 @@
699 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
700 }
701 }
702+ copy_query = estrdup(Z_STRVAL_PP(query));
703+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
704+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
705+ efree(copy_query);
706+ if (HG(hphp_sql_bailout_on_error)) {
707+ zend_bailout();
708+ }
709 RETURN_FALSE;
710 }
711 #else
712@@ -1284,6 +1293,13 @@
713 php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(&mysql->conn));
714 }
715 }
716+ copy_query = estrdup(Z_STRVAL_PP(query));
717+ for (i=0; copy_query[i]; i++) if (copy_query[i] < 32) copy_query[i]='.';
718+ php_security_log(S_SQL, "MySQL error: %s - query: %s", mysql_error(&mysql->conn), copy_query);
719+ efree(copy_query);
720+ if (HG(hphp_sql_bailout_on_error)) {
721+ zend_bailout();
722+ }
723 RETURN_FALSE;
724 }
725 #endif
726diff -Nura php-5.0.5/ext/mysqli/mysqli_nonapi.c hardening-patch-5.0.5-0.4.2/ext/mysqli/mysqli_nonapi.c
727--- php-5.0.5/ext/mysqli/mysqli_nonapi.c 2005-08-06 18:56:06.000000000 +0200
728+++ hardening-patch-5.0.5-0.4.2/ext/mysqli/mysqli_nonapi.c 2005-09-07 13:49:17.000000000 +0200
729@@ -229,6 +229,17 @@
730 if (mysql_real_query(mysql->mysql, query, query_len)) {
731 char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
732 unsigned int s_errno;
733+#if HARDENING_PATCH
734+ char *query_copy = estrdup(query);
735+ int i;
736+
737+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
738+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_errno, query_copy);
739+ efree(query_copy);
740+ if (HG(hphp_sql_bailout_on_error)) {
741+ zend_bailout();
742+ }
743+#endif
744 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
745
746 /* we have to save error information, cause
747@@ -278,6 +289,17 @@
748 MYSQLI_DISABLE_MQ;
749
750 if (mysql_real_query(mysql->mysql, query, query_len)) {
751+#if HARDENING_PATCH
752+ char *query_copy = estrdup(query);
753+ int i;
754+
755+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
756+ php_security_log(S_SQL, "MySQLi error: %s - query: %s", mysql->mysql->net.last_errno, query_copy);
757+ efree(query_copy);
758+ if (HG(hphp_sql_bailout_on_error)) {
759+ zend_bailout();
760+ }
761+#endif
762 MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
763 RETURN_FALSE;
764 }
765diff -Nura php-5.0.5/ext/pgsql/pgsql.c hardening-patch-5.0.5-0.4.2/ext/pgsql/pgsql.c
766--- php-5.0.5/ext/pgsql/pgsql.c 2005-07-05 14:47:06.000000000 +0200
767+++ hardening-patch-5.0.5-0.4.2/ext/pgsql/pgsql.c 2005-09-07 13:49:17.000000000 +0200
768@@ -1080,10 +1080,28 @@
769 case PGRES_EMPTY_QUERY:
770 case PGRES_BAD_RESPONSE:
771 case PGRES_NONFATAL_ERROR:
772- case PGRES_FATAL_ERROR:
773- PHP_PQ_ERROR("Query failed: %s", pgsql);
774- PQclear(pgsql_result);
775- RETURN_FALSE;
776+ case PGRES_FATAL_ERROR:
777+ {
778+#if HARDENING_PATCH
779+ int i;
780+ char *query_copy;
781+#endif
782+ char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL);
783+ PQclear(pgsql_result);
784+#if HARDENING_PATCH
785+ query_copy = estrdup(Z_STRVAL_PP(query));
786+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
787+ php_security_log(S_SQL, "PgSQL error: %s - query: %s", msgbuf, query_copy);
788+ efree(query_copy);
789+ if (HG(hphp_sql_bailout_on_error)) {
790+ efree(msgbuf);
791+ zend_bailout();
792+ }
793+#endif
794+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Query failed: %s", msgbuf);
795+ efree(msgbuf);
796+ RETURN_FALSE;
797+ }
798 break;
799 case PGRES_COMMAND_OK: /* successful command that did not return rows */
800 default:
801diff -Nura php-5.0.5/ext/sqlite/sqlite.c hardening-patch-5.0.5-0.4.2/ext/sqlite/sqlite.c
802--- php-5.0.5/ext/sqlite/sqlite.c 2005-06-07 17:38:37.000000000 +0200
803+++ hardening-patch-5.0.5-0.4.2/ext/sqlite/sqlite.c 2005-09-07 13:49:17.000000000 +0200
804@@ -1481,6 +1481,19 @@
805 db->last_err_code = ret;
806
807 if (ret != SQLITE_OK) {
808+#if HARDENING_PATCH
809+ char *query_copy;
810+ int i;
811+
812+ query_copy = estrdup(sql);
813+ for (i=0; query_copy[i]; i++) if (query_copy[i]<32) query_copy[i]='.';
814+ php_security_log(S_SQL, "SQLite error: %s - query: %s", errtext, query_copy);
815+ efree(query_copy);
816+ if (HG(hphp_sql_bailout_on_error)) {
817+ sqlite_freemem(errtext);
818+ zend_bailout();
819+ }
820+#endif
821 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", errtext);
822 sqlite_freemem(errtext);
823 goto terminate;
824diff -Nura php-5.0.5/ext/standard/array.c hardening-patch-5.0.5-0.4.2/ext/standard/array.c
825--- php-5.0.5/ext/standard/array.c 2005-09-01 14:01:01.000000000 +0200
826+++ hardening-patch-5.0.5-0.4.2/ext/standard/array.c 2005-09-07 13:49:17.000000000 +0200
827@@ -1283,6 +1283,32 @@
828 }
829 }
830 }
831+
832+ if (var_name[0] == 'H') {
833+ if ((strcmp(var_name, "HTTP_GET_VARS")==0)||
834+ (strcmp(var_name, "HTTP_POST_VARS")==0)||
835+ (strcmp(var_name, "HTTP_POST_FILES")==0)||
836+ (strcmp(var_name, "HTTP_ENV_VARS")==0)||
837+ (strcmp(var_name, "HTTP_SERVER_VARS")==0)||
838+ (strcmp(var_name, "HTTP_SESSION_VARS")==0)||
839+ (strcmp(var_name, "HTTP_COOKIE_VARS")==0)||
840+ (strcmp(var_name, "HTTP_RAW_POST_DATA")==0)) {
841+ return 0;
842+ }
843+ } else if (var_name[0] == '_') {
844+ if ((strcmp(var_name, "_COOKIE")==0)||
845+ (strcmp(var_name, "_ENV")==0)||
846+ (strcmp(var_name, "_FILES")==0)||
847+ (strcmp(var_name, "_GET")==0)||
848+ (strcmp(var_name, "_POST")==0)||
849+ (strcmp(var_name, "_REQUEST")==0)||
850+ (strcmp(var_name, "_SESSION")==0)||
851+ (strcmp(var_name, "_SERVER")==0)) {
852+ return 0;
853+ }
854+ } else if (strcmp(var_name, "GLOBALS")==0) {
855+ return 0;
856+ }
857
858 return 1;
859 }
860diff -Nura php-5.0.5/ext/standard/basic_functions.c hardening-patch-5.0.5-0.4.2/ext/standard/basic_functions.c
861--- php-5.0.5/ext/standard/basic_functions.c 2005-08-21 20:36:33.000000000 +0200
862+++ hardening-patch-5.0.5-0.4.2/ext/standard/basic_functions.c 2005-09-07 14:19:05.000000000 +0200
863@@ -142,12 +142,14 @@
864 typedef struct _php_shutdown_function_entry {
865 zval **arguments;
866 int arg_count;
867+ zend_bool created_by_eval;
868 } php_shutdown_function_entry;
869
870 typedef struct _user_tick_function_entry {
871 zval **arguments;
872 int arg_count;
873 int calling;
874+ zend_bool created_by_eval;
875 } user_tick_function_entry;
876
877 /* some prototypes for local functions */
878@@ -189,6 +191,8 @@
879 PHP_FE(get_html_translation_table, NULL)
880 PHP_FE(sha1, NULL)
881 PHP_FE(sha1_file, NULL)
882+ PHP_FE(sha256, NULL)
883+ PHP_FE(sha256_file, NULL)
884 PHP_NAMED_FE(md5,php_if_md5, NULL)
885 PHP_NAMED_FE(md5_file,php_if_md5_file, NULL)
886 PHP_NAMED_FE(crc32,php_if_crc32, NULL)
887@@ -616,7 +620,7 @@
888 PHP_FALIAS(socket_get_status, stream_get_meta_data, NULL)
889
890 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
891- PHP_FE(realpath, NULL)
892+ PHP_STATIC_FE("realpath", zif_real_path, NULL)
893 #endif
894
895 #ifdef HAVE_FNMATCH
896@@ -2095,6 +2099,13 @@
897 {
898 zval retval;
899 char *function_name = NULL;
900+#if HARDENING_PATCH
901+ zend_uint orig_code_type = EG(in_code_type);
902+
903+ if (shutdown_function_entry->created_by_eval) {
904+ EG(in_code_type) = ZEND_EVAL_CODE;
905+ }
906+#endif
907
908 if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) {
909 php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name);
910@@ -2110,6 +2121,9 @@
911 if (function_name) {
912 efree(function_name);
913 }
914+#if HARDENING_PATCH
915+ EG(in_code_type) = orig_code_type;
916+#endif
917 return 0;
918 }
919
920@@ -2117,6 +2131,13 @@
921 {
922 zval retval;
923 zval *function = tick_fe->arguments[0];
924+#if HARDENING_PATCH
925+ zend_uint orig_code_type = EG(in_code_type);
926+
927+ if (tick_fe->created_by_eval) {
928+ EG(in_code_type) = ZEND_EVAL_CODE;
929+ }
930+#endif
931
932 /* Prevent reentrant calls to the same user ticks function */
933 if (! tick_fe->calling) {
934@@ -2148,6 +2169,9 @@
935
936 tick_fe->calling = 0;
937 }
938+#if HARDENING_PATCH
939+ EG(in_code_type) = orig_code_type;
940+#endif
941 }
942
943 static void run_user_tick_functions(int tick_count)
944@@ -2211,6 +2235,13 @@
945 }
946
947 shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0);
948+#if HARDENING_PATCH
949+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
950+ shutdown_function_entry.created_by_eval = 1;
951+ } else {
952+ shutdown_function_entry.created_by_eval = 0;
953+ }
954+#endif
955
956 if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) {
957 RETURN_FALSE;
958@@ -2794,6 +2825,13 @@
959 }
960
961 tick_fe.arguments = (zval **) safe_emalloc(sizeof(zval *), tick_fe.arg_count, 0);
962+#if HARDENING_PATCH
963+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
964+ tick_fe.created_by_eval = 1;
965+ } else {
966+ tick_fe.created_by_eval = 0;
967+ }
968+#endif
969
970 if (zend_get_parameters_array(ht, tick_fe.arg_count, tick_fe.arguments) == FAILURE) {
971 RETURN_FALSE;
972@@ -3082,6 +3120,35 @@
973 memcpy(new_key, prefix, prefix_len);
974 memcpy(new_key+prefix_len, hash_key->arKey, hash_key->nKeyLength);
975
976+ if (new_key[0] == 'H') {
977+ if ((strcmp(new_key, "HTTP_GET_VARS")==0)||
978+ (strcmp(new_key, "HTTP_POST_VARS")==0)||
979+ (strcmp(new_key, "HTTP_POST_FILES")==0)||
980+ (strcmp(new_key, "HTTP_ENV_VARS")==0)||
981+ (strcmp(new_key, "HTTP_SERVER_VARS")==0)||
982+ (strcmp(new_key, "HTTP_SESSION_VARS")==0)||
983+ (strcmp(new_key, "HTTP_COOKIE_VARS")==0)||
984+ (strcmp(new_key, "HTTP_RAW_POST_DATA")==0)) {
985+ efree(new_key);
986+ return 0;
987+ }
988+ } else if (new_key[0] == '_') {
989+ if ((strcmp(new_key, "_COOKIE")==0)||
990+ (strcmp(new_key, "_ENV")==0)||
991+ (strcmp(new_key, "_FILES")==0)||
992+ (strcmp(new_key, "_GET")==0)||
993+ (strcmp(new_key, "_POST")==0)||
994+ (strcmp(new_key, "_REQUEST")==0)||
995+ (strcmp(new_key, "_SESSION")==0)||
996+ (strcmp(new_key, "_SERVER")==0)) {
997+ efree(new_key);
998+ return 0;
999+ }
1000+ } else if (strcmp(new_key, "GLOBALS")==0) {
1001+ efree(new_key);
1002+ return 0;
1003+ }
1004+
1005 zend_hash_del(&EG(symbol_table), new_key, new_key_len);
1006 ZEND_SET_SYMBOL_WITH_LENGTH(&EG(symbol_table), new_key, new_key_len, *var, (*var)->refcount+1, 0);
1007
1008diff -Nura php-5.0.5/ext/standard/config.m4 hardening-patch-5.0.5-0.4.2/ext/standard/config.m4
1009--- php-5.0.5/ext/standard/config.m4 2004-12-30 08:04:11.000000000 +0100
1010+++ hardening-patch-5.0.5-0.4.2/ext/standard/config.m4 2005-09-07 14:19:05.000000000 +0200
1011@@ -187,7 +187,7 @@
1012 if test "$ac_cv_crypt_blowfish" = "yes"; then
1013 ac_result=1
1014 else
1015- ac_result=0
1016+ ac_result=1
1017 fi
1018 AC_DEFINE_UNQUOTED(PHP_BLOWFISH_CRYPT, $ac_result, [Whether the system supports BlowFish salt])
1019 ])
1020@@ -469,6 +469,6 @@
1021 incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \
1022 http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \
1023 var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \
1024- filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c)
1025+ filters.c proc_open.c sunfuncs.c streamsfuncs.c http.c sha256.c crypt_blowfish.c )
1026
1027 PHP_ADD_MAKEFILE_FRAGMENT
1028diff -Nura php-5.0.5/ext/standard/config.w32 hardening-patch-5.0.5-0.4.2/ext/standard/config.w32
1029--- php-5.0.5/ext/standard/config.w32 2003-12-06 17:04:33.000000000 +0100
1030+++ hardening-patch-5.0.5-0.4.2/ext/standard/config.w32 2005-09-07 14:19:05.000000000 +0200
1031@@ -14,5 +14,5 @@
1032 url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \
1033 php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \
1034 user_filters.c uuencode.c filters.c proc_open.c sunfuncs.c \
1035- streamsfuncs.c http.c", false /* never shared */);
1036+ streamsfuncs.c http.c sha256.c crypt_blowfish.c", false /* never shared */);
1037
1038diff -Nura php-5.0.5/ext/standard/crypt_blowfish.c hardening-patch-5.0.5-0.4.2/ext/standard/crypt_blowfish.c
1039--- php-5.0.5/ext/standard/crypt_blowfish.c 1970-01-01 01:00:00.000000000 +0100
1040+++ hardening-patch-5.0.5-0.4.2/ext/standard/crypt_blowfish.c 2005-09-07 14:19:05.000000000 +0200
1041@@ -0,0 +1,748 @@
1042+/*
1043+ * This code comes from John the Ripper password cracker, with reentrant
1044+ * and crypt(3) interfaces added, but optimizations specific to password
1045+ * cracking removed.
1046+ *
1047+ * Written by Solar Designer <solar at openwall.com> in 1998-2002 and
1048+ * placed in the public domain.
1049+ *
1050+ * There's absolutely no warranty.
1051+ *
1052+ * It is my intent that you should be able to use this on your system,
1053+ * as a part of a software package, or anywhere else to improve security,
1054+ * ensure compatibility, or for any other purpose. I would appreciate
1055+ * it if you give credit where it is due and keep your modifications in
1056+ * the public domain as well, but I don't require that in order to let
1057+ * you place this code and any modifications you make under a license
1058+ * of your choice.
1059+ *
1060+ * This implementation is compatible with OpenBSD bcrypt.c (version 2a)
1061+ * by Niels Provos <provos at citi.umich.edu>, and uses some of his
1062+ * ideas. The password hashing algorithm was designed by David Mazieres
1063+ * <dm at lcs.mit.edu>.
1064+ *
1065+ * There's a paper on the algorithm that explains its design decisions:
1066+ *
1067+ * http://www.usenix.org/events/usenix99/provos.html
1068+ *
1069+ * Some of the tricks in BF_ROUND might be inspired by Eric Young's
1070+ * Blowfish library (I can't be sure if I would think of something if I
1071+ * hadn't seen his code).
1072+ */
1073+
1074+#include <string.h>
1075+
1076+#include <errno.h>
1077+#ifndef __set_errno
1078+#define __set_errno(val) errno = (val)
1079+#endif
1080+
1081+#undef __CONST
1082+#ifdef __GNUC__
1083+#define __CONST __const
1084+#else
1085+#define __CONST
1086+#endif
1087+
1088+#ifdef __i386__
1089+#define BF_ASM 0
1090+#define BF_SCALE 1
1091+#elif defined(__alpha__) || defined(__hppa__)
1092+#define BF_ASM 0
1093+#define BF_SCALE 1
1094+#else
1095+#define BF_ASM 0
1096+#define BF_SCALE 0
1097+#endif
1098+
1099+typedef unsigned int BF_word;
1100+
1101+/* Number of Blowfish rounds, this is also hardcoded into a few places */
1102+#define BF_N 16
1103+
1104+typedef BF_word BF_key[BF_N + 2];
1105+
1106+typedef struct {
1107+ BF_word S[4][0x100];
1108+ BF_key P;
1109+} BF_ctx;
1110+
1111+/*
1112+ * Magic IV for 64 Blowfish encryptions that we do at the end.
1113+ * The string is "OrpheanBeholderScryDoubt" on big-endian.
1114+ */
1115+static BF_word BF_magic_w[6] = {
1116+ 0x4F727068, 0x65616E42, 0x65686F6C,
1117+ 0x64657253, 0x63727944, 0x6F756274
1118+};
1119+
1120+/*
1121+ * P-box and S-box tables initialized with digits of Pi.
1122+ */
1123+static BF_ctx BF_init_state = {
1124+ {
1125+ {
1126+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1127+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1128+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1129+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1130+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1131+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1132+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1133+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1134+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1135+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1136+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1137+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1138+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1139+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1140+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1141+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1142+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1143+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1144+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1145+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1146+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1147+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1148+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1149+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1150+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1151+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1152+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1153+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1154+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1155+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1156+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1157+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1158+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1159+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1160+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1161+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1162+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1163+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1164+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1165+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1166+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1167+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1168+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1169+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1170+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1171+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1172+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1173+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1174+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1175+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1176+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1177+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1178+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1179+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1180+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1181+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1182+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1183+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1184+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1185+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1186+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1187+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1188+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1189+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
1190+ }, {
1191+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1192+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1193+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1194+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
1195+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
1196+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
1197+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
1198+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
1199+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
1200+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
1201+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
1202+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
1203+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
1204+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
1205+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
1206+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
1207+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
1208+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
1209+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
1210+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
1211+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
1212+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
1213+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
1214+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
1215+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
1216+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
1217+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
1218+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
1219+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
1220+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
1221+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
1222+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
1223+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
1224+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
1225+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
1226+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
1227+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
1228+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
1229+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
1230+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
1231+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
1232+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
1233+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
1234+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
1235+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
1236+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
1237+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
1238+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
1239+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
1240+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
1241+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
1242+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
1243+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
1244+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
1245+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
1246+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
1247+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
1248+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
1249+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
1250+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
1251+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
1252+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
1253+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
1254+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
1255+ }, {
1256+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
1257+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
1258+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
1259+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
1260+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
1261+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
1262+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
1263+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
1264+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
1265+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
1266+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
1267+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
1268+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
1269+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
1270+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
1271+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
1272+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
1273+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
1274+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
1275+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
1276+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
1277+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
1278+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
1279+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
1280+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
1281+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
1282+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
1283+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
1284+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
1285+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
1286+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
1287+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
1288+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
1289+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
1290+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
1291+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
1292+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
1293+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
1294+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
1295+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
1296+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
1297+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
1298+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
1299+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
1300+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
1301+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
1302+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
1303+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
1304+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
1305+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
1306+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
1307+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
1308+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
1309+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
1310+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
1311+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
1312+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
1313+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
1314+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
1315+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
1316+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
1317+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
1318+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
1319+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
1320+ }, {
1321+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
1322+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
1323+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
1324+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
1325+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
1326+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
1327+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
1328+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
1329+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
1330+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
1331+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
1332+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
1333+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
1334+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
1335+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
1336+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
1337+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
1338+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
1339+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
1340+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
1341+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
1342+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
1343+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
1344+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
1345+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
1346+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
1347+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
1348+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
1349+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
1350+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
1351+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
1352+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
1353+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
1354+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
1355+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
1356+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
1357+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
1358+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
1359+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
1360+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
1361+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
1362+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
1363+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
1364+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
1365+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
1366+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
1367+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
1368+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
1369+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
1370+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
1371+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
1372+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
1373+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
1374+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
1375+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
1376+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
1377+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
1378+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
1379+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
1380+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
1381+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
1382+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
1383+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
1384+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
1385+ }
1386+ }, {
1387+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
1388+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
1389+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
1390+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
1391+ 0x9216d5d9, 0x8979fb1b
1392+ }
1393+};
1394+
1395+static unsigned char BF_itoa64[64 + 1] =
1396+ "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1397+
1398+static unsigned char BF_atoi64[0x60] = {
1399+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
1400+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
1401+ 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
1402+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
1403+ 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
1404+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
1405+};
1406+
1407+/*
1408+ * This may be optimized out if built with function inlining and no BF_ASM.
1409+ */
1410+static void clean(void *data, int size)
1411+{
1412+#if BF_ASM
1413+ extern void _BF_clean(void *data);
1414+#endif
1415+ memset(data, 0, size);
1416+#if BF_ASM
1417+ _BF_clean(data);
1418+#endif
1419+}
1420+
1421+#define BF_safe_atoi64(dst, src) \
1422+{ \
1423+ tmp = (unsigned char)(src); \
1424+ if (tmp == '$') break; \
1425+ if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
1426+ tmp = BF_atoi64[tmp]; \
1427+ if (tmp > 63) return -1; \
1428+ (dst) = tmp; \
1429+}
1430+
1431+static int BF_decode(BF_word *dst, __CONST char *src, int size)
1432+{
1433+ unsigned char *dptr = (unsigned char *)dst;
1434+ unsigned char *end = dptr + size;
1435+ unsigned char *sptr = (unsigned char *)src;
1436+ unsigned int tmp, c1, c2, c3, c4;
1437+
1438+ do {
1439+ BF_safe_atoi64(c1, *sptr++);
1440+ BF_safe_atoi64(c2, *sptr++);
1441+ *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
1442+ if (dptr >= end) break;
1443+
1444+ BF_safe_atoi64(c3, *sptr++);
1445+ *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
1446+ if (dptr >= end) break;
1447+
1448+ BF_safe_atoi64(c4, *sptr++);
1449+ *dptr++ = ((c3 & 0x03) << 6) | c4;
1450+ } while (dptr < end);
1451+
1452+ while (dptr < end)
1453+ *dptr++ = 0;
1454+
1455+ return 0;
1456+}
1457+
1458+static void BF_encode(char *dst, __CONST BF_word *src, int size)
1459+{
1460+ unsigned char *sptr = (unsigned char *)src;
1461+ unsigned char *end = sptr + size;
1462+ unsigned char *dptr = (unsigned char *)dst;
1463+ unsigned int c1, c2;
1464+
1465+ do {
1466+ c1 = *sptr++;
1467+ *dptr++ = BF_itoa64[c1 >> 2];
1468+ c1 = (c1 & 0x03) << 4;
1469+ if (sptr >= end) {
1470+ *dptr++ = BF_itoa64[c1];
1471+ break;
1472+ }
1473+
1474+ c2 = *sptr++;
1475+ c1 |= c2 >> 4;
1476+ *dptr++ = BF_itoa64[c1];
1477+ c1 = (c2 & 0x0f) << 2;
1478+ if (sptr >= end) {
1479+ *dptr++ = BF_itoa64[c1];
1480+ break;
1481+ }
1482+
1483+ c2 = *sptr++;
1484+ c1 |= c2 >> 6;
1485+ *dptr++ = BF_itoa64[c1];
1486+ *dptr++ = BF_itoa64[c2 & 0x3f];
1487+ } while (sptr < end);
1488+}
1489+
1490+static void BF_swap(BF_word *x, int count)
1491+{
1492+ static int endianness_check = 1;
1493+ char *is_little_endian = (char *)&endianness_check;
1494+ BF_word tmp;
1495+
1496+ if (*is_little_endian)
1497+ do {
1498+ tmp = *x;
1499+ tmp = (tmp << 16) | (tmp >> 16);
1500+ *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
1501+ } while (--count);
1502+}
1503+
1504+#if BF_SCALE
1505+/* Architectures which can shift addresses left by 2 bits with no extra cost */
1506+#define BF_ROUND(L, R, N) \
1507+ tmp1 = L & 0xFF; \
1508+ tmp2 = L >> 8; \
1509+ tmp2 &= 0xFF; \
1510+ tmp3 = L >> 16; \
1511+ tmp3 &= 0xFF; \
1512+ tmp4 = L >> 24; \
1513+ tmp1 = data.ctx.S[3][tmp1]; \
1514+ tmp2 = data.ctx.S[2][tmp2]; \
1515+ tmp3 = data.ctx.S[1][tmp3]; \
1516+ tmp3 += data.ctx.S[0][tmp4]; \
1517+ tmp3 ^= tmp2; \
1518+ R ^= data.ctx.P[N + 1]; \
1519+ tmp3 += tmp1; \
1520+ R ^= tmp3;
1521+#else
1522+/* Architectures with no complicated addressing modes supported */
1523+#define BF_INDEX(S, i) \
1524+ (*((BF_word *)(((unsigned char *)S) + (i))))
1525+#define BF_ROUND(L, R, N) \
1526+ tmp1 = L & 0xFF; \
1527+ tmp1 <<= 2; \
1528+ tmp2 = L >> 6; \
1529+ tmp2 &= 0x3FC; \
1530+ tmp3 = L >> 14; \
1531+ tmp3 &= 0x3FC; \
1532+ tmp4 = L >> 22; \
1533+ tmp4 &= 0x3FC; \
1534+ tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
1535+ tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
1536+ tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
1537+ tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
1538+ tmp3 ^= tmp2; \
1539+ R ^= data.ctx.P[N + 1]; \
1540+ tmp3 += tmp1; \
1541+ R ^= tmp3;
1542+#endif
1543+
1544+/*
1545+ * Encrypt one block, BF_N is hardcoded here.
1546+ */
1547+#define BF_ENCRYPT \
1548+ L ^= data.ctx.P[0]; \
1549+ BF_ROUND(L, R, 0); \
1550+ BF_ROUND(R, L, 1); \
1551+ BF_ROUND(L, R, 2); \
1552+ BF_ROUND(R, L, 3); \
1553+ BF_ROUND(L, R, 4); \
1554+ BF_ROUND(R, L, 5); \
1555+ BF_ROUND(L, R, 6); \
1556+ BF_ROUND(R, L, 7); \
1557+ BF_ROUND(L, R, 8); \
1558+ BF_ROUND(R, L, 9); \
1559+ BF_ROUND(L, R, 10); \
1560+ BF_ROUND(R, L, 11); \
1561+ BF_ROUND(L, R, 12); \
1562+ BF_ROUND(R, L, 13); \
1563+ BF_ROUND(L, R, 14); \
1564+ BF_ROUND(R, L, 15); \
1565+ tmp4 = R; \
1566+ R = L; \
1567+ L = tmp4 ^ data.ctx.P[BF_N + 1];
1568+
1569+#if BF_ASM
1570+#define BF_body() \
1571+ _BF_body_r(&data.ctx);
1572+#else
1573+#define BF_body() \
1574+ L = R = 0; \
1575+ ptr = data.ctx.P; \
1576+ do { \
1577+ ptr += 2; \
1578+ BF_ENCRYPT; \
1579+ *(ptr - 2) = L; \
1580+ *(ptr - 1) = R; \
1581+ } while (ptr < &data.ctx.P[BF_N + 2]); \
1582+\
1583+ ptr = data.ctx.S[0]; \
1584+ do { \
1585+ ptr += 2; \
1586+ BF_ENCRYPT; \
1587+ *(ptr - 2) = L; \
1588+ *(ptr - 1) = R; \
1589+ } while (ptr < &data.ctx.S[3][0xFF]);
1590+#endif
1591+
1592+static void BF_set_key(__CONST char *key, BF_key expanded, BF_key initial)
1593+{
1594+ __CONST char *ptr = key;
1595+ int i, j;
1596+ BF_word tmp;
1597+
1598+ for (i = 0; i < BF_N + 2; i++) {
1599+ tmp = 0;
1600+ for (j = 0; j < 4; j++) {
1601+ tmp <<= 8;
1602+ tmp |= *ptr;
1603+
1604+ if (!*ptr) ptr = key; else ptr++;
1605+ }
1606+
1607+ expanded[i] = tmp;
1608+ initial[i] = BF_init_state.P[i] ^ tmp;
1609+ }
1610+}
1611+
1612+char *_crypt_blowfish_rn(__CONST char *key, __CONST char *setting,
1613+ char *output, int size)
1614+{
1615+#if BF_ASM
1616+ extern void _BF_body_r(BF_ctx *ctx);
1617+#endif
1618+ struct {
1619+ BF_ctx ctx;
1620+ BF_key expanded_key;
1621+ union {
1622+ BF_word salt[4];
1623+ BF_word output[6];
1624+ } binary;
1625+ } data;
1626+ BF_word L, R;
1627+ BF_word tmp1, tmp2, tmp3, tmp4;
1628+ BF_word *ptr;
1629+ BF_word count;
1630+ int i;
1631+
1632+ if (size < 7 + 22 + 31 + 1) {
1633+ __set_errno(ERANGE);
1634+ return NULL;
1635+ }
1636+
1637+ if (setting[0] != '$' ||
1638+ setting[1] != '2' ||
1639+ setting[2] != 'a' ||
1640+ setting[3] != '$' ||
1641+ setting[4] < '0' || setting[4] > '3' ||
1642+ setting[5] < '0' || setting[5] > '9' ||
1643+ setting[6] != '$') {
1644+ __set_errno(EINVAL);
1645+ return NULL;
1646+ }
1647+
1648+ count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
1649+ if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) {
1650+ clean(data.binary.salt, sizeof(data.binary.salt));
1651+ __set_errno(EINVAL);
1652+ return NULL;
1653+ }
1654+
1655+ BF_swap(data.binary.salt, 4);
1656+
1657+ BF_set_key(key, data.expanded_key, data.ctx.P);
1658+
1659+ memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
1660+
1661+ L = R = 0;
1662+ for (i = 0; i < BF_N + 2; i += 2) {
1663+ L ^= data.binary.salt[i & 2];
1664+ R ^= data.binary.salt[(i & 2) + 1];
1665+ BF_ENCRYPT;
1666+ data.ctx.P[i] = L;
1667+ data.ctx.P[i + 1] = R;
1668+ }
1669+
1670+ ptr = data.ctx.S[0];
1671+ do {
1672+ ptr += 4;
1673+ L ^= data.binary.salt[(BF_N + 2) & 3];
1674+ R ^= data.binary.salt[(BF_N + 3) & 3];
1675+ BF_ENCRYPT;
1676+ *(ptr - 4) = L;
1677+ *(ptr - 3) = R;
1678+
1679+ L ^= data.binary.salt[(BF_N + 4) & 3];
1680+ R ^= data.binary.salt[(BF_N + 5) & 3];
1681+ BF_ENCRYPT;
1682+ *(ptr - 2) = L;
1683+ *(ptr - 1) = R;
1684+ } while (ptr < &data.ctx.S[3][0xFF]);
1685+
1686+ do {
1687+ data.ctx.P[0] ^= data.expanded_key[0];
1688+ data.ctx.P[1] ^= data.expanded_key[1];
1689+ data.ctx.P[2] ^= data.expanded_key[2];
1690+ data.ctx.P[3] ^= data.expanded_key[3];
1691+ data.ctx.P[4] ^= data.expanded_key[4];
1692+ data.ctx.P[5] ^= data.expanded_key[5];
1693+ data.ctx.P[6] ^= data.expanded_key[6];
1694+ data.ctx.P[7] ^= data.expanded_key[7];
1695+ data.ctx.P[8] ^= data.expanded_key[8];
1696+ data.ctx.P[9] ^= data.expanded_key[9];
1697+ data.ctx.P[10] ^= data.expanded_key[10];
1698+ data.ctx.P[11] ^= data.expanded_key[11];
1699+ data.ctx.P[12] ^= data.expanded_key[12];
1700+ data.ctx.P[13] ^= data.expanded_key[13];
1701+ data.ctx.P[14] ^= data.expanded_key[14];
1702+ data.ctx.P[15] ^= data.expanded_key[15];
1703+ data.ctx.P[16] ^= data.expanded_key[16];
1704+ data.ctx.P[17] ^= data.expanded_key[17];
1705+
1706+ BF_body();
1707+
1708+ tmp1 = data.binary.salt[0];
1709+ tmp2 = data.binary.salt[1];
1710+ tmp3 = data.binary.salt[2];
1711+ tmp4 = data.binary.salt[3];
1712+ data.ctx.P[0] ^= tmp1;
1713+ data.ctx.P[1] ^= tmp2;
1714+ data.ctx.P[2] ^= tmp3;
1715+ data.ctx.P[3] ^= tmp4;
1716+ data.ctx.P[4] ^= tmp1;
1717+ data.ctx.P[5] ^= tmp2;
1718+ data.ctx.P[6] ^= tmp3;
1719+ data.ctx.P[7] ^= tmp4;
1720+ data.ctx.P[8] ^= tmp1;
1721+ data.ctx.P[9] ^= tmp2;
1722+ data.ctx.P[10] ^= tmp3;
1723+ data.ctx.P[11] ^= tmp4;
1724+ data.ctx.P[12] ^= tmp1;
1725+ data.ctx.P[13] ^= tmp2;
1726+ data.ctx.P[14] ^= tmp3;
1727+ data.ctx.P[15] ^= tmp4;
1728+ data.ctx.P[16] ^= tmp1;
1729+ data.ctx.P[17] ^= tmp2;
1730+
1731+ BF_body();
1732+ } while (--count);
1733+
1734+ for (i = 0; i < 6; i += 2) {
1735+ L = BF_magic_w[i];
1736+ R = BF_magic_w[i + 1];
1737+
1738+ count = 64;
1739+ do {
1740+ BF_ENCRYPT;
1741+ } while (--count);
1742+
1743+ data.binary.output[i] = L;
1744+ data.binary.output[i + 1] = R;
1745+ }
1746+
1747+ memcpy(output, setting, 7 + 22 - 1);
1748+ output[7 + 22 - 1] = BF_itoa64[(int)
1749+ BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
1750+
1751+/* This has to be bug-compatible with the original implementation, so
1752+ * only encode 23 of the 24 bytes. :-) */
1753+ BF_swap(data.binary.output, 6);
1754+ BF_encode(&output[7 + 22], data.binary.output, 23);
1755+ output[7 + 22 + 31] = '\0';
1756+
1757+/* Overwrite the most obvious sensitive data we have on the stack. Note
1758+ * that this does not guarantee there's no sensitive data left on the
1759+ * stack and/or in registers; I'm not aware of portable code that does. */
1760+ clean(&data, sizeof(data));
1761+
1762+ return output;
1763+}
1764+
1765+char *_crypt_gensalt_blowfish_rn(unsigned long count,
1766+ __CONST char *input, int size, char *output, int output_size)
1767+{
1768+ if (size < 16 || output_size < 7 + 22 + 1 ||
1769+ (count && (count < 4 || count > 31))) {
1770+ if (output_size > 0) output[0] = '\0';
1771+ __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
1772+ return NULL;
1773+ }
1774+
1775+ if (!count) count = 5;
1776+
1777+ output[0] = '$';
1778+ output[1] = '2';
1779+ output[2] = 'a';
1780+ output[3] = '$';
1781+ output[4] = '0' + count / 10;
1782+ output[5] = '0' + count % 10;
1783+ output[6] = '$';
1784+
1785+ BF_encode(&output[7], (BF_word *)input, 16);
1786+ output[7 + 22] = '\0';
1787+
1788+ return output;
1789+}
1790diff -Nura php-5.0.5/ext/standard/crypt.c hardening-patch-5.0.5-0.4.2/ext/standard/crypt.c
1791--- php-5.0.5/ext/standard/crypt.c 2004-02-12 20:05:41.000000000 +0100
1792+++ hardening-patch-5.0.5-0.4.2/ext/standard/crypt.c 2005-09-07 15:22:30.000000000 +0200
1793@@ -100,6 +100,8 @@
1794 return SUCCESS;
1795 }
1796
1797+char *_crypt_blowfish_rn(char *key, char *setting, char *output, int size);
1798+char *_crypt_gensalt_blowfish_rn(unsigned long count, char *input, int size, char *output, int output_size);
1799
1800 static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1801
1802@@ -135,7 +137,14 @@
1803
1804 /* The automatic salt generation only covers standard DES and md5-crypt */
1805 if(!*salt) {
1806-#if PHP_MD5_CRYPT
1807+#if PHP_BLOWFISH_CRYPT
1808+ char randat[16];
1809+ int i;
1810+
1811+ for (i=0; i<16; i++) randat[i] = PHP_CRYPT_RAND;
1812+
1813+ _crypt_gensalt_blowfish_rn(5, randat, sizeof(randat), salt, sizeof(salt));
1814+#elif PHP_MD5_CRYPT
1815 strcpy(salt, "$1$");
1816 php_to64(&salt[3], PHP_CRYPT_RAND, 4);
1817 php_to64(&salt[7], PHP_CRYPT_RAND, 4);
1818@@ -145,8 +154,24 @@
1819 salt[2] = '\0';
1820 #endif
1821 }
1822-
1823- RETVAL_STRING(crypt(str, salt), 1);
1824+
1825+ if (salt[0] == '$' &&
1826+ salt[1] == '2' &&
1827+ salt[2] == 'a' &&
1828+ salt[3] == '$' &&
1829+ salt[4] >= '0' && salt[4] <= '3' &&
1830+ salt[5] >= '0' && salt[5] <= '9' &&
1831+ salt[6] == '$') {
1832+
1833+ char output[PHP_MAX_SALT_LEN+1];
1834+
1835+ output[0] = 0;
1836+ _crypt_blowfish_rn(str, salt, output, sizeof(output));
1837+ RETVAL_STRING(output, 1);
1838+
1839+ } else {
1840+ RETVAL_STRING(crypt(str, salt), 1);
1841+ }
1842 }
1843 /* }}} */
1844 #endif
1845diff -Nura php-5.0.5/ext/standard/dl.c hardening-patch-5.0.5-0.4.2/ext/standard/dl.c
1846--- php-5.0.5/ext/standard/dl.c 2005-05-04 15:48:01.000000000 +0200
1847+++ hardening-patch-5.0.5-0.4.2/ext/standard/dl.c 2005-09-07 13:49:17.000000000 +0200
1848@@ -159,8 +159,35 @@
1849 RETURN_FALSE;
1850 }
1851 module_entry = get_module();
1852+
1853+ /* check if Hardening-Patch is installed */
1854+ if (module_entry->zend_api < 1000000000) {
1855+ php_error_docref(NULL TSRMLS_CC, error_type,
1856+ "%s: Unable to initialize module\n"
1857+ "Module compiled without Hardening-Patch, module API=%d, debug=%d, thread-safety=%d\n"
1858+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1859+ "These options need to match\n",
1860+ module_entry->name, module_entry->zend_api, module_entry->zend_debug, module_entry->zts,
1861+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1862+ DL_UNLOAD(handle);
1863+ RETURN_FALSE;
1864+ }
1865+
1866+ /* check if correct Hardening-Patch is installed */
1867+ if (module_entry->zend_api != HARDENING_PATCH_ZEND_MODULE_API_NO) {
1868+ php_error_docref(NULL TSRMLS_CC, error_type,
1869+ "%s: Unable to initialize module\n"
1870+ "Module compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1871+ "PHP compiled with Hardening-Patch=%d, module API=%d, debug=%d, thread-safety=%d\n"
1872+ "These options need to match\n",
1873+ module_entry->name, module_entry->zend_api, module_entry->real_zend_api, module_entry->zend_debug, module_entry->zts,
1874+ HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS);
1875+ DL_UNLOAD(handle);
1876+ RETURN_FALSE;
1877+ }
1878+
1879 if ((module_entry->zend_debug != ZEND_DEBUG) || (module_entry->zts != USING_ZTS)
1880- || (module_entry->zend_api != ZEND_MODULE_API_NO)) {
1881+ || (module_entry->real_zend_api != ZEND_MODULE_API_NO)) {
1882 /* Check for pre-4.1.0 module which has a slightly different module_entry structure :( */
1883 struct pre_4_1_0_module_entry {
1884 char *name;
1885@@ -194,7 +221,7 @@
1886 zts = ((struct pre_4_1_0_module_entry *)module_entry)->zts;
1887 } else {
1888 name = module_entry->name;
1889- zend_api = module_entry->zend_api;
1890+ zend_api = module_entry->real_zend_api;
1891 zend_debug = module_entry->zend_debug;
1892 zts = module_entry->zts;
1893 }
1894diff -Nura php-5.0.5/ext/standard/file.c hardening-patch-5.0.5-0.4.2/ext/standard/file.c
1895--- php-5.0.5/ext/standard/file.c 2005-04-06 15:59:48.000000000 +0200
1896+++ hardening-patch-5.0.5-0.4.2/ext/standard/file.c 2005-09-07 13:49:17.000000000 +0200
1897@@ -2044,7 +2044,7 @@
1898 #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1899 /* {{{ proto string realpath(string path)
1900 Return the resolved path */
1901-PHP_FUNCTION(realpath)
1902+PHP_FUNCTION(real_path)
1903 {
1904 zval **path;
1905 char resolved_path_buff[MAXPATHLEN];
1906diff -Nura php-5.0.5/ext/standard/file.h hardening-patch-5.0.5-0.4.2/ext/standard/file.h
1907--- php-5.0.5/ext/standard/file.h 2005-07-15 11:29:18.000000000 +0200
1908+++ hardening-patch-5.0.5-0.4.2/ext/standard/file.h 2005-09-07 13:54:52.000000000 +0200
1909@@ -60,7 +60,7 @@
1910 PHP_FUNCTION(fd_set);
1911 PHP_FUNCTION(fd_isset);
1912 #if (!defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
1913-PHP_FUNCTION(realpath);
1914+PHP_FUNCTION(real_path);
1915 PHP_FUNCTION(fnmatch);
1916 #endif
1917 PHP_NAMED_FUNCTION(php_if_ftruncate);
1918diff -Nura php-5.0.5/ext/standard/head.c hardening-patch-5.0.5-0.4.2/ext/standard/head.c
1919--- php-5.0.5/ext/standard/head.c 2005-06-28 16:49:14.000000000 +0200
1920+++ hardening-patch-5.0.5-0.4.2/ext/standard/head.c 2005-09-07 13:49:17.000000000 +0200
1921@@ -40,10 +40,31 @@
1922 {
1923 zend_bool rep = 1;
1924 sapi_header_line ctr = {0};
1925+#if HARDENING_PATCH
1926+ int i;
1927+#endif
1928
1929 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
1930 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
1931 return;
1932+
1933+#if HARDENING_PATCH
1934+ if (!HG(hphp_multiheader)) {
1935+ for (i=0; i<ctr.line_len; i++) {
1936+ if (ctr.line[i]==0) {
1937+ php_security_log(S_MISC, "header(): headerline truncated by an ASCII-NUL char");
1938+ ctr.line_len=i;
1939+ break;
1940+ } else if (ctr.line[i]=='\n') {
1941+ if (i>0 && (i<ctr.line_len-1) && (ctr.line[i+1]==' ' || ctr.line[i+1]=='\t')) {
1942+ continue;
1943+ }
1944+ php_security_log(S_MISC, "header(): headerline contains more than one header");
1945+ ctr.line_len=i;
1946+ }
1947+ }
1948+ }
1949+#endif
1950
1951 sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
1952 }
1953diff -Nura php-5.0.5/ext/standard/info.c hardening-patch-5.0.5-0.4.2/ext/standard/info.c
1954--- php-5.0.5/ext/standard/info.c 2005-08-16 02:25:46.000000000 +0200
1955+++ hardening-patch-5.0.5-0.4.2/ext/standard/info.c 2005-09-07 13:49:17.000000000 +0200
1956@@ -409,7 +409,7 @@
1957
1958 if (flag & PHP_INFO_GENERAL) {
1959 char *zend_version = get_zend_version();
1960- char temp_api[10];
1961+ char temp_api[11];
1962 char *logo_guid;
1963
1964 php_uname = php_get_uname('a');
1965@@ -432,11 +432,22 @@
1966 PUTS("\" alt=\"PHP Logo\" /></a>");
1967 }
1968
1969+#if HARDENING_PATCH
1970+ if (!sapi_module.phpinfo_as_text) {
1971+ php_printf("<h1 class=\"p\">PHP Version %s with Hardening-Patch %s</h1>\n", PHP_VERSION, HARDENING_PATCH_VERSION);
1972+ } else {
1973+ char temp_ver[40];
1974+
1975+ snprintf(temp_ver, sizeof(temp_ver), "%s/%s", PHP_VERSION, HARDENING_PATCH_VERSION);
1976+ php_info_print_table_row(2, "PHP/Hardening-Patch Version", temp_ver);
1977+ }
1978+#else
1979 if (!sapi_module.phpinfo_as_text) {
1980 php_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
1981 } else {
1982 php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1983- }
1984+ }
1985+#endif
1986 php_info_print_box_end();
1987 php_info_print_table_start();
1988 php_info_print_table_row(2, "System", php_uname );
1989diff -Nura php-5.0.5/ext/standard/php_standard.h hardening-patch-5.0.5-0.4.2/ext/standard/php_standard.h
1990--- php-5.0.5/ext/standard/php_standard.h 2004-01-08 18:32:51.000000000 +0100
1991+++ hardening-patch-5.0.5-0.4.2/ext/standard/php_standard.h 2005-09-07 14:19:05.000000000 +0200
1992@@ -28,6 +28,7 @@
1993 #include "php_mail.h"
1994 #include "md5.h"
1995 #include "sha1.h"
1996+#include "sha256.h"
1997 #include "html.h"
1998 #include "exec.h"
1999 #include "file.h"
2000diff -Nura php-5.0.5/ext/standard/sha256.c hardening-patch-5.0.5-0.4.2/ext/standard/sha256.c
2001--- php-5.0.5/ext/standard/sha256.c 1970-01-01 01:00:00.000000000 +0100
2002+++ hardening-patch-5.0.5-0.4.2/ext/standard/sha256.c 2005-09-07 14:19:05.000000000 +0200
2003@@ -0,0 +1,398 @@
2004+/*
2005+ +----------------------------------------------------------------------+
2006+ | PHP Version 5 |
2007+ +----------------------------------------------------------------------+
2008+ | Copyright (c) 1997-2004 The PHP Group |
2009+ +----------------------------------------------------------------------+
2010+ | This source file is subject to version 3.0 of the PHP license, |
2011+ | that is bundled with this package in the file LICENSE, and is |
2012+ | available through the world-wide-web at the following url: |
2013+ | http://www.php.net/license/3_0.txt. |
2014+ | If you did not receive a copy of the PHP license and are unable to |
2015+ | obtain it through the world-wide-web, please send a note to |
2016+ | license@php.net so we can mail you a copy immediately. |
2017+ +----------------------------------------------------------------------+
2018+ | Author: Stefan Esser <sesser@php.net> |
2019+ +----------------------------------------------------------------------+
2020+*/
2021+
2022+/* $Id: sha256.c,v 1.9 2004/01/08 08:17:34 andi Exp $ */
2023+
2024+#include <stdio.h>
2025+#include "php.h"
2026+
2027+/* This code is heavily based on the PHP md5/sha1 implementations */
2028+
2029+#include "sha256.h"
2030+
2031+PHPAPI void make_sha256_digest(char *sha256str, unsigned char *digest)
2032+{
2033+ int i;
2034+
2035+ for (i = 0; i < 32; i++) {
2036+ sprintf(sha256str, "%02x", digest[i]);
2037+ sha256str += 2;
2038+ }
2039+
2040+ *sha256str = '\0';
2041+}
2042+
2043+/* {{{ proto string sha256(string str [, bool raw_output])
2044+ Calculate the sha256 hash of a string */
2045+PHP_FUNCTION(sha256)
2046+{
2047+ char *arg;
2048+ int arg_len;
2049+ zend_bool raw_output = 0;
2050+ char sha256str[65];
2051+ PHP_SHA256_CTX context;
2052+ unsigned char digest[32];
2053+
2054+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2055+ return;
2056+ }
2057+
2058+ sha256str[0] = '\0';
2059+ PHP_SHA256Init(&context);
2060+ PHP_SHA256Update(&context, arg, arg_len);
2061+ PHP_SHA256Final(digest, &context);
2062+ if (raw_output) {
2063+ RETURN_STRINGL(digest, 32, 1);
2064+ } else {
2065+ make_sha256_digest(sha256str, digest);
2066+ RETVAL_STRING(sha256str, 1);
2067+ }
2068+
2069+}
2070+
2071+/* }}} */
2072+
2073+/* {{{ proto string sha256_file(string filename [, bool raw_output])
2074+ Calculate the sha256 hash of given filename */
2075+PHP_FUNCTION(sha256_file)
2076+{
2077+ char *arg;
2078+ int arg_len;
2079+ zend_bool raw_output = 0;
2080+ char sha256str[65];
2081+ unsigned char buf[1024];
2082+ unsigned char digest[32];
2083+ PHP_SHA256_CTX context;
2084+ int n;
2085+ FILE *fp;
2086+
2087+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
2088+ return;
2089+ }
2090+
2091+ if (PG(safe_mode) && (!php_checkuid(arg, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
2092+ RETURN_FALSE;
2093+ }
2094+
2095+ if (php_check_open_basedir(arg TSRMLS_CC)) {
2096+ RETURN_FALSE;
2097+ }
2098+
2099+ if ((fp = VCWD_FOPEN(arg, "rb")) == NULL) {
2100+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open file");
2101+ RETURN_FALSE;
2102+ }
2103+
2104+ PHP_SHA256Init(&context);
2105+
2106+ while ((n = fread(buf, 1, sizeof(buf), fp)) > 0) {
2107+ PHP_SHA256Update(&context, buf, n);
2108+ }
2109+
2110+ PHP_SHA256Final(digest, &context);
2111+
2112+ if (ferror(fp)) {
2113+ fclose(fp);
2114+ RETURN_FALSE;
2115+ }
2116+
2117+ fclose(fp);
2118+
2119+ if (raw_output) {
2120+ RETURN_STRINGL(digest, 32, 1);
2121+ } else {
2122+ make_sha256_digest(sha256str, digest);
2123+ RETVAL_STRING(sha256str, 1);
2124+ }
2125+}
2126+/* }}} */
2127+
2128+
2129+static void SHA256Transform(php_uint32[8], const unsigned char[64]);
2130+static void SHA256Encode(unsigned char *, php_uint32 *, unsigned int);
2131+static void SHA256Decode(php_uint32 *, const unsigned char *, unsigned int);
2132+
2133+static unsigned char PADDING[64] =
2134+{
2135+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2136+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2137+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2138+};
2139+
2140+/* F, G, H and I are basic SHA256 functions.
2141+ */
2142+#define F(x) (ROTATE_RIGHT(x,2) ^ ROTATE_RIGHT(x,13) ^ ROTATE_RIGHT(x,22))
2143+#define G(x, y, z) (((x) & (y)) | ((z) & ((y) | (x))))
2144+#define H(x) (ROTATE_RIGHT(x,6) ^ ROTATE_RIGHT(x,11) ^ ROTATE_RIGHT(x,25))
2145+#define I(x, y, z) (((x) & (y)) | ((~x) & z))
2146+
2147+/* ROTATE_RIGHT rotates x right n bits.
2148+ */
2149+#define ROTATE_RIGHT(x, n) (((x) >> (n)) | ((x) << (32-(n))))
2150+
2151+/* W[i]
2152+ */
2153+#define W(i) ( tmp1=ROTATE_RIGHT(x[(i-15)&15],7)^ROTATE_RIGHT(x[(i-15)&15],18)^(x[(i-15)&15] >> 3), \
2154+ tmp2=ROTATE_RIGHT(x[(i-2)&15],17)^ROTATE_RIGHT(x[(i-2)&15],19)^(x[(i-2)&15] >> 10), \
2155+ (x[i&15]=x[i&15] + tmp1 + x[(i-7)&15] + tmp2) )
2156+
2157+/* ROUND function of sha256
2158+ */
2159+
2160+#define ROUND(a,b,c,d,e,f,g,h,w,k) { \
2161+ t1 = (h) + H((e)) + I((e), (f), (g)) + (k) + (php_uint32)(w); \
2162+ (h) = F((a)) + G((a), (b), (c)) + t1; \
2163+ (d) += t1; \
2164+ }
2165+
2166+
2167+/* {{{ PHP_SHA256Init
2168+ * SHA256 initialization. Begins an SHA256 operation, writing a new context.
2169+ */
2170+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX * context)
2171+{
2172+ context->count[0] = context->count[1] = 0;
2173+ /* Load magic initialization constants.
2174+ */
2175+ context->state[0] = 0x6a09e667;
2176+ context->state[1] = 0xbb67ae85;
2177+ context->state[2] = 0x3c6ef372;
2178+ context->state[3] = 0xa54ff53a;
2179+ context->state[4] = 0x510e527f;
2180+ context->state[5] = 0x9b05688c;
2181+ context->state[6] = 0x1f83d9ab;
2182+ context->state[7] = 0x5be0cd19;
2183+}
2184+/* }}} */
2185+
2186+/* {{{ PHP_SHA256Update
2187+ SHA256 block update operation. Continues an SHA256 message-digest
2188+ operation, processing another message block, and updating the
2189+ context.
2190+ */
2191+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input,
2192+ unsigned int inputLen)
2193+{
2194+ unsigned int i, index, partLen;
2195+
2196+ /* Compute number of bytes mod 64 */
2197+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
2198+
2199+ /* Update number of bits */
2200+ if ((context->count[0] += ((php_uint32) inputLen << 3))
2201+ < ((php_uint32) inputLen << 3))
2202+ context->count[1]++;
2203+ context->count[1] += ((php_uint32) inputLen >> 29);
2204+
2205+ partLen = 64 - index;
2206+
2207+ /* Transform as many times as possible.
2208+ */
2209+ if (inputLen >= partLen) {
2210+ memcpy
2211+ ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
2212+ SHA256Transform(context->state, context->buffer);
2213+
2214+ for (i = partLen; i + 63 < inputLen; i += 64)
2215+ SHA256Transform(context->state, &input[i]);
2216+
2217+ index = 0;
2218+ } else
2219+ i = 0;
2220+
2221+ /* Buffer remaining input */
2222+ memcpy
2223+ ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
2224+ inputLen - i);
2225+}
2226+/* }}} */
2227+
2228+/* {{{ PHP_SHA256Final
2229+ SHA256 finalization. Ends an SHA256 message-digest operation, writing the
2230+ the message digest and zeroizing the context.
2231+ */
2232+PHPAPI void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
2233+{
2234+ unsigned char bits[8];
2235+ unsigned int index, padLen;
2236+
2237+ /* Save number of bits */
2238+ bits[7] = context->count[0] & 0xFF;
2239+ bits[6] = (context->count[0] >> 8) & 0xFF;
2240+ bits[5] = (context->count[0] >> 16) & 0xFF;
2241+ bits[4] = (context->count[0] >> 24) & 0xFF;
2242+ bits[3] = context->count[1] & 0xFF;
2243+ bits[2] = (context->count[1] >> 8) & 0xFF;
2244+ bits[1] = (context->count[1] >> 16) & 0xFF;
2245+ bits[0] = (context->count[1] >> 24) & 0xFF;
2246+
2247+ /* Pad out to 56 mod 64.
2248+ */
2249+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
2250+ padLen = (index < 56) ? (56 - index) : (120 - index);
2251+ PHP_SHA256Update(context, PADDING, padLen);
2252+
2253+ /* Append length (before padding) */
2254+ PHP_SHA256Update(context, bits, 8);
2255+
2256+ /* Store state in digest */
2257+ SHA256Encode(digest, context->state, 32);
2258+
2259+ /* Zeroize sensitive information.
2260+ */
2261+ memset((unsigned char*) context, 0, sizeof(*context));
2262+}
2263+/* }}} */
2264+
2265+/* {{{ SHA256Transform
2266+ * SHA256 basic transformation. Transforms state based on block.
2267+ */
2268+static void SHA256Transform(state, block)
2269+php_uint32 state[8];
2270+const unsigned char block[64];
2271+{
2272+ php_uint32 a = state[0], b = state[1], c = state[2];
2273+ php_uint32 d = state[3], e = state[4], f = state[5];
2274+ php_uint32 g = state[6], h = state[7], x[16], tmp1, tmp2, t1;
2275+
2276+ SHA256Decode(x, block, 64);
2277+
2278+ ROUND(a, b, c, d, e, f, g, h, x[0], 0x428a2f98)
2279+ ROUND(h, a, b, c, d, e, f, g, x[1], 0x71374491)
2280+ ROUND(g, h, a, b, c, d, e, f, x[2], 0xb5c0fbcf)
2281+ ROUND(f, g, h, a, b, c, d, e, x[3], 0xe9b5dba5)
2282+ ROUND(e, f, g, h, a, b, c, d, x[4], 0x3956c25b)
2283+ ROUND(d, e, f, g, h, a, b, c, x[5], 0x59f111f1)
2284+ ROUND(c, d, e, f, g, h, a, b, x[6], 0x923f82a4)
2285+ ROUND(b, c, d, e, f, g, h, a, x[7], 0xab1c5ed5)
2286+ ROUND(a, b, c, d, e, f, g, h, x[8], 0xd807aa98)
2287+ ROUND(h, a, b, c, d, e, f, g, x[9], 0x12835b01)
2288+ ROUND(g, h, a, b, c, d, e, f, x[10], 0x243185be)
2289+ ROUND(f, g, h, a, b, c, d, e, x[11], 0x550c7dc3)
2290+ ROUND(e, f, g, h, a, b, c, d, x[12], 0x72be5d74)
2291+ ROUND(d, e, f, g, h, a, b, c, x[13], 0x80deb1fe)
2292+ ROUND(c, d, e, f, g, h, a, b, x[14], 0x9bdc06a7)
2293+ ROUND(b, c, d, e, f, g, h, a, x[15], 0xc19bf174)
2294+ ROUND(a, b, c, d, e, f, g, h, W(16), 0xe49b69c1)
2295+ ROUND(h, a, b, c, d, e, f, g, W(17), 0xefbe4786)
2296+ ROUND(g, h, a, b, c, d, e, f, W(18), 0x0fc19dc6)
2297+ ROUND(f, g, h, a, b, c, d, e, W(19), 0x240ca1cc)
2298+ ROUND(e, f, g, h, a, b, c, d, W(20), 0x2de92c6f)
2299+ ROUND(d, e, f, g, h, a, b, c, W(21), 0x4a7484aa)
2300+ ROUND(c, d, e, f, g, h, a, b, W(22), 0x5cb0a9dc)
2301+ ROUND(b, c, d, e, f, g, h, a, W(23), 0x76f988da)
2302+ ROUND(a, b, c, d, e, f, g, h, W(24), 0x983e5152)
2303+ ROUND(h, a, b, c, d, e, f, g, W(25), 0xa831c66d)
2304+ ROUND(g, h, a, b, c, d, e, f, W(26), 0xb00327c8)
2305+ ROUND(f, g, h, a, b, c, d, e, W(27), 0xbf597fc7)
2306+ ROUND(e, f, g, h, a, b, c, d, W(28), 0xc6e00bf3)
2307+ ROUND(d, e, f, g, h, a, b, c, W(29), 0xd5a79147)
2308+ ROUND(c, d, e, f, g, h, a, b, W(30), 0x06ca6351)
2309+ ROUND(b, c, d, e, f, g, h, a, W(31), 0x14292967)
2310+ ROUND(a, b, c, d, e, f, g, h, W(32), 0x27b70a85)
2311+ ROUND(h, a, b, c, d, e, f, g, W(33), 0x2e1b2138)
2312+ ROUND(g, h, a, b, c, d, e, f, W(34), 0x4d2c6dfc)
2313+ ROUND(f, g, h, a, b, c, d, e, W(35), 0x53380d13)
2314+ ROUND(e, f, g, h, a, b, c, d, W(36), 0x650a7354)
2315+ ROUND(d, e, f, g, h, a, b, c, W(37), 0x766a0abb)
2316+ ROUND(c, d, e, f, g, h, a, b, W(38), 0x81c2c92e)
2317+ ROUND(b, c, d, e, f, g, h, a, W(39), 0x92722c85)
2318+ ROUND(a, b, c, d, e, f, g, h, W(40), 0xa2bfe8a1)
2319+ ROUND(h, a, b, c, d, e, f, g, W(41), 0xa81a664b)
2320+ ROUND(g, h, a, b, c, d, e, f, W(42), 0xc24b8b70)
2321+ ROUND(f, g, h, a, b, c, d, e, W(43), 0xc76c51a3)
2322+ ROUND(e, f, g, h, a, b, c, d, W(44), 0xd192e819)
2323+ ROUND(d, e, f, g, h, a, b, c, W(45), 0xd6990624)
2324+ ROUND(c, d, e, f, g, h, a, b, W(46), 0xf40e3585)
2325+ ROUND(b, c, d, e, f, g, h, a, W(47), 0x106aa070)
2326+ ROUND(a, b, c, d, e, f, g, h, W(48), 0x19a4c116)
2327+ ROUND(h, a, b, c, d, e, f, g, W(49), 0x1e376c08)
2328+ ROUND(g, h, a, b, c, d, e, f, W(50), 0x2748774c)
2329+ ROUND(f, g, h, a, b, c, d, e, W(51), 0x34b0bcb5)
2330+ ROUND(e, f, g, h, a, b, c, d, W(52), 0x391c0cb3)
2331+ ROUND(d, e, f, g, h, a, b, c, W(53), 0x4ed8aa4a)
2332+ ROUND(c, d, e, f, g, h, a, b, W(54), 0x5b9cca4f)
2333+ ROUND(b, c, d, e, f, g, h, a, W(55), 0x682e6ff3)
2334+ ROUND(a, b, c, d, e, f, g, h, W(56), 0x748f82ee)
2335+ ROUND(h, a, b, c, d, e, f, g, W(57), 0x78a5636f)
2336+ ROUND(g, h, a, b, c, d, e, f, W(58), 0x84c87814)
2337+ ROUND(f, g, h, a, b, c, d, e, W(59), 0x8cc70208)
2338+ ROUND(e, f, g, h, a, b, c, d, W(60), 0x90befffa)
2339+ ROUND(d, e, f, g, h, a, b, c, W(61), 0xa4506ceb)
2340+ ROUND(c, d, e, f, g, h, a, b, W(62), 0xbef9a3f7)
2341+ ROUND(b, c, d, e, f, g, h, a, W(63), 0xc67178f2)
2342+
2343+ state[0] += a;
2344+ state[1] += b;
2345+ state[2] += c;
2346+ state[3] += d;
2347+ state[4] += e;
2348+ state[5] += f;
2349+ state[6] += g;
2350+ state[7] += h;
2351+
2352+ /* Zeroize sensitive information. */
2353+ memset((unsigned char*) x, 0, sizeof(x));
2354+}
2355+/* }}} */
2356+
2357+/* {{{ SHA256Encode
2358+ Encodes input (php_uint32) into output (unsigned char). Assumes len is
2359+ a multiple of 4.
2360+ */
2361+static void SHA256Encode(output, input, len)
2362+unsigned char *output;
2363+php_uint32 *input;
2364+unsigned int len;
2365+{
2366+ unsigned int i, j;
2367+
2368+ for (i = 0, j = 0; j < len; i++, j += 4) {
2369+ output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
2370+ output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
2371+ output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
2372+ output[j + 3] = (unsigned char) (input[i] & 0xff);
2373+ }
2374+}
2375+/* }}} */
2376+
2377+/* {{{ SHA256Decode
2378+ Decodes input (unsigned char) into output (php_uint32). Assumes len is
2379+ a multiple of 4.
2380+ */
2381+static void SHA256Decode(output, input, len)
2382+php_uint32 *output;
2383+const unsigned char *input;
2384+unsigned int len;
2385+{
2386+ unsigned int i, j;
2387+
2388+ for (i = 0, j = 0; j < len; i++, j += 4)
2389+ output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
2390+ (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
2391+}
2392+/* }}} */
2393+
2394+/*
2395+ * Local variables:
2396+ * tab-width: 4
2397+ * c-basic-offset: 4
2398+ * End:
2399+ * vim600: sw=4 ts=4 fdm=marker
2400+ * vim<600: sw=4 ts=4
2401+ */
2402diff -Nura php-5.0.5/ext/standard/sha256.h hardening-patch-5.0.5-0.4.2/ext/standard/sha256.h
2403--- php-5.0.5/ext/standard/sha256.h 1970-01-01 01:00:00.000000000 +0100
2404+++ hardening-patch-5.0.5-0.4.2/ext/standard/sha256.h 2005-09-07 14:19:05.000000000 +0200
2405@@ -0,0 +1,40 @@
2406+/*
2407+ +----------------------------------------------------------------------+
2408+ | PHP Version 5 |
2409+ +----------------------------------------------------------------------+
2410+ | Copyright (c) 1997-2004 The PHP Group |
2411+ +----------------------------------------------------------------------+
2412+ | This source file is subject to version 3.0 of the PHP license, |
2413+ | that is bundled with this package in the file LICENSE, and is |
2414+ | available through the world-wide-web at the following url: |
2415+ | http://www.php.net/license/3_0.txt. |
2416+ | If you did not receive a copy of the PHP license and are unable to |
2417+ | obtain it through the world-wide-web, please send a note to |
2418+ | license@php.net so we can mail you a copy immediately. |
2419+ +----------------------------------------------------------------------+
2420+ | Author: Stefan Esser <sesser@php.net> |
2421+ +----------------------------------------------------------------------+
2422+*/
2423+
2424+/* $Id: sha256.h,v 1.4 2004/01/08 17:32:52 sniper Exp $ */
2425+
2426+#ifndef SHA256_H
2427+#define SHA256_H
2428+
2429+#include "ext/standard/basic_functions.h"
2430+
2431+/* SHA1 context. */
2432+typedef struct {
2433+ php_uint32 state[8]; /* state (ABCD) */
2434+ php_uint32 count[2]; /* number of bits, modulo 2^64 (lsb first) */
2435+ unsigned char buffer[64]; /* input buffer */
2436+} PHP_SHA256_CTX;
2437+
2438+PHPAPI void PHP_SHA256Init(PHP_SHA256_CTX *);
2439+PHPAPI void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, unsigned int);
2440+PHPAPI void PHP_SHA256Final(unsigned char[32], PHP_SHA256_CTX *);
2441+
2442+PHP_FUNCTION(sha256);
2443+PHP_FUNCTION(sha256_file);
2444+
2445+#endif
2446diff -Nura php-5.0.5/ext/standard/syslog.c hardening-patch-5.0.5-0.4.2/ext/standard/syslog.c
2447--- php-5.0.5/ext/standard/syslog.c 2005-07-15 11:29:19.000000000 +0200
2448+++ hardening-patch-5.0.5-0.4.2/ext/standard/syslog.c 2005-09-07 13:49:17.000000000 +0200
2449@@ -42,6 +42,7 @@
2450 */
2451 PHP_MINIT_FUNCTION(syslog)
2452 {
2453+#if !HARDENING_PATCH
2454 /* error levels */
2455 REGISTER_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
2456 REGISTER_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
2457@@ -97,7 +98,7 @@
2458 /* AIX doesn't have LOG_PERROR */
2459 REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
2460 #endif
2461-
2462+#endif
2463 return SUCCESS;
2464 }
2465 /* }}} */
2466diff -Nura php-5.0.5/ext/varfilter/config.m4 hardening-patch-5.0.5-0.4.2/ext/varfilter/config.m4
2467--- php-5.0.5/ext/varfilter/config.m4 1970-01-01 01:00:00.000000000 +0100
2468+++ hardening-patch-5.0.5-0.4.2/ext/varfilter/config.m4 2005-09-07 13:49:17.000000000 +0200
2469@@ -0,0 +1,11 @@
2470+dnl
2471+dnl $Id: config.m4,v 1.1 2004/11/14 13:27:16 ionic Exp $
2472+dnl
2473+
2474+PHP_ARG_ENABLE(varfilter, whether to enable Hardening-Patch's variable filter,
2475+[ --disable-varfilter Disable Hardening-Patch's variable filter], yes)
2476+
2477+if test "$PHP_VARFILTER" != "no"; then
2478+ AC_DEFINE(HAVE_VARFILTER, 1, [ ])
2479+ PHP_NEW_EXTENSION(varfilter, varfilter.c, $ext_shared)
2480+fi
2481diff -Nura php-5.0.5/ext/varfilter/CREDITS hardening-patch-5.0.5-0.4.2/ext/varfilter/CREDITS
2482--- php-5.0.5/ext/varfilter/CREDITS 1970-01-01 01:00:00.000000000 +0100
2483+++ hardening-patch-5.0.5-0.4.2/ext/varfilter/CREDITS 2005-09-07 13:49:17.000000000 +0200
2484@@ -0,0 +1,2 @@
2485+varfilter
2486+Stefan Esser
2487\ Kein Zeilenumbruch am Dateiende.
2488diff -Nura php-5.0.5/ext/varfilter/php_varfilter.h hardening-patch-5.0.5-0.4.2/ext/varfilter/php_varfilter.h
2489--- php-5.0.5/ext/varfilter/php_varfilter.h 1970-01-01 01:00:00.000000000 +0100
2490+++ hardening-patch-5.0.5-0.4.2/ext/varfilter/php_varfilter.h 2005-09-07 13:49:17.000000000 +0200
2491@@ -0,0 +1,111 @@
2492+/*
2493+ +----------------------------------------------------------------------+
2494+ | Hardened-PHP Project's varfilter extension |
2495+ +----------------------------------------------------------------------+
2496+ | Copyright (c) 2004-2005 Stefan Esser |
2497+ +----------------------------------------------------------------------+
2498+ | This source file is subject to version 2.02 of the PHP license, |
2499+ | that is bundled with this package in the file LICENSE, and is |
2500+ | available at through the world-wide-web at |
2501+ | http://www.php.net/license/2_02.txt. |
2502+ | If you did not receive a copy of the PHP license and are unable to |
2503+ | obtain it through the world-wide-web, please send a note to |
2504+ | license@php.net so we can mail you a copy immediately. |
2505+ +----------------------------------------------------------------------+
2506+ | Author: Stefan Esser <sesser@hardened-php.net> |
2507+ +----------------------------------------------------------------------+
2508+
2509+ $Id: php_varfilter.h,v 1.1 2004/11/14 13:27:16 ionic Exp $
2510+*/
2511+
2512+#ifndef PHP_VARFILTER_H
2513+#define PHP_VARFILTER_H
2514+
2515+extern zend_module_entry varfilter_module_entry;
2516+#define phpext_varfilter_ptr &varfilter_module_entry
2517+
2518+#ifdef PHP_WIN32
2519+#define PHP_VARFILTER_API __declspec(dllexport)
2520+#else
2521+#define PHP_VARFILTER_API
2522+#endif
2523+
2524+#ifdef ZTS
2525+#include "TSRM.h"
2526+#endif
2527+
2528+#include "SAPI.h"
2529+
2530+#include "php_variables.h"
2531+
2532+
2533+PHP_MINIT_FUNCTION(varfilter);
2534+PHP_MSHUTDOWN_FUNCTION(varfilter);
2535+PHP_RINIT_FUNCTION(varfilter);
2536+PHP_RSHUTDOWN_FUNCTION(varfilter);
2537+PHP_MINFO_FUNCTION(varfilter);
2538+
2539+
2540+ZEND_BEGIN_MODULE_GLOBALS(varfilter)
2541+/* request variables */
2542+ long max_request_variables;
2543+ long cur_request_variables;
2544+ long max_varname_length;
2545+ long max_totalname_length;
2546+ long max_value_length;
2547+ long max_array_depth;
2548+ long max_array_index_length;
2549+/* cookie variables */
2550+ long max_cookie_vars;
2551+ long cur_cookie_vars;
2552+ long max_cookie_name_length;
2553+ long max_cookie_totalname_length;
2554+ long max_cookie_value_length;
2555+ long max_cookie_array_depth;
2556+ long max_cookie_array_index_length;
2557+/* get variables */
2558+ long max_get_vars;
2559+ long cur_get_vars;
2560+ long max_get_name_length;
2561+ long max_get_totalname_length;
2562+ long max_get_value_length;
2563+ long max_get_array_depth;
2564+ long max_get_array_index_length;
2565+/* post variables */
2566+ long max_post_vars;
2567+ long cur_post_vars;
2568+ long max_post_name_length;
2569+ long max_post_totalname_length;
2570+ long max_post_value_length;
2571+ long max_post_array_depth;
2572+ long max_post_array_index_length;
2573+/* fileupload */
2574+ long max_uploads;
2575+ long cur_uploads;
2576+ zend_bool disallow_elf_files;
2577+ char *verification_script;
2578+
2579+ZEND_END_MODULE_GLOBALS(varfilter)
2580+
2581+
2582+#ifdef ZTS
2583+#define VARFILTER_G(v) TSRMG(varfilter_globals_id, zend_varfilter_globals *, v)
2584+#else
2585+#define VARFILTER_G(v) (varfilter_globals.v)
2586+#endif
2587+
2588+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter);
2589+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter);
2590+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter);
2591+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter);
2592+
2593+#endif /* PHP_VARFILTER_H */
2594+
2595+
2596+/*
2597+ * Local variables:
2598+ * tab-width: 4
2599+ * c-basic-offset: 4
2600+ * indent-tabs-mode: t
2601+ * End:
2602+ */
2603diff -Nura php-5.0.5/ext/varfilter/varfilter.c hardening-patch-5.0.5-0.4.2/ext/varfilter/varfilter.c
2604--- php-5.0.5/ext/varfilter/varfilter.c 1970-01-01 01:00:00.000000000 +0100
2605+++ hardening-patch-5.0.5-0.4.2/ext/varfilter/varfilter.c 2005-09-07 14:19:05.000000000 +0200
2606@@ -0,0 +1,602 @@
2607+/*
2608+ +----------------------------------------------------------------------+
2609+ | Hardened-PHP Project's varfilter extension |
2610+ +----------------------------------------------------------------------+
2611+ | Copyright (c) 2004-2005 Stefan Esser |
2612+ +----------------------------------------------------------------------+
2613+ | This source file is subject to version 2.02 of the PHP license, |
2614+ | that is bundled with this package in the file LICENSE, and is |
2615+ | available at through the world-wide-web at |
2616+ | http://www.php.net/license/2_02.txt. |
2617+ | If you did not receive a copy of the PHP license and are unable to |
2618+ | obtain it through the world-wide-web, please send a note to |
2619+ | license@php.net so we can mail you a copy immediately. |
2620+ +----------------------------------------------------------------------+
2621+ | Author: Stefan Esser <sesser@hardened-php.net> |
2622+ +----------------------------------------------------------------------+
2623+
2624+ $Id: varfilter.c,v 1.1 2004/11/14 13:27:16 ionic Exp $
2625+*/
2626+
2627+#ifdef HAVE_CONFIG_H
2628+#include "config.h"
2629+#endif
2630+
2631+#include "php.h"
2632+#include "php_ini.h"
2633+#include "ext/standard/info.h"
2634+#include "php_varfilter.h"
2635+#include "hardening_patch.h"
2636+
2637+ZEND_DECLARE_MODULE_GLOBALS(varfilter)
2638+
2639+/* True global resources - no need for thread safety here */
2640+static int le_varfilter;
2641+
2642+/* {{{ varfilter_module_entry
2643+ */
2644+zend_module_entry varfilter_module_entry = {
2645+#if ZEND_MODULE_API_NO >= 20010901
2646+ STANDARD_MODULE_HEADER,
2647+#endif
2648+ "varfilter",
2649+ NULL,
2650+ PHP_MINIT(varfilter),
2651+ PHP_MSHUTDOWN(varfilter),
2652+ PHP_RINIT(varfilter), /* Replace with NULL if there's nothing to do at request start */
2653+ PHP_RSHUTDOWN(varfilter), /* Replace with NULL if there's nothing to do at request end */
2654+ PHP_MINFO(varfilter),
2655+#if ZEND_MODULE_API_NO >= 20010901
2656+ "0.3.2", /* Replace with version number for your extension */
2657+#endif
2658+ STANDARD_MODULE_PROPERTIES
2659+};
2660+/* }}} */
2661+
2662+#ifdef COMPILE_DL_VARFILTER
2663+ZEND_GET_MODULE(varfilter)
2664+#endif
2665+
2666+/* {{{ PHP_INI
2667+ */
2668+PHP_INI_BEGIN()
2669+ /* for backward compatibility */
2670+ STD_PHP_INI_ENTRY("varfilter.max_request_variables", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2671+ STD_PHP_INI_ENTRY("varfilter.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2672+ STD_PHP_INI_ENTRY("varfilter.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2673+ STD_PHP_INI_ENTRY("varfilter.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2674+ STD_PHP_INI_ENTRY("varfilter.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2675+ STD_PHP_INI_ENTRY("varfilter.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2676+
2677+ STD_PHP_INI_ENTRY("hphp.request.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_request_variables, zend_varfilter_globals, varfilter_globals)
2678+ STD_PHP_INI_ENTRY("hphp.request.max_varname_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_varname_length, zend_varfilter_globals, varfilter_globals)
2679+ STD_PHP_INI_ENTRY("hphp.request.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_value_length, zend_varfilter_globals, varfilter_globals)
2680+ STD_PHP_INI_ENTRY("hphp.request.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_array_depth, zend_varfilter_globals, varfilter_globals)
2681+ STD_PHP_INI_ENTRY("hphp.request.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_totalname_length, zend_varfilter_globals, varfilter_globals)
2682+ STD_PHP_INI_ENTRY("hphp.request.max_array_index_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_array_index_length, zend_varfilter_globals, varfilter_globals)
2683+
2684+ STD_PHP_INI_ENTRY("hphp.cookie.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_vars, zend_varfilter_globals, varfilter_globals)
2685+ STD_PHP_INI_ENTRY("hphp.cookie.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_cookie_name_length, zend_varfilter_globals, varfilter_globals)
2686+ STD_PHP_INI_ENTRY("hphp.cookie.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_cookie_totalname_length, zend_varfilter_globals, varfilter_globals)
2687+ STD_PHP_INI_ENTRY("hphp.cookie.max_value_length", "10000", PHP_INI_PERDIR, OnUpdateLong, max_cookie_value_length, zend_varfilter_globals, varfilter_globals)
2688+ STD_PHP_INI_ENTRY("hphp.cookie.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_cookie_array_depth, zend_varfilter_globals, varfilter_globals)
2689+ 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)
2690+
2691+ STD_PHP_INI_ENTRY("hphp.get.max_vars", "100", PHP_INI_PERDIR, OnUpdateLong, max_get_vars, zend_varfilter_globals, varfilter_globals)
2692+ STD_PHP_INI_ENTRY("hphp.get.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_get_name_length, zend_varfilter_globals, varfilter_globals)
2693+ STD_PHP_INI_ENTRY("hphp.get.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_get_totalname_length, zend_varfilter_globals, varfilter_globals)
2694+ STD_PHP_INI_ENTRY("hphp.get.max_value_length", "512", PHP_INI_PERDIR, OnUpdateLong, max_get_value_length, zend_varfilter_globals, varfilter_globals)
2695+ STD_PHP_INI_ENTRY("hphp.get.max_array_depth", "50", PHP_INI_PERDIR, OnUpdateLong, max_get_array_depth, zend_varfilter_globals, varfilter_globals)
2696+ 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)
2697+
2698+ STD_PHP_INI_ENTRY("hphp.post.max_vars", "200", PHP_INI_PERDIR, OnUpdateLong, max_post_vars, zend_varfilter_globals, varfilter_globals)
2699+ STD_PHP_INI_ENTRY("hphp.post.max_name_length", "64", PHP_INI_PERDIR, OnUpdateLong, max_post_name_length, zend_varfilter_globals, varfilter_globals)
2700+ STD_PHP_INI_ENTRY("hphp.post.max_totalname_length", "256", PHP_INI_PERDIR, OnUpdateLong, max_post_totalname_length, zend_varfilter_globals, varfilter_globals)
2701+ STD_PHP_INI_ENTRY("hphp.post.max_value_length", "65000", PHP_INI_PERDIR, OnUpdateLong, max_post_value_length, zend_varfilter_globals, varfilter_globals)
2702+ STD_PHP_INI_ENTRY("hphp.post.max_array_depth", "100", PHP_INI_PERDIR, OnUpdateLong, max_post_array_depth, zend_varfilter_globals, varfilter_globals)
2703+ 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)
2704+
2705+ STD_PHP_INI_ENTRY("hphp.upload.max_uploads", "25", PHP_INI_PERDIR, OnUpdateLong, max_uploads, zend_varfilter_globals, varfilter_globals)
2706+ STD_PHP_INI_ENTRY("hphp.upload.disallow_elf_files", "1", PHP_INI_SYSTEM, OnUpdateBool, disallow_elf_files, zend_varfilter_globals, varfilter_globals)
2707+ STD_PHP_INI_ENTRY("hphp.upload.verification_script", NULL, PHP_INI_SYSTEM, OnUpdateString, verification_script, zend_varfilter_globals, varfilter_globals)
2708+
2709+
2710+PHP_INI_END()
2711+/* }}} */
2712+
2713+/* {{{ php_varfilter_init_globals
2714+ */
2715+static void php_varfilter_init_globals(zend_varfilter_globals *varfilter_globals)
2716+{
2717+ varfilter_globals->max_request_variables = 200;
2718+ varfilter_globals->max_varname_length = 64;
2719+ varfilter_globals->max_value_length = 10000;
2720+ varfilter_globals->max_array_depth = 100;
2721+ varfilter_globals->max_totalname_length = 256;
2722+ varfilter_globals->max_array_index_length = 64;
2723+
2724+ varfilter_globals->max_cookie_vars = 100;
2725+ varfilter_globals->max_cookie_name_length = 64;
2726+ varfilter_globals->max_cookie_totalname_length = 256;
2727+ varfilter_globals->max_cookie_value_length = 10000;
2728+ varfilter_globals->max_cookie_array_depth = 100;
2729+ varfilter_globals->max_cookie_array_index_length = 64;
2730+
2731+ varfilter_globals->max_get_vars = 100;
2732+ varfilter_globals->max_get_name_length = 64;
2733+ varfilter_globals->max_get_totalname_length = 256;
2734+ varfilter_globals->max_get_value_length = 512;
2735+ varfilter_globals->max_get_array_depth = 50;
2736+ varfilter_globals->max_get_array_index_length = 64;
2737+
2738+ varfilter_globals->max_post_vars = 200;
2739+ varfilter_globals->max_post_name_length = 64;
2740+ varfilter_globals->max_post_totalname_length = 256;
2741+ varfilter_globals->max_post_value_length = 65000;
2742+ varfilter_globals->max_post_array_depth = 100;
2743+ varfilter_globals->max_post_array_index_length = 64;
2744+
2745+ varfilter_globals->max_uploads = 25;
2746+ varfilter_globals->disallow_elf_files = 1;
2747+ varfilter_globals->verification_script = NULL;
2748+}
2749+/* }}} */
2750+
2751+/* {{{ PHP_MINIT_FUNCTION
2752+ */
2753+PHP_MINIT_FUNCTION(varfilter)
2754+{
2755+ ZEND_INIT_MODULE_GLOBALS(varfilter, php_varfilter_init_globals, NULL);
2756+ REGISTER_INI_ENTRIES();
2757+
2758+ sapi_register_input_filter(varfilter_input_filter);
2759+ sapi_register_pre_upload_filter(varfilter_pre_upload_filter);
2760+ sapi_register_upload_content_filter(varfilter_upload_content_filter);
2761+ sapi_register_post_upload_filter(varfilter_post_upload_filter);
2762+
2763+ return SUCCESS;
2764+}
2765+/* }}} */
2766+
2767+/* {{{ PHP_MSHUTDOWN_FUNCTION
2768+ */
2769+PHP_MSHUTDOWN_FUNCTION(varfilter)
2770+{
2771+ UNREGISTER_INI_ENTRIES();
2772+
2773+ return SUCCESS;
2774+}
2775+/* }}} */
2776+
2777+/* Remove if there's nothing to do at request start */
2778+/* {{{ PHP_RINIT_FUNCTION
2779+ */
2780+PHP_RINIT_FUNCTION(varfilter)
2781+{
2782+ VARFILTER_G(cur_request_variables) = 0;
2783+ VARFILTER_G(cur_get_vars) = 0;
2784+ VARFILTER_G(cur_post_vars) = 0;
2785+ VARFILTER_G(cur_cookie_vars) = 0;
2786+
2787+ VARFILTER_G(cur_uploads) = 0;
2788+
2789+ return SUCCESS;
2790+}
2791+/* }}} */
2792+
2793+/* Remove if there's nothing to do at request end */
2794+/* {{{ PHP_RSHUTDOWN_FUNCTION
2795+ */
2796+PHP_RSHUTDOWN_FUNCTION(varfilter)
2797+{
2798+ return SUCCESS;
2799+}
2800+/* }}} */
2801+
2802+/* {{{ PHP_MINFO_FUNCTION
2803+ */
2804+PHP_MINFO_FUNCTION(varfilter)
2805+{
2806+ php_info_print_table_start();
2807+ php_info_print_table_header(2, "Hardening-Patch's variable filter support", "enabled");
2808+ php_info_print_table_end();
2809+
2810+ DISPLAY_INI_ENTRIES();
2811+}
2812+/* }}} */
2813+
2814+/* {{{ normalize_varname
2815+ */
2816+static void normalize_varname(char *varname)
2817+{
2818+ char *s=varname, *index=NULL, *indexend=NULL, *p;
2819+
2820+ /* overjump leading space */
2821+ while (*s == ' ') {
2822+ s++;
2823+ }
2824+
2825+ /* and remove it */
2826+ if (s != varname) {
2827+ memmove(varname, s, strlen(s)+1);
2828+ }
2829+
2830+ for (p=varname; *p && *p != '['; p++) {
2831+ switch(*p) {
2832+ case ' ':
2833+ case '.':
2834+ *p='_';
2835+ break;
2836+ }
2837+ }
2838+
2839+ /* find index */
2840+ index = strchr(varname, '[');
2841+ if (index) {
2842+ index++;
2843+ s=index;
2844+ } else {
2845+ return;
2846+ }
2847+
2848+ /* done? */
2849+ while (index) {
2850+
2851+ while (*index == ' ' || *index == '\r' || *index == '\n' || *index=='\t') {
2852+ index++;
2853+ }
2854+ indexend = strchr(index, ']');
2855+ indexend = indexend ? indexend + 1 : index + strlen(index);
2856+
2857+ if (s != index) {
2858+ memmove(s, index, strlen(index)+1);
2859+ s += indexend-index;
2860+ } else {
2861+ s = indexend;
2862+ }
2863+
2864+ if (*s == '[') {
2865+ s++;
2866+ index = s;
2867+ } else {
2868+ index = NULL;
2869+ }
2870+ }
2871+ *s++='\0';
2872+}
2873+/* }}} */
2874+
2875+/* {{{ SAPI_PRE_UPLOAD_FILTER_FUNC
2876+ */
2877+SAPI_PRE_UPLOAD_FILTER_FUNC(varfilter_pre_upload_filter)
2878+{
2879+ /* Drop this fileupload if the limit is reached */
2880+ if (VARFILTER_G(max_uploads) && VARFILTER_G(max_uploads) <= VARFILTER_G(cur_uploads)) {
2881+ php_security_log(S_FILES, "configured fileupload limit exceeded - file dropped");
2882+ return FAILURE;
2883+ }
2884+
2885+ return SUCCESS;
2886+}
2887+/* }}} */
2888+
2889+/* {{{ SAPI_UPLOAD_CONTENT_FILTER_FUNC
2890+ */
2891+SAPI_UPLOAD_CONTENT_FILTER_FUNC(varfilter_upload_content_filter)
2892+{
2893+
2894+ if (VARFILTER_G(disallow_elf_files)) {
2895+
2896+ if (offset == 0 && buffer_len > 10) {
2897+
2898+ if (buffer[0] == 0x7F && buffer[1] == 'E' && buffer[2] == 'L' && buffer[3] == 'F') {
2899+ php_security_log(S_FILES, "uploaded file is an ELF executable - file dropped");
2900+ return FAILURE;
2901+ }
2902+ }
2903+
2904+ }
2905+
2906+ return SUCCESS;
2907+}
2908+/* }}} */
2909+
2910+/* {{{ SAPI_POST_UPLOAD_FILTER_FUNC
2911+ */
2912+SAPI_POST_UPLOAD_FILTER_FUNC(varfilter_post_upload_filter)
2913+{
2914+ int retval = SUCCESS;
2915+
2916+ if (VARFILTER_G(verification_script)) {
2917+ char cmd[8192];
2918+ FILE *in;
2919+ int first=1;
2920+
2921+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s", VARFILTER_G(verification_script), tmpfilename);
2922+
2923+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
2924+ php_security_log(S_FILES, "unable to execute fileupload verification script %s - file dropped", VARFILTER_G(verification_script));
2925+ return FAILURE;
2926+ }
2927+
2928+ retval = FAILURE;
2929+
2930+ /* read and forget the result */
2931+ while (1) {
2932+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
2933+ if (readbytes<=0) {
2934+ break;
2935+ }
2936+ if (first) {
2937+ retval = atoi(cmd) == 1 ? SUCCESS : FAILURE;
2938+ first = 0;
2939+ }
2940+ }
2941+ pclose(in);
2942+ }
2943+
2944+ if (retval != SUCCESS) {
2945+ php_security_log(S_FILES, "fileupload verification script disallows file - file dropped");
2946+ return FAILURE;
2947+ }
2948+
2949+ VARFILTER_G(cur_uploads)++;
2950+ return SUCCESS;
2951+}
2952+/* }}} */
2953+
2954+/* {{{ SAPI_INPUT_FILTER_FUNC
2955+ */
2956+SAPI_INPUT_FILTER_FUNC(varfilter_input_filter)
2957+{
2958+ char *index, *prev_index = NULL, *copy_var;
2959+ unsigned int var_len, total_len, depth = 0, rv;
2960+
2961+ /* Drop this variable if the limit is reached */
2962+ if (VARFILTER_G(max_request_variables) && VARFILTER_G(max_request_variables) <= VARFILTER_G(cur_request_variables)) {
2963+ php_security_log(S_VARS, "configured request variable limit exceeded - dropped %s", var);
2964+ return 0;
2965+ }
2966+ switch (arg) {
2967+ case PARSE_GET:
2968+ if (VARFILTER_G(max_get_vars) && VARFILTER_G(max_get_vars) <= VARFILTER_G(cur_get_vars)) {
2969+ php_security_log(S_VARS, "configured GET variable limit exceeded - dropped %s", var);
2970+ return 0;
2971+ }
2972+ break;
2973+ case PARSE_COOKIE:
2974+ if (VARFILTER_G(max_cookie_vars) && VARFILTER_G(max_cookie_vars) <= VARFILTER_G(cur_cookie_vars)) {
2975+ php_security_log(S_VARS, "configured COOKIE variable limit exceeded - dropped %s", var);
2976+ return 0;
2977+ }
2978+ break;
2979+ case PARSE_POST:
2980+ if (VARFILTER_G(max_post_vars) && VARFILTER_G(max_post_vars) <= VARFILTER_G(cur_post_vars)) {
2981+ php_security_log(S_VARS, "configured POST variable limit exceeded - dropped %s", var);
2982+ return 0;
2983+ }
2984+ break;
2985+ }
2986+
2987+
2988+ /* Drop this variable if it exceeds the value length limit */
2989+ if (VARFILTER_G(max_value_length) && VARFILTER_G(max_value_length) < val_len) {
2990+ php_security_log(S_VARS, "configured request variable value length limit exceeded - dropped %s", var);
2991+ return 0;
2992+ }
2993+ switch (arg) {
2994+ case PARSE_GET:
2995+ if (VARFILTER_G(max_get_value_length) && VARFILTER_G(max_get_value_length) < val_len) {
2996+ php_security_log(S_VARS, "configured GET variable value length limit exceeded - dropped %s", var);
2997+ return 0;
2998+ }
2999+ break;
3000+ case PARSE_COOKIE:
3001+ if (VARFILTER_G(max_cookie_value_length) && VARFILTER_G(max_cookie_value_length) < val_len) {
3002+ php_security_log(S_VARS, "configured COOKIE variable value length limit exceeded - dropped %s", var);
3003+ return 0;
3004+ }
3005+ break;
3006+ case PARSE_POST:
3007+ if (VARFILTER_G(max_post_value_length) && VARFILTER_G(max_post_value_length) < val_len) {
3008+ php_security_log(S_VARS, "configured POST variable value length limit exceeded - dropped %s", var);
3009+ return 0;
3010+ }
3011+ break;
3012+ }
3013+
3014+ /* Normalize the variable name */
3015+ normalize_varname(var);
3016+
3017+ /* Find length of variable name */
3018+ index = strchr(var, '[');
3019+ total_len = strlen(var);
3020+ var_len = index ? index-var : total_len;
3021+
3022+ /* Drop this variable if it exceeds the varname/total length limit */
3023+ if (VARFILTER_G(max_varname_length) && VARFILTER_G(max_varname_length) < var_len) {
3024+ php_security_log(S_VARS, "configured request variable name length limit exceeded - dropped %s", var);
3025+ return 0;
3026+ }
3027+ if (VARFILTER_G(max_totalname_length) && VARFILTER_G(max_totalname_length) < total_len) {
3028+ php_security_log(S_VARS, "configured request variable total name length limit exceeded - dropped %s", var);
3029+ return 0;
3030+ }
3031+ switch (arg) {
3032+ case PARSE_GET:
3033+ if (VARFILTER_G(max_get_name_length) && VARFILTER_G(max_get_name_length) < var_len) {
3034+ php_security_log(S_VARS, "configured GET variable name length limit exceeded - dropped %s", var);
3035+ return 0;
3036+ }
3037+ if (VARFILTER_G(max_get_totalname_length) && VARFILTER_G(max_get_totalname_length) < var_len) {
3038+ php_security_log(S_VARS, "configured GET variable total name length limit exceeded - dropped %s", var);
3039+ return 0;
3040+ }
3041+ break;
3042+ case PARSE_COOKIE:
3043+ if (VARFILTER_G(max_cookie_name_length) && VARFILTER_G(max_cookie_name_length) < var_len) {
3044+ php_security_log(S_VARS, "configured COOKIE variable name length limit exceeded - dropped %s", var);
3045+ return 0;
3046+ }
3047+ if (VARFILTER_G(max_cookie_totalname_length) && VARFILTER_G(max_cookie_totalname_length) < var_len) {
3048+ php_security_log(S_VARS, "configured COOKIE variable total name length limit exceeded - dropped %s", var);
3049+ return 0;
3050+ }
3051+ break;
3052+ case PARSE_POST:
3053+ if (VARFILTER_G(max_post_name_length) && VARFILTER_G(max_post_name_length) < var_len) {
3054+ php_security_log(S_VARS, "configured POST variable name length limit exceeded - dropped %s", var);
3055+ return 0;
3056+ }
3057+ if (VARFILTER_G(max_post_totalname_length) && VARFILTER_G(max_post_totalname_length) < var_len) {
3058+ php_security_log(S_VARS, "configured POST variable total name length limit exceeded - dropped %s", var);
3059+ return 0;
3060+ }
3061+ break;
3062+ }
3063+
3064+ /* Find out array depth */
3065+ while (index) {
3066+ unsigned int index_length;
3067+
3068+ depth++;
3069+ index = strchr(index+1, '[');
3070+
3071+ if (prev_index) {
3072+ index_length = index ? index - 1 - prev_index - 1: strlen(prev_index);
3073+
3074+ if (VARFILTER_G(max_array_index_length) && VARFILTER_G(max_array_index_length) < index_length) {
3075+ php_security_log(S_VARS, "configured request variable array index length limit exceeded - dropped %s", var);
3076+ return 0;
3077+ }
3078+ switch (arg) {
3079+ case PARSE_GET:
3080+ if (VARFILTER_G(max_get_array_index_length) && VARFILTER_G(max_get_array_index_length) < index_length) {
3081+ php_security_log(S_VARS, "configured GET variable array index length limit exceeded - dropped %s", var);
3082+ return 0;
3083+ }
3084+ break;
3085+ case PARSE_COOKIE:
3086+ if (VARFILTER_G(max_cookie_array_index_length) && VARFILTER_G(max_cookie_array_index_length) < index_length) {
3087+ php_security_log(S_VARS, "configured COOKIE variable array index length limit exceeded - dropped %s", var);
3088+ return 0;
3089+ }
3090+ break;
3091+ case PARSE_POST:
3092+ if (VARFILTER_G(max_post_array_index_length) && VARFILTER_G(max_post_array_index_length) < index_length) {
3093+ php_security_log(S_VARS, "configured POST variable array index length limit exceeded - dropped %s", var);
3094+ return 0;
3095+ }
3096+ break;
3097+ }
3098+ prev_index = index;
3099+ }
3100+
3101+ }
3102+
3103+ /* Drop this variable if it exceeds the array depth limit */
3104+ if (VARFILTER_G(max_array_depth) && VARFILTER_G(max_array_depth) < depth) {
3105+ php_security_log(S_VARS, "configured request variable array depth limit exceeded - dropped %s", var);
3106+ return 0;
3107+ }
3108+ switch (arg) {
3109+ case PARSE_GET:
3110+ if (VARFILTER_G(max_get_array_depth) && VARFILTER_G(max_get_array_depth) < depth) {
3111+ php_security_log(S_VARS, "configured GET variable array depth limit exceeded - dropped %s", var);
3112+ return 0;
3113+ }
3114+ break;
3115+ case PARSE_COOKIE:
3116+ if (VARFILTER_G(max_cookie_array_depth) && VARFILTER_G(max_cookie_array_depth) < depth) {
3117+ php_security_log(S_VARS, "configured COOKIE variable array depth limit exceeded - dropped %s", var);
3118+ return 0;
3119+ }
3120+ break;
3121+ case PARSE_POST:
3122+ if (VARFILTER_G(max_post_array_depth) && VARFILTER_G(max_post_array_depth) < depth) {
3123+ php_security_log(S_VARS, "configured POST variable array depth limit exceeded - dropped %s", var);
3124+ return 0;
3125+ }
3126+ break;
3127+ }
3128+
3129+ /* Drop this variable if it is one of GLOBALS, _GET, _POST, ... */
3130+ /* This is to protect several silly scripts that do globalizing themself */
3131+
3132+ switch (var_len) {
3133+ case 18:
3134+ if (memcmp(var, "HTTP_RAW_POST_DATA", 18)==0) goto protected_varname;
3135+ break;
3136+ case 17:
3137+ if (memcmp(var, "HTTP_SESSION_VARS", 17)==0) goto protected_varname;
3138+ break;
3139+ case 16:
3140+ if (memcmp(var, "HTTP_SERVER_VARS", 16)==0) goto protected_varname;
3141+ if (memcmp(var, "HTTP_COOKIE_VARS", 16)==0) goto protected_varname;
3142+ break;
3143+ case 15:
3144+ if (memcmp(var, "HTTP_POST_FILES", 15)==0) goto protected_varname;
3145+ break;
3146+ case 14:
3147+ if (memcmp(var, "HTTP_POST_VARS", 14)==0) goto protected_varname;
3148+ break;
3149+ case 13:
3150+ if (memcmp(var, "HTTP_GET_VARS", 13)==0) goto protected_varname;
3151+ if (memcmp(var, "HTTP_ENV_VARS", 13)==0) goto protected_varname;
3152+ break;
3153+ case 8:
3154+ if (memcmp(var, "_SESSION", 8)==0) goto protected_varname;
3155+ if (memcmp(var, "_REQUEST", 8)==0) goto protected_varname;
3156+ break;
3157+ case 7:
3158+ if (memcmp(var, "GLOBALS", 7)==0) goto protected_varname;
3159+ if (memcmp(var, "_COOKIE", 7)==0) goto protected_varname;
3160+ if (memcmp(var, "_SERVER", 7)==0) goto protected_varname;
3161+ break;
3162+ case 6:
3163+ if (memcmp(var, "_FILES", 6)==0) goto protected_varname;
3164+ break;
3165+ case 5:
3166+ if (memcmp(var, "_POST", 5)==0) goto protected_varname;
3167+ break;
3168+ case 4:
3169+ if (memcmp(var, "_ENV", 4)==0) goto protected_varname;
3170+ if (memcmp(var, "_GET", 4)==0) goto protected_varname;
3171+ break;
3172+ }
3173+
3174+ /* Okay let PHP register this variable */
3175+ VARFILTER_G(cur_request_variables)++;
3176+ switch (arg) {
3177+ case PARSE_GET:
3178+ VARFILTER_G(cur_get_vars)++;
3179+ break;
3180+ case PARSE_COOKIE:
3181+ VARFILTER_G(cur_cookie_vars)++;
3182+ break;
3183+ case PARSE_POST:
3184+ VARFILTER_G(cur_post_vars)++;
3185+ break;
3186+ }
3187+
3188+ if (new_val_len) {
3189+ *new_val_len = val_len;
3190+ }
3191+
3192+ return 1;
3193+protected_varname:
3194+ php_security_log(S_VARS, "tried to register forbidden variable '%s' through %s variables", var, arg == PARSE_GET ? "GET" : arg == PARSE_POST ? "POST" : "COOKIE");
3195+ return 0;
3196+}
3197+/* }}} */
3198+
3199+/*
3200+ * Local variables:
3201+ * tab-width: 4
3202+ * c-basic-offset: 4
3203+ * End:
3204+ * vim600: noet sw=4 ts=4 fdm=marker
3205+ * vim<600: noet sw=4 ts=4
3206+ */
3207+
3208+
3209diff -Nura php-5.0.5/main/fopen_wrappers.c hardening-patch-5.0.5-0.4.2/main/fopen_wrappers.c
3210--- php-5.0.5/main/fopen_wrappers.c 2005-07-16 14:14:44.000000000 +0200
3211+++ hardening-patch-5.0.5-0.4.2/main/fopen_wrappers.c 2005-09-07 13:49:17.000000000 +0200
3212@@ -155,6 +155,21 @@
3213 char *pathbuf;
3214 char *ptr;
3215 char *end;
3216+ char path_copy[MAXPATHLEN];
3217+ int path_len;
3218+
3219+ /* Special case path ends with a trailing slash */
3220+ path_len = strlen(path);
3221+ if (path_len >= MAXPATHLEN) {
3222+ errno = EPERM; /* we deny permission to open it */
3223+ return -1;
3224+ }
3225+ if (path_len > 0 && path[path_len-1] == PHP_DIR_SEPARATOR) {
3226+ memcpy(path_copy, path, path_len+1);
3227+ while (path_len > 0 && path_copy[path_len-1] == PHP_DIR_SEPARATOR) path_len--;
3228+ path_copy[path_len] = '\0';
3229+ path = (const char *)&path_copy;
3230+ }
3231
3232 pathbuf = estrdup(PG(open_basedir));
3233
3234diff -Nura php-5.0.5/main/hardened_globals.h hardening-patch-5.0.5-0.4.2/main/hardened_globals.h
3235--- php-5.0.5/main/hardened_globals.h 1970-01-01 01:00:00.000000000 +0100
3236+++ hardening-patch-5.0.5-0.4.2/main/hardened_globals.h 2005-09-07 13:49:17.000000000 +0200
3237@@ -0,0 +1,60 @@
3238+/*
3239+ +----------------------------------------------------------------------+
3240+ | Hardening-Patch for PHP |
3241+ +----------------------------------------------------------------------+
3242+ | Copyright (c) 2004-2005 Stefan Esser |
3243+ +----------------------------------------------------------------------+
3244+ | This source file is subject to version 2.02 of the PHP license, |
3245+ | that is bundled with this package in the file LICENSE, and is |
3246+ | available at through the world-wide-web at |
3247+ | http://www.php.net/license/2_02.txt. |
3248+ | If you did not receive a copy of the PHP license and are unable to |
3249+ | obtain it through the world-wide-web, please send a note to |
3250+ | license@php.net so we can mail you a copy immediately. |
3251+ +----------------------------------------------------------------------+
3252+ | Author: Stefan Esser <sesser@hardened-php.net> |
3253+ +----------------------------------------------------------------------+
3254+ */
3255+
3256+#ifndef HARDENED_GLOBALS_H
3257+#define HARDENED_GLOBALS_H
3258+
3259+typedef struct _hardened_globals hardened_globals_struct;
3260+
3261+#ifdef ZTS
3262+# define HG(v) TSRMG(hardened_globals_id, hardened_globals_struct *, v)
3263+extern int hardened_globals_id;
3264+#else
3265+# define HG(v) (hardened_globals.v)
3266+extern struct _hardened_globals hardened_globals;
3267+#endif
3268+
3269+
3270+struct _hardened_globals {
3271+#if HARDENING_PATCH_MM_PROTECT
3272+ unsigned int canary_1;
3273+ unsigned int canary_2;
3274+#endif
3275+#if HARDENING_PATCH_LL_PROTECT
3276+ unsigned int canary_3;
3277+ unsigned int canary_4;
3278+ unsigned int ll_canary_inited;
3279+#endif
3280+ zend_bool hphp_sql_bailout_on_error;
3281+ zend_bool hphp_multiheader;
3282+ HashTable *eval_whitelist;
3283+ HashTable *eval_blacklist;
3284+ HashTable *func_whitelist;
3285+ HashTable *func_blacklist;
3286+ unsigned int dummy;
3287+};
3288+
3289+
3290+#endif /* HARDENED_GLOBALS_H */
3291+
3292+/*
3293+ * Local variables:
3294+ * tab-width: 4
3295+ * c-basic-offset: 4
3296+ * End:
3297+ */
3298diff -Nura php-5.0.5/main/hardening_patch.c hardening-patch-5.0.5-0.4.2/main/hardening_patch.c
3299--- php-5.0.5/main/hardening_patch.c 1970-01-01 01:00:00.000000000 +0100
3300+++ hardening-patch-5.0.5-0.4.2/main/hardening_patch.c 2005-09-07 14:19:05.000000000 +0200
3301@@ -0,0 +1,323 @@
3302+/*
3303+ +----------------------------------------------------------------------+
3304+ | Hardening Patch for PHP |
3305+ +----------------------------------------------------------------------+
3306+ | Copyright (c) 2004-2005 Stefan Esser |
3307+ +----------------------------------------------------------------------+
3308+ | This source file is subject to version 2.02 of the PHP license, |
3309+ | that is bundled with this package in the file LICENSE, and is |
3310+ | available at through the world-wide-web at |
3311+ | http://www.php.net/license/2_02.txt. |
3312+ | If you did not receive a copy of the PHP license and are unable to |
3313+ | obtain it through the world-wide-web, please send a note to |
3314+ | license@php.net so we can mail you a copy immediately. |
3315+ +----------------------------------------------------------------------+
3316+ | Author: Stefan Esser <sesser@hardened-php.net> |
3317+ +----------------------------------------------------------------------+
3318+ */
3319+/* $Id: hardening_patch.c,v 1.2 2004/11/21 09:38:52 ionic Exp $ */
3320+
3321+#include "php.h"
3322+
3323+#include <stdio.h>
3324+#include <stdlib.h>
3325+
3326+#if HAVE_UNISTD_H
3327+#include <unistd.h>
3328+#endif
3329+#include "SAPI.h"
3330+#include "php_globals.h"
3331+
3332+#if HARDENING_PATCH
3333+
3334+#ifdef HAVE_SYS_SOCKET_H
3335+#include <sys/socket.h>
3336+#endif
3337+
3338+#if defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)
3339+#undef AF_UNIX
3340+#endif
3341+
3342+#if defined(AF_UNIX)
3343+#include <sys/un.h>
3344+#endif
3345+
3346+#define SYSLOG_PATH "/dev/log"
3347+
3348+#include "snprintf.h"
3349+
3350+#include "hardening_patch.h"
3351+
3352+#ifdef ZTS
3353+#include "hardened_globals.h"
3354+int hardened_globals_id;
3355+#else
3356+struct _hardened_globals hardened_globals;
3357+#endif
3358+
3359+static void hardened_globals_ctor(hardened_globals_struct *hardened_globals TSRMLS_DC)
3360+{
3361+ memset(hardened_globals, 0, sizeof(*hardened_globals));
3362+}
3363+
3364+
3365+PHPAPI void hardened_startup()
3366+{
3367+#ifdef ZTS
3368+ ts_allocate_id(&hardened_globals_id, sizeof(hardened_globals_struct), (ts_allocate_ctor) hardened_globals_ctor, NULL);
3369+#else
3370+ hardened_globals_ctor(&hardened_globals TSRMLS_CC);
3371+#endif
3372+}
3373+
3374+char *loglevel2string(int loglevel)
3375+{
3376+ switch (loglevel) {
3377+ case S_FILES:
3378+ return "FILES";
3379+ case S_INCLUDE:
3380+ return "INCLUDE";
3381+ case S_MEMORY:
3382+ return "MEMORY";
3383+ case S_MISC:
3384+ return "MISC";
3385+ case S_SQL:
3386+ return "SQL";
3387+ case S_EXECUTOR:
3388+ return "EXECUTOR";
3389+ case S_VARS:
3390+ return "VARS";
3391+ default:
3392+ return "UNKNOWN";
3393+ }
3394+}
3395+
3396+PHPAPI void php_security_log(int loglevel, char *fmt, ...)
3397+{
3398+#if defined(AF_UNIX)
3399+ int s, r, i=0;
3400+ struct sockaddr_un saun;
3401+ char buf[4096+64];
3402+ char error[4096+100];
3403+ char *ip_address;
3404+ char *fname;
3405+ int lineno;
3406+ va_list ap;
3407+ TSRMLS_FETCH();
3408+
3409+ if (EG(hphp_log_use_x_forwarded_for)) {
3410+ ip_address = sapi_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC);
3411+ if (ip_address == NULL) {
3412+ ip_address = "X-FORWARDED-FOR not set";
3413+ }
3414+ } else {
3415+ ip_address = sapi_getenv("REMOTE_ADDR", 11 TSRMLS_CC);
3416+ if (ip_address == NULL) {
3417+ ip_address = "REMOTE_ADDR not set";
3418+ }
3419+ }
3420+
3421+
3422+ va_start(ap, fmt);
3423+ ap_php_vsnprintf(error, sizeof(error), fmt, ap);
3424+ va_end(ap);
3425+ while (error[i]) {
3426+ if (error[i] < 32) error[i] = '.';
3427+ i++;
3428+ }
3429+
3430+ if (zend_is_executing(TSRMLS_C)) {
3431+ lineno = zend_get_executed_lineno(TSRMLS_C);
3432+ fname = zend_get_executed_filename(TSRMLS_C);
3433+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s', line %u)", error, ip_address, fname, lineno);
3434+ } else {
3435+ fname = sapi_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC);
3436+ if (fname==NULL) {
3437+ fname = "unknown";
3438+ }
3439+ ap_php_snprintf(buf, sizeof(buf), "ALERT - %s (attacker '%s', file '%s')", error, ip_address, fname);
3440+ }
3441+
3442+ /* Syslog-Logging disabled? */
3443+ if ((EG(hphp_log_syslog) & loglevel)==0) {
3444+ goto log_sapi;
3445+ }
3446+
3447+ ap_php_snprintf(error, sizeof(error), "<%u>hphp[%u]: %s\n", EG(hphp_log_syslog_facility)|EG(hphp_log_syslog_priority),getpid(),buf);
3448+
3449+ s = socket(AF_UNIX, SOCK_DGRAM, 0);
3450+ if (s == -1) {
3451+ goto log_sapi;
3452+ }
3453+
3454+ memset(&saun, 0, sizeof(saun));
3455+ saun.sun_family = AF_UNIX;
3456+ strcpy(saun.sun_path, SYSLOG_PATH);
3457+ /*saun.sun_len = sizeof(saun);*/
3458+
3459+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3460+ if (r) {
3461+ close(s);
3462+ s = socket(AF_UNIX, SOCK_STREAM, 0);
3463+ if (s == -1) {
3464+ goto log_sapi;
3465+ }
3466+
3467+ memset(&saun, 0, sizeof(saun));
3468+ saun.sun_family = AF_UNIX;
3469+ strcpy(saun.sun_path, SYSLOG_PATH);
3470+ /*saun.sun_len = sizeof(saun);*/
3471+
3472+ r = connect(s, (struct sockaddr *)&saun, sizeof(saun));
3473+ if (r) {
3474+ close(s);
3475+ goto log_sapi;
3476+ }
3477+ }
3478+ send(s, error, strlen(error), 0);
3479+
3480+ close(s);
3481+
3482+log_sapi:
3483+ /* SAPI Logging activated? */
3484+ if ((EG(hphp_log_syslog) & loglevel)!=0) {
3485+ sapi_module.log_message(buf);
3486+ }
3487+
3488+log_script:
3489+ /* script logging activaed? */
3490+ if (((EG(hphp_log_script) & loglevel)!=0) && EG(hphp_log_scriptname)!=NULL) {
3491+ char cmd[8192], *cmdpos, *bufpos;
3492+ FILE *in;
3493+ int space;
3494+
3495+ ap_php_snprintf(cmd, sizeof(cmd), "%s %s \'", EG(hphp_log_scriptname), loglevel2string(loglevel));
3496+ space = sizeof(cmd) - strlen(cmd);
3497+ cmdpos = cmd + strlen(cmd);
3498+ bufpos = buf;
3499+ if (space <= 1) return;
3500+ while (space > 2 && *bufpos) {
3501+ if (*bufpos == '\'') {
3502+ if (space<=5) break;
3503+ *cmdpos++ = '\'';
3504+ *cmdpos++ = '\\';
3505+ *cmdpos++ = '\'';
3506+ *cmdpos++ = '\'';
3507+ bufpos++;
3508+ space-=4;
3509+ } else {
3510+ *cmdpos++ = *bufpos++;
3511+ space--;
3512+ }
3513+ }
3514+ *cmdpos++ = '\'';
3515+ *cmdpos = 0;
3516+
3517+ if ((in=VCWD_POPEN(cmd, "r"))==NULL) {
3518+ php_security_log(S_INTERNAL, "Unable to execute logging shell script: %s", EG(hphp_log_scriptname));
3519+ return;
3520+ }
3521+ /* read and forget the result */
3522+ while (1) {
3523+ int readbytes = fread(cmd, 1, sizeof(cmd), in);
3524+ if (readbytes<=0) {
3525+ break;
3526+ }
3527+ }
3528+ pclose(in);
3529+ }
3530+
3531+#endif
3532+}
3533+#endif
3534+
3535+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3536+
3537+/* will be replaced later with more compatible method */
3538+PHPAPI unsigned int php_canary()
3539+{
3540+ time_t t;
3541+ unsigned int canary;
3542+ int fd;
3543+
3544+ fd = open("/dev/urandom", 0);
3545+ if (fd != -1) {
3546+ int r = read(fd, &canary, sizeof(canary));
3547+ close(fd);
3548+ if (r == sizeof(canary)) {
3549+ return (canary);
3550+ }
3551+ }
3552+ /* not good but we never want to do this */
3553+ time(&t);
3554+ canary = *(unsigned int *)&t + getpid() << 16;
3555+ return (canary);
3556+}
3557+#endif
3558+
3559+#if HARDENING_PATCH_INC_PROTECT
3560+
3561+PHPAPI int php_is_valid_include(zval *z)
3562+{
3563+ char *filename;
3564+ int len, i;
3565+ TSRMLS_FETCH();
3566+
3567+ /* must be of type string */
3568+ if (z->type != IS_STRING || z->value.str.val == NULL) {
3569+ return (0);
3570+ }
3571+
3572+ /* short cut */
3573+ filename = z->value.str.val;
3574+ len = z->value.str.len;
3575+
3576+ /* 1. must be shorter than MAXPATHLEN */
3577+ if (len > MAXPATHLEN) {
3578+ char *fname = estrndup(filename, len);
3579+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3580+ php_security_log(S_INCLUDE, "Include filename ('%s') longer than MAXPATHLEN chars", fname);
3581+ efree(fname);
3582+ return (0);
3583+ }
3584+
3585+ /* 2. must not be cutted */
3586+ if (len != strlen(filename)) {
3587+ char *fname = estrndup(filename, len);
3588+ for (i=0; fname[i]; i++) if (fname[i] < 32) fname[i]='.';
3589+ php_security_log(S_INCLUDE, "Include filename truncated by a \\0 after '%s'", fname);
3590+ efree(fname);
3591+ return (0);
3592+ }
3593+
3594+ /* 3. must not be a URL */
3595+ if (strstr(filename, "://")) {
3596+ char *fname = estrndup(filename, len);
3597+ for (i=0; i < len; i++) if (fname[i] < 32) fname[i]='.';
3598+ php_security_log(S_INCLUDE, "Include filename ('%s') is an URL", fname);
3599+ efree(fname);
3600+ return (0);
3601+ }
3602+
3603+ /* 4. must not be an uploaded file */
3604+ if (SG(rfc1867_uploaded_files)) {
3605+ if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, len+1)) {
3606+ php_security_log(S_INCLUDE, "Include filename is an uploaded file");
3607+ return (0);
3608+ }
3609+ }
3610+
3611+ /* passed all tests */
3612+ return (1);
3613+}
3614+
3615+#endif
3616+
3617+/*
3618+ * Local variables:
3619+ * tab-width: 4
3620+ * c-basic-offset: 4
3621+ * End:
3622+ * vim600: sw=4 ts=4 fdm=marker
3623+ * vim<600: sw=4 ts=4
3624+ */
3625diff -Nura php-5.0.5/main/hardening_patch.h hardening-patch-5.0.5-0.4.2/main/hardening_patch.h
3626--- php-5.0.5/main/hardening_patch.h 1970-01-01 01:00:00.000000000 +0100
3627+++ hardening-patch-5.0.5-0.4.2/main/hardening_patch.h 2005-09-07 14:19:05.000000000 +0200
3628@@ -0,0 +1,46 @@
3629+/*
3630+ +----------------------------------------------------------------------+
3631+ | Hardening Patch for PHP |
3632+ +----------------------------------------------------------------------+
3633+ | Copyright (c) 2004-2005 Stefan Esser |
3634+ +----------------------------------------------------------------------+
3635+ | This source file is subject to version 2.02 of the PHP license, |
3636+ | that is bundled with this package in the file LICENSE, and is |
3637+ | available at through the world-wide-web at |
3638+ | http://www.php.net/license/2_02.txt. |
3639+ | If you did not receive a copy of the PHP license and are unable to |
3640+ | obtain it through the world-wide-web, please send a note to |
3641+ | license@php.net so we can mail you a copy immediately. |
3642+ +----------------------------------------------------------------------+
3643+ | Author: Stefan Esser <sesser@hardened-php.net> |
3644+ +----------------------------------------------------------------------+
3645+ */
3646+
3647+#ifndef HARDENING_PATCH_H
3648+#define HARDENING_PATCH_H
3649+
3650+#include "zend.h"
3651+
3652+#if HARDENING_PATCH
3653+PHPAPI void php_security_log(int loglevel, char *fmt, ...);
3654+PHPAPI void hardened_startup();
3655+#define HARDENING_PATCH_VERSION "0.4.2"
3656+
3657+#endif
3658+
3659+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
3660+PHPAPI unsigned int php_canary();
3661+#endif
3662+
3663+#if HARDENING_PATCH_INC_PROTECT
3664+PHPAPI int php_is_valid_include(zval *z);
3665+#endif
3666+
3667+#endif /* HARDENING_PATCH_H */
3668+
3669+/*
3670+ * Local variables:
3671+ * tab-width: 4
3672+ * c-basic-offset: 4
3673+ * End:
3674+ */
3675diff -Nura php-5.0.5/main/hardening_patch.m4 hardening-patch-5.0.5-0.4.2/main/hardening_patch.m4
3676--- php-5.0.5/main/hardening_patch.m4 1970-01-01 01:00:00.000000000 +0100
3677+++ hardening-patch-5.0.5-0.4.2/main/hardening_patch.m4 2005-09-07 13:49:17.000000000 +0200
3678@@ -0,0 +1,95 @@
3679+dnl
3680+dnl $Id: hardening_patch.m4,v 1.1 2004/11/14 13:24:24 ionic Exp $
3681+dnl
3682+dnl This file contains Hardening Patch for PHP specific autoconf functions.
3683+dnl
3684+
3685+AC_ARG_ENABLE(hardening-patch-mm-protect,
3686+[ --disable-hardening-patch-mm-protect Disable the Memory Manager protection.],[
3687+ DO_HARDENING_PATCH_MM_PROTECT=$enableval
3688+],[
3689+ DO_HARDENING_PATCH_MM_PROTECT=yes
3690+])
3691+
3692+AC_ARG_ENABLE(hardening-patch-ll-protect,
3693+[ --disable-hardening-patch-ll-protect Disable the Linked List protection.],[
3694+ DO_HARDENING_PATCH_LL_PROTECT=$enableval
3695+],[
3696+ DO_HARDENING_PATCH_LL_PROTECT=yes
3697+])
3698+
3699+AC_ARG_ENABLE(hardening-patch-inc-protect,
3700+[ --disable-hardening-patch-inc-protect Disable include/require protection.],[
3701+ DO_HARDENING_PATCH_INC_PROTECT=$enableval
3702+],[
3703+ DO_HARDENING_PATCH_INC_PROTECT=yes
3704+])
3705+
3706+AC_ARG_ENABLE(hardening-patch-fmt-protect,
3707+[ --disable-hardening-patch-fmt-protect Disable format string protection.],[
3708+ DO_HARDENING_PATCH_FMT_PROTECT=$enableval
3709+],[
3710+ DO_HARDENING_PATCH_FMT_PROTECT=yes
3711+])
3712+
3713+AC_ARG_ENABLE(hardening-patch-hash-protect,
3714+[ --disable-hardening-patch-hash-protect Disable HashTable destructor protection.],[
3715+ DO_HARDENING_PATCH_HASH_PROTECT=$enableval
3716+],[
3717+ DO_HARDENING_PATCH_HASH_PROTECT=yes
3718+])
3719+
3720+AC_MSG_CHECKING(whether to protect the Zend Memory Manager)
3721+AC_MSG_RESULT($DO_HARDENING_PATCH_MM_PROTECT)
3722+
3723+AC_MSG_CHECKING(whether to protect the Zend Linked Lists)
3724+AC_MSG_RESULT($DO_HARDENING_PATCH_LL_PROTECT)
3725+
3726+AC_MSG_CHECKING(whether to protect include/require statements)
3727+AC_MSG_RESULT($DO_HARDENING_PATCH_INC_PROTECT)
3728+
3729+AC_MSG_CHECKING(whether to protect PHP Format String functions)
3730+AC_MSG_RESULT($DO_HARDENING_PATCH_FMT_PROTECT)
3731+
3732+AC_MSG_CHECKING(whether to protect the destructor of Zend HashTables)
3733+AC_MSG_RESULT($DO_HARDENING_PATCH_HASH_PROTECT)
3734+
3735+
3736+AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3737+
3738+
3739+if test "$DO_HARDENING_PATCH_MM_PROTECT" = "yes"; then
3740+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3741+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 1, [Memory Manager Protection])
3742+else
3743+ AC_DEFINE(HARDENING_PATCH_MM_PROTECT, 0, [Memory Manager Protection])
3744+fi
3745+
3746+if test "$DO_HARDENING_PATCH_LL_PROTECT" = "yes"; then
3747+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3748+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 1, [Linked List Protection])
3749+else
3750+ AC_DEFINE(HARDENING_PATCH_LL_PROTECT, 0, [Linked List Protection])
3751+fi
3752+
3753+if test "$DO_HARDENING_PATCH_INC_PROTECT" = "yes"; then
3754+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3755+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 1, [Include/Require Protection])
3756+else
3757+ AC_DEFINE(HARDENING_PATCH_INC_PROTECT, 0, [Include/Require Protection])
3758+fi
3759+
3760+if test "$DO_HARDENING_PATCH_FMT_PROTECT" = "yes"; then
3761+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3762+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 1, [Fmt String Protection])
3763+else
3764+ AC_DEFINE(HARDENING_PATCH_FMT_PROTECT, 0, [Fmt String Protection])
3765+fi
3766+
3767+if test "$DO_HARDENING_PATCH_HASH_PROTECT" = "yes"; then
3768+dnl AC_DEFINE(HARDENING_PATCH, 1, [Hardening Patch])
3769+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 1, [HashTable DTOR Protection])
3770+else
3771+ AC_DEFINE(HARDENING_PATCH_HASH_PROTECT, 0, [HashTable DTOR Protection])
3772+fi
3773+
3774diff -Nura php-5.0.5/main/main.c hardening-patch-5.0.5-0.4.2/main/main.c
3775--- php-5.0.5/main/main.c 2005-08-16 20:11:34.000000000 +0200
3776+++ hardening-patch-5.0.5-0.4.2/main/main.c 2005-09-07 13:49:17.000000000 +0200
3777@@ -85,6 +85,10 @@
3778
3779 #include "SAPI.h"
3780 #include "rfc1867.h"
3781+#if HARDENING_PATCH
3782+#include "hardened_globals.h"
3783+#endif
3784+
3785 /* }}} */
3786
3787 #ifndef ZTS
3788@@ -109,10 +113,33 @@
3789 */
3790 static PHP_INI_MH(OnChangeMemoryLimit)
3791 {
3792+#if HARDENING_PATCH
3793+ long orig_memory_limit;
3794+
3795+ if (entry->modified) {
3796+ orig_memory_limit = zend_atoi(entry->orig_value, entry->orig_value_length);
3797+ } else {
3798+ orig_memory_limit = 1<<30;
3799+ }
3800+ if (orig_memory_limit < 0 || orig_memory_limit > (1<<30)) {
3801+ orig_memory_limit = 1<<30;
3802+ }
3803+#endif
3804 if (new_value) {
3805 PG(memory_limit) = zend_atoi(new_value, new_value_length);
3806+#if HARDENING_PATCH
3807+ if (PG(memory_limit) > orig_memory_limit) {
3808+ PG(memory_limit) = orig_memory_limit;
3809+ php_security_log(S_MISC, "script tried to increase memory_limit above allowed value");
3810+ return FAILURE;
3811+ }
3812+#endif
3813 } else {
3814+#if HARDENING_PATCH
3815+ PG(memory_limit) = orig_memory_limit;
3816+#else
3817 PG(memory_limit) = 1<<30; /* effectively, no limit */
3818+#endif
3819 }
3820 return zend_set_memory_limit(PG(memory_limit));
3821 }
3822@@ -1322,6 +1349,10 @@
3823 tsrm_ls = ts_resource(0);
3824 #endif
3825
3826+#if HARDENING_PATCH
3827+ hardened_startup();
3828+#endif
3829+
3830 module_shutdown = 0;
3831 module_startup = 1;
3832 sapi_initialize_empty_request(TSRMLS_C);
3833@@ -1335,6 +1366,12 @@
3834
3835 php_output_startup();
3836
3837+#if HARDENING_PATCH_INC_PROTECT
3838+ zuf.is_valid_include = php_is_valid_include;
3839+#endif
3840+#if HARDENING_PATCH
3841+ zuf.security_log_function = php_security_log;
3842+#endif
3843 zuf.error_function = php_error_cb;
3844 zuf.printf_function = php_printf;
3845 zuf.write_function = php_body_write_wrapper;
3846@@ -1438,6 +1475,10 @@
3847 REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, sizeof(PHP_CONFIG_FILE_PATH)-1, CONST_PERSISTENT | CONST_CS);
3848 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);
3849 REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
3850+#if HARDENING_PATCH
3851+ REGISTER_MAIN_LONG_CONSTANT("HARDENING_PATCH", 1, CONST_PERSISTENT | CONST_CS);
3852+ REGISTER_MAIN_STRINGL_CONSTANT("HARDENING_PATCH_VERSION", HARDENING_PATCH_VERSION, sizeof(HARDENING_PATCH_VERSION)-1, CONST_PERSISTENT | CONST_CS);
3853+#endif
3854 REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
3855 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS);
3856 REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);
3857diff -Nura php-5.0.5/main/php_config.h.in hardening-patch-5.0.5-0.4.2/main/php_config.h.in
3858--- php-5.0.5/main/php_config.h.in 2005-09-05 13:16:27.000000000 +0200
3859+++ hardening-patch-5.0.5-0.4.2/main/php_config.h.in 2005-09-07 13:49:17.000000000 +0200
3860@@ -752,6 +752,39 @@
3861 /* Enabling BIND8 compatibility for Panther */
3862 #undef BIND_8_COMPAT
3863
3864+/* Hardening-Patch for PHP */
3865+#undef HARDENING_PATCH
3866+
3867+/* Memory Manager Protection */
3868+#undef HARDENING_PATCH_MM_PROTECT
3869+
3870+/* Memory Manager Protection */
3871+#undef HARDENING_PATCH_MM_PROTECT
3872+
3873+/* Linked List Protection */
3874+#undef HARDENING_PATCH_LL_PROTECT
3875+
3876+/* Linked List Protection */
3877+#undef HARDENING_PATCH_LL_PROTECT
3878+
3879+/* Include/Require Protection */
3880+#undef HARDENING_PATCH_INC_PROTECT
3881+
3882+/* Include/Require Protection */
3883+#undef HARDENING_PATCH_INC_PROTECT
3884+
3885+/* Fmt String Protection */
3886+#undef HARDENING_PATCH_FMT_PROTECT
3887+
3888+/* Fmt String Protection */
3889+#undef HARDENING_PATCH_FMT_PROTECT
3890+
3891+/* HashTable DTOR Protection */
3892+#undef HARDENING_PATCH_HASH_PROTECT
3893+
3894+/* HashTable DTOR Protection */
3895+#undef HARDENING_PATCH_HASH_PROTECT
3896+
3897 /* Whether you have AOLserver */
3898 #undef HAVE_AOLSERVER
3899
3900@@ -1083,6 +1116,12 @@
3901 /* Define if you have the getaddrinfo function */
3902 #undef HAVE_GETADDRINFO
3903
3904+/* Whether realpath is broken */
3905+#undef PHP_BROKEN_REALPATH
3906+
3907+/* Whether realpath is broken */
3908+#undef PHP_BROKEN_REALPATH
3909+
3910 /* Whether system headers declare timezone */
3911 #undef HAVE_DECLARED_TIMEZONE
3912
3913diff -Nura php-5.0.5/main/php.h hardening-patch-5.0.5-0.4.2/main/php.h
3914--- php-5.0.5/main/php.h 2005-06-29 08:41:15.000000000 +0200
3915+++ hardening-patch-5.0.5-0.4.2/main/php.h 2005-09-07 13:49:17.000000000 +0200
3916@@ -35,11 +35,19 @@
3917 #include "zend_qsort.h"
3918 #include "php_compat.h"
3919
3920+
3921 #include "zend_API.h"
3922
3923 #undef sprintf
3924 #define sprintf php_sprintf
3925
3926+#if HARDENING_PATCH
3927+#if HAVE_REALPATH
3928+#undef realpath
3929+#define realpath php_realpath
3930+#endif
3931+#endif
3932+
3933 /* PHP's DEBUG value must match Zend's ZEND_DEBUG value */
3934 #undef PHP_DEBUG
3935 #define PHP_DEBUG ZEND_DEBUG
3936@@ -330,6 +338,7 @@
3937 #define PHP_FUNCTION ZEND_FUNCTION
3938 #define PHP_METHOD ZEND_METHOD
3939
3940+#define PHP_STATIC_FE ZEND_STATIC_FE
3941 #define PHP_NAMED_FE ZEND_NAMED_FE
3942 #define PHP_FE ZEND_FE
3943 #define PHP_FALIAS ZEND_FALIAS
3944@@ -435,6 +444,10 @@
3945 #endif
3946 #endif /* !XtOffsetOf */
3947
3948+#if HARDENING_PATCH
3949+#include "hardening_patch.h"
3950+#endif
3951+
3952 #endif
3953
3954 /*
3955diff -Nura php-5.0.5/main/php_variables.c hardening-patch-5.0.5-0.4.2/main/php_variables.c
3956--- php-5.0.5/main/php_variables.c 2005-09-01 21:15:51.000000000 +0200
3957+++ hardening-patch-5.0.5-0.4.2/main/php_variables.c 2005-09-07 13:49:17.000000000 +0200
3958@@ -514,7 +514,7 @@
3959 */
3960 static inline void php_register_server_variables(TSRMLS_D)
3961 {
3962- zval *array_ptr=NULL;
3963+ zval *array_ptr=NULL, *vptr;
3964 /* turn off magic_quotes while importing server variables */
3965 int magic_quotes_gpc = PG(magic_quotes_gpc);
3966
3967@@ -530,6 +530,16 @@
3968 /* Server variables */
3969 if (sapi_module.register_server_variables) {
3970 sapi_module.register_server_variables(array_ptr TSRMLS_CC);
3971+ if (zend_hash_find(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"), (void **)&vptr)==SUCCESS) {
3972+ char *str;
3973+ if (vptr->type != IS_STRING) {
3974+ str = "Array";
3975+ } else {
3976+ str = vptr->value.str.val;
3977+ }
3978+ php_security_log(S_VARS, "Attacker tried to overwrite HTTP_RAW_POST_DATA with '%s' through a HTTP header", str);
3979+ zend_hash_del(array_ptr->value.ht, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA"));
3980+ }
3981 }
3982
3983 /* PHP Authentication support */
3984diff -Nura php-5.0.5/main/rfc1867.c hardening-patch-5.0.5-0.4.2/main/rfc1867.c
3985--- php-5.0.5/main/rfc1867.c 2005-07-13 22:51:12.000000000 +0200
3986+++ hardening-patch-5.0.5-0.4.2/main/rfc1867.c 2005-09-07 14:14:13.000000000 +0200
3987@@ -132,6 +132,7 @@
3988 #define UPLOAD_ERROR_D 4 /* No file uploaded */
3989 #define UPLOAD_ERROR_E 6 /* Missing /tmp or similar directory */
3990 #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */
3991+#define UPLOAD_ERROR_X 32 /* Filter forbids fileupload */
3992
3993 void php_rfc1867_register_constants(TSRMLS_D)
3994 {
3995@@ -142,6 +143,7 @@
3996 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_FILE", UPLOAD_ERROR_D, CONST_CS | CONST_PERSISTENT);
3997 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_NO_TMP_DIR", UPLOAD_ERROR_E, CONST_CS | CONST_PERSISTENT);
3998 REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_CANT_WRITE", UPLOAD_ERROR_F, CONST_CS | CONST_PERSISTENT);
3999+ REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_FILTER", UPLOAD_ERROR_X, CONST_CS | CONST_PERSISTENT);
4000 }
4001
4002 static void normalize_protected_variable(char *varname TSRMLS_DC)
4003@@ -854,6 +856,7 @@
4004 char buff[FILLUNIT];
4005 char *cd=NULL,*param=NULL,*filename=NULL, *tmp=NULL;
4006 int blen=0, wlen=0;
4007+ unsigned long offset;
4008
4009 zend_llist_clean(&header);
4010
4011@@ -994,6 +997,11 @@
4012 cancel_upload = UPLOAD_ERROR_D;
4013 }
4014
4015+ if (sapi_module.pre_upload_filter && sapi_module.pre_upload_filter(param, filename TSRMLS_CC)==FAILURE) {
4016+ cancel_upload = UPLOAD_ERROR_X;
4017+ }
4018+
4019+ offset = 0;
4020 end = 0;
4021 while (!cancel_upload && (blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC)))
4022 {
4023@@ -1008,6 +1016,10 @@
4024 #endif
4025 cancel_upload = UPLOAD_ERROR_B;
4026 } else if (blen > 0) {
4027+ if (sapi_module.upload_content_filter && sapi_module.upload_content_filter(offset, buff, blen, &blen TSRMLS_CC)==FAILURE) {
4028+ cancel_upload = UPLOAD_ERROR_X;
4029+ }
4030+
4031 wlen = write(fd, buff, blen);
4032
4033 if (wlen < blen) {
4034@@ -1036,6 +1048,10 @@
4035 }
4036 #endif
4037
4038+ if (!cancel_upload && sapi_module.post_upload_filter && sapi_module.post_upload_filter(temp_filename TSRMLS_CC)==FAILURE) {
4039+ cancel_upload = UPLOAD_ERROR_X;
4040+ }
4041+
4042 if (cancel_upload) {
4043 if (temp_filename) {
4044 if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */
4045diff -Nura php-5.0.5/main/SAPI.c hardening-patch-5.0.5-0.4.2/main/SAPI.c
4046--- php-5.0.5/main/SAPI.c 2005-02-22 15:46:15.000000000 +0100
4047+++ hardening-patch-5.0.5-0.4.2/main/SAPI.c 2005-09-07 13:49:17.000000000 +0200
4048@@ -821,6 +821,30 @@
4049 zend_hash_del(&known_post_content_types, post_entry->content_type, post_entry->content_type_len+1);
4050 }
4051
4052+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))
4053+{
4054+ sapi_module.input_filter = input_filter;
4055+ return SUCCESS;
4056+}
4057+
4058+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC))
4059+{
4060+ sapi_module.pre_upload_filter = pre_upload_filter;
4061+ return SUCCESS;
4062+}
4063+
4064+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))
4065+{
4066+ sapi_module.upload_content_filter = upload_content_filter;
4067+ return SUCCESS;
4068+}
4069+
4070+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC))
4071+{
4072+ sapi_module.post_upload_filter = post_upload_filter;
4073+ return SUCCESS;
4074+}
4075+
4076
4077 SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D))
4078 {
4079@@ -835,11 +859,6 @@
4080 return SUCCESS;
4081 }
4082
4083-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))
4084-{
4085- sapi_module.input_filter = input_filter;
4086- return SUCCESS;
4087-}
4088
4089 SAPI_API int sapi_flush(TSRMLS_D)
4090 {
4091diff -Nura php-5.0.5/main/SAPI.h hardening-patch-5.0.5-0.4.2/main/SAPI.h
4092--- php-5.0.5/main/SAPI.h 2004-01-08 18:33:04.000000000 +0100
4093+++ hardening-patch-5.0.5-0.4.2/main/SAPI.h 2005-09-07 13:49:17.000000000 +0200
4094@@ -103,9 +103,10 @@
4095 char *current_user;
4096 int current_user_length;
4097
4098- /* this is necessary for CLI module */
4099- int argc;
4100- char **argv;
4101+ /* this is necessary for CLI module */
4102+ int argc;
4103+ char **argv;
4104+
4105 } sapi_request_info;
4106
4107
4108@@ -183,6 +184,10 @@
4109 SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC));
4110 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));
4111
4112+SAPI_API int sapi_register_pre_upload_filter(unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC));
4113+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));
4114+SAPI_API int sapi_register_post_upload_filter(unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC));
4115+
4116 SAPI_API int sapi_flush(TSRMLS_D);
4117 SAPI_API struct stat *sapi_get_stat(TSRMLS_D);
4118 SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC);
4119@@ -245,6 +250,10 @@
4120 int (*get_target_gid)(gid_t * TSRMLS_DC);
4121
4122 unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC);
4123+
4124+ unsigned int (*pre_upload_filter)(char *varname, char *filename TSRMLS_DC);
4125+ unsigned int (*upload_content_filter)(unsigned long offset, char *buffer, unsigned int buffer_len, unsigned int *new_buffer_len TSRMLS_DC);
4126+ unsigned int (*post_upload_filter)(char *tmpfilename TSRMLS_DC);
4127
4128 void (*ini_defaults)(HashTable *configuration_hash);
4129 int phpinfo_as_text;
4130@@ -270,7 +279,11 @@
4131
4132 #define SAPI_DEFAULT_MIMETYPE "text/html"
4133 #define SAPI_DEFAULT_CHARSET ""
4134+#if HARDENING_PATCH
4135+#define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION " with Hardening-Patch"
4136+#else
4137 #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION
4138+#endif
4139
4140 #define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D)
4141 #define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC)
4142@@ -278,6 +291,10 @@
4143 #define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC)
4144 #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)
4145
4146+#define SAPI_PRE_UPLOAD_FILTER_FUNC(pre_upload_filter) unsigned int pre_upload_filter(char *varname, char *filename TSRMLS_DC)
4147+#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)
4148+#define SAPI_POST_UPLOAD_FILTER_FUNC(post_upload_filter) unsigned int post_upload_filter(char *tmpfilename TSRMLS_DC)
4149+
4150 BEGIN_EXTERN_C()
4151 SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data);
4152 SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader);
4153diff -Nura php-5.0.5/main/snprintf.c hardening-patch-5.0.5-0.4.2/main/snprintf.c
4154--- php-5.0.5/main/snprintf.c 2004-11-16 00:14:40.000000000 +0100
4155+++ hardening-patch-5.0.5-0.4.2/main/snprintf.c 2005-09-07 13:49:17.000000000 +0200
4156@@ -1013,7 +1013,11 @@
4157
4158
4159 case 'n':
4160+#if HARDENING_PATCH_FMT_PROTECT
4161+ php_security_log(S_MISC, "'n' specifier within format string");
4162+#else
4163 *(va_arg(ap, int *)) = cc;
4164+#endif
4165 break;
4166
4167 /*
4168diff -Nura php-5.0.5/main/spprintf.c hardening-patch-5.0.5-0.4.2/main/spprintf.c
4169--- php-5.0.5/main/spprintf.c 2004-04-16 01:04:49.000000000 +0200
4170+++ hardening-patch-5.0.5-0.4.2/main/spprintf.c 2005-09-07 13:49:17.000000000 +0200
4171@@ -630,7 +630,11 @@
4172
4173
4174 case 'n':
4175+#if HARDENING_PATCH_FMT_PROTECT
4176+ php_security_log(S_MISC, "'n' specifier within format string");
4177+#else
4178 *(va_arg(ap, int *)) = xbuf->len;
4179+#endif
4180 break;
4181
4182 /*
4183diff -Nura php-5.0.5/php.ini-dist hardening-patch-5.0.5-0.4.2/php.ini-dist
4184--- php-5.0.5/php.ini-dist 2005-05-05 14:33:56.000000000 +0200
4185+++ hardening-patch-5.0.5-0.4.2/php.ini-dist 2005-09-07 13:49:17.000000000 +0200
4186@@ -1197,6 +1197,185 @@
4187 ; instead of original one.
4188 soap.wsdl_cache_ttl=86400
4189
4190+[hardening-patch]
4191+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4192+; Hardening-Patch's logging ;
4193+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4194+
4195+;
4196+; hphp.log.syslog - Configures level for alerts reported through syslog
4197+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4198+; hphp.log.script - Configures level for alerts reported through external script
4199+;
4200+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4201+; Or each number up to get desired Hardening-Patch's reporting level
4202+;
4203+; S_ALL - All alerts
4204+; S_MEMORY - All canary violations and the safe unlink protection use this class
4205+; S_VARS - All variable filters trigger this class
4206+; S_FILES - All violation of uploaded files filter use this class
4207+; S_INCLUDE - The protection against malicious include filenames use this class
4208+; S_SQL - Failed SQL queries in MySQL are logged with this class
4209+; S_EXECUTOR - The execution depth protection uses this logging class
4210+; S_MISC - All other log messages (f.e. format string protection) use this class
4211+;
4212+; Example:
4213+;
4214+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4215+; memory alerts through syslog and SQL+Include alerts fo the script
4216+;
4217+;hphp.log.syslog = S_MEMORY
4218+;hphp.log.sapi = S_ALL & ~S_MEMORY
4219+;hphp.log.script = S_INCLUDE | S_SQL
4220+;
4221+; Syslog logging:
4222+;
4223+; - Facility configuration: one of the following facilities
4224+;
4225+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4226+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4227+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4228+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4229+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4230+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4231+; LOG_PERROR
4232+;
4233+; - Priority configuration: one of the followinf priorities
4234+;
4235+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4236+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4237+;
4238+hphp.log.syslog.priority = LOG_ALERT
4239+hphp.log.syslog.facility = LOG_USER
4240+;
4241+; Script logging:
4242+;
4243+;hphp.log.script.name = /home/hphp/log_script
4244+;
4245+; Alert configuration:
4246+;
4247+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4248+;
4249+;hphp.log.use-x-forwarded-for = On
4250+;
4251+
4252+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4253+; Hardening-Patch's Executor options ;
4254+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4255+
4256+; Execution depth limit
4257+;hphp.executor.max_depth = 8000
4258+
4259+; White-/blacklist for function calls during normal execution
4260+;hphp.executor.func.whitelist = ord,chr
4261+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4262+
4263+; White-/blacklist for function calls during eval() execution
4264+;hphp.executor.eval.whitelist = ord,chr
4265+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4266+
4267+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4268+; Hardening-Patch's REQUEST variable filters ;
4269+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4270+
4271+; Limits the number of REQUEST variables
4272+hphp.request.max_vars = 200
4273+
4274+; Limits the length of variable names (without indices)
4275+hphp.request.max_varname_length = 64
4276+
4277+; Limits the length of complete variable names (with indices)
4278+hphp.request.max_totalname_length = 256
4279+
4280+; Limits the length of array indices
4281+hphp.request.max_array_index_length = 64
4282+
4283+; Limits the depth of arrays
4284+hphp.request.max_array_depth = 100
4285+
4286+; Limits the length of variable values
4287+hphp.request.max_value_length = 65000
4288+
4289+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4290+; Hardening-Patch's COOKIE variable filters ;
4291+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4292+
4293+; Limits the number of COOKIE variables
4294+hphp.cookie.max_vars = 100
4295+
4296+; Limits the length of variable names (without indices)
4297+hphp.cookie.max_name_length = 64
4298+
4299+; Limits the length of complete variable names (with indices)
4300+hphp.cookie.max_totalname_length = 256
4301+
4302+; Limits the length of array indices
4303+hphp.cookie.max_array_index_length = 64
4304+
4305+; Limits the depth of arrays
4306+hphp.cookie.max_array_depth = 100
4307+
4308+; Limits the length of variable values
4309+hphp.cookie.max_value_length = 10000
4310+
4311+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4312+; Hardening-Patch's GET variable filters ;
4313+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4314+
4315+; Limits the number of COOKIE variables
4316+hphp.get.max_vars = 100
4317+
4318+; Limits the length of variable names (without indices)
4319+hphp.get.max_name_length = 64
4320+
4321+; Limits the length of complete variable names (with indices)
4322+hphp.get.max_totalname_length = 256
4323+
4324+; Limits the length of array indices
4325+hphp.get.max_array_index_length = 64
4326+
4327+; Limits the depth of arrays
4328+hphp.get.max_array_depth = 50
4329+
4330+; Limits the length of variable values
4331+hphp.get.max_value_length = 512
4332+
4333+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4334+; Hardening-Patch's POST variable filters ;
4335+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4336+
4337+; Limits the number of POST variables
4338+hphp.post.max_vars = 200
4339+
4340+; Limits the length of variable names (without indices)
4341+hphp.post.max_name_length = 64
4342+
4343+; Limits the length of complete variable names (with indices)
4344+hphp.post.max_totalname_length = 256
4345+
4346+; Limits the length of array indices
4347+hphp.post.max_array_index_length = 64
4348+
4349+; Limits the depth of arrays
4350+hphp.post.max_array_depth = 100
4351+
4352+; Limits the length of variable values
4353+hphp.post.max_value_length = 65000
4354+
4355+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4356+; Hardening-Patch's fileupload variable filters ;
4357+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4358+
4359+; Limits the number of uploadable files
4360+hphp.upload.max_uploads = 25
4361+
4362+; Filter out the upload of ELF executables
4363+hphp.upload.disallow_elf_files = On
4364+
4365+; External filterscript for upload verification
4366+;hphp.upload.verification_script = /home/hphp/verify_script
4367+
4368+
4369 ; Local Variables:
4370 ; tab-width: 4
4371 ; End:
4372diff -Nura php-5.0.5/php.ini-recommended hardening-patch-5.0.5-0.4.2/php.ini-recommended
4373--- php-5.0.5/php.ini-recommended 2005-05-05 14:33:56.000000000 +0200
4374+++ hardening-patch-5.0.5-0.4.2/php.ini-recommended 2005-09-07 13:49:17.000000000 +0200
4375@@ -1255,6 +1255,184 @@
4376 ; instead of original one.
4377 soap.wsdl_cache_ttl=86400
4378
4379+[hardening-patch]
4380+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4381+; Hardening-Patch's logging ;
4382+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4383+
4384+;
4385+; hphp.log.syslog - Configures level for alerts reported through syslog
4386+; hphp.log.sapi - Configures level for alerts reported through SAPI errorlog
4387+; hphp.log.script - Configures level for alerts reported through external script
4388+;
4389+; hphp.log.syslog, hphp.log.sapi, hphp.log.script are bit-fields.
4390+; Or each number up to get desired Hardening-Patch's reporting level
4391+;
4392+; S_ALL - All alerts
4393+; S_MEMORY - All canary violations and the safe unlink protection use this class
4394+; S_VARS - All variable filters trigger this class
4395+; S_FILES - All violation of uploaded files filter use this class
4396+; S_INCLUDE - The protection against malicious include filenames use this class
4397+; S_SQL - Failed SQL queries in MySQL are logged with this class
4398+; S_EXECUTOR - The execution depth protection uses this logging class
4399+; S_MISC - All other log messages (f.e. format string protection) use this class
4400+;
4401+; Example:
4402+;
4403+; - Report all alerts (except memory alerts) to the SAPI errorlog,
4404+; memory alerts through syslog and SQL+Include alerts fo the script
4405+;
4406+;hphp.log.syslog = S_MEMORY
4407+;hphp.log.sapi = S_ALL & ~S_MEMORY
4408+;hphp.log.script = S_INCLUDE | S_SQL
4409+;
4410+; Syslog logging:
4411+;
4412+; - Facility configuration: one of the following facilities
4413+;
4414+; LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON
4415+; LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS
4416+; LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0
4417+; LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4
4418+; LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, LOG_PID
4419+; LOG_CONS, LOG_ODELAY, LOG_NDELAY, LOG_NOWAIT
4420+; LOG_PERROR
4421+;
4422+; - Priority configuration: one of the followinf priorities
4423+;
4424+; LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING
4425+; LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
4426+;
4427+hphp.log.syslog.priority = LOG_ALERT
4428+hphp.log.syslog.facility = LOG_USER
4429+;
4430+; Script logging:
4431+;
4432+;hphp.log.script.name = /home/hphp/log_script
4433+;
4434+; Alert configuration:
4435+;
4436+; - Logged IP addresses from X-Forwarded-For instead of REMOTE_ADDR
4437+;
4438+;hphp.log.use-x-forwarded-for = On
4439+;
4440+
4441+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4442+; Hardening-Patch's Executor options ;
4443+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4444+
4445+; Execution depth limit
4446+;hphp.executor.max_depth = 8000
4447+
4448+; White-/blacklist for function calls during normal execution
4449+;hphp.executor.func.whitelist = ord,chr
4450+;hphp.executor.func.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4451+
4452+; White-/blacklist for function calls during eval() execution
4453+;hphp.executor.eval.whitelist = ord,chr
4454+;hphp.executor.eval.blacklist = system,shell_exec,popen,proc_open,exec,passthru
4455+
4456+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4457+; Hardening-Patch's REQUEST variable filters ;
4458+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4459+
4460+; Limits the number of REQUEST variables
4461+hphp.request.max_vars = 200
4462+
4463+; Limits the length of variable names (without indices)
4464+hphp.request.max_varname_length = 64
4465+
4466+; Limits the length of complete variable names (with indices)
4467+hphp.request.max_totalname_length = 256
4468+
4469+; Limits the length of array indices
4470+hphp.request.max_array_index_length = 64
4471+
4472+; Limits the depth of arrays
4473+hphp.request.max_array_depth = 100
4474+
4475+; Limits the length of variable values
4476+hphp.request.max_value_length = 65000
4477+
4478+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4479+; Hardening-Patch's COOKIE variable filters ;
4480+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4481+
4482+; Limits the number of COOKIE variables
4483+hphp.cookie.max_vars = 100
4484+
4485+; Limits the length of variable names (without indices)
4486+hphp.cookie.max_name_length = 64
4487+
4488+; Limits the length of complete variable names (with indices)
4489+hphp.cookie.max_totalname_length = 256
4490+
4491+; Limits the length of array indices
4492+hphp.cookie.max_array_index_length = 64
4493+
4494+; Limits the depth of arrays
4495+hphp.cookie.max_array_depth = 100
4496+
4497+; Limits the length of variable values
4498+hphp.cookie.max_value_length = 10000
4499+
4500+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4501+; Hardening-Patch's GET variable filters ;
4502+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4503+
4504+; Limits the number of COOKIE variables
4505+hphp.get.max_vars = 100
4506+
4507+; Limits the length of variable names (without indices)
4508+hphp.get.max_name_length = 64
4509+
4510+; Limits the length of complete variable names (with indices)
4511+hphp.get.max_totalname_length = 256
4512+
4513+; Limits the length of array indices
4514+hphp.get.max_array_index_length = 64
4515+
4516+; Limits the depth of arrays
4517+hphp.get.max_array_depth = 50
4518+
4519+; Limits the length of variable values
4520+hphp.get.max_value_length = 512
4521+
4522+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4523+; Hardening-Patch's POST variable filters ;
4524+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4525+
4526+; Limits the number of POST variables
4527+hphp.post.max_vars = 200
4528+
4529+; Limits the length of variable names (without indices)
4530+hphp.post.max_name_length = 64
4531+
4532+; Limits the length of complete variable names (with indices)
4533+hphp.post.max_totalname_length = 256
4534+
4535+; Limits the length of array indices
4536+hphp.post.max_array_index_length = 64
4537+
4538+; Limits the depth of arrays
4539+hphp.post.max_array_depth = 100
4540+
4541+; Limits the length of variable values
4542+hphp.post.max_value_length = 65000
4543+
4544+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4545+; Hardening-Patch's fileupload variable filters ;
4546+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4547+
4548+; Limits the number of uploadable files
4549+hphp.upload.max_uploads = 25
4550+
4551+; Filter out the upload of ELF executables
4552+hphp.upload.disallow_elf_files = On
4553+
4554+; External filterscript for upload verification
4555+;hphp.upload.verification_script = /home/hphp/verify_script
4556+
4557 ; Local Variables:
4558 ; tab-width: 4
4559 ; End:
4560diff -Nura php-5.0.5/sapi/apache/mod_php5.c hardening-patch-5.0.5-0.4.2/sapi/apache/mod_php5.c
4561--- php-5.0.5/sapi/apache/mod_php5.c 2005-08-01 10:12:42.000000000 +0200
4562+++ hardening-patch-5.0.5-0.4.2/sapi/apache/mod_php5.c 2005-09-07 13:49:17.000000000 +0200
4563@@ -455,7 +455,7 @@
4564 sapi_apache_get_fd,
4565 sapi_apache_force_http_10,
4566 sapi_apache_get_target_uid,
4567- sapi_apache_get_target_gid
4568+ sapi_apache_get_target_gid,
4569 };
4570 /* }}} */
4571
4572@@ -907,7 +907,11 @@
4573 {
4574 TSRMLS_FETCH();
4575 if (PG(expose_php)) {
4576+#if HARDENING_PATCH
4577+ ap_add_version_component("PHP/" PHP_VERSION " with Hardening-Patch");
4578+#else
4579 ap_add_version_component("PHP/" PHP_VERSION);
4580+#endif
4581 }
4582 }
4583 #endif
4584diff -Nura php-5.0.5/sapi/apache2filter/sapi_apache2.c hardening-patch-5.0.5-0.4.2/sapi/apache2filter/sapi_apache2.c
4585--- php-5.0.5/sapi/apache2filter/sapi_apache2.c 2005-07-16 14:30:10.000000000 +0200
4586+++ hardening-patch-5.0.5-0.4.2/sapi/apache2filter/sapi_apache2.c 2005-09-07 13:49:17.000000000 +0200
4587@@ -562,7 +562,11 @@
4588 {
4589 TSRMLS_FETCH();
4590 if (PG(expose_php)) {
4591+#if HARDENING_PATCH
4592+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
4593+#else
4594 ap_add_version_component(p, "PHP/" PHP_VERSION);
4595+#endif
4596 }
4597 }
4598
4599diff -Nura php-5.0.5/sapi/apache2handler/sapi_apache2.c hardening-patch-5.0.5-0.4.2/sapi/apache2handler/sapi_apache2.c
4600--- php-5.0.5/sapi/apache2handler/sapi_apache2.c 2005-09-02 15:51:26.000000000 +0200
4601+++ hardening-patch-5.0.5-0.4.2/sapi/apache2handler/sapi_apache2.c 2005-09-07 13:49:17.000000000 +0200
4602@@ -333,7 +333,11 @@
4603 {
4604 TSRMLS_FETCH();
4605 if (PG(expose_php)) {
4606+#if HARDENING_PATCH
4607+ ap_add_version_component(p, "PHP/" PHP_VERSION " with Hardening-Patch");
4608+#else
4609 ap_add_version_component(p, "PHP/" PHP_VERSION);
4610+#endif
4611 }
4612 }
4613
4614diff -Nura php-5.0.5/sapi/cgi/cgi_main.c hardening-patch-5.0.5-0.4.2/sapi/cgi/cgi_main.c
4615--- php-5.0.5/sapi/cgi/cgi_main.c 2005-04-28 16:24:21.000000000 +0200
4616+++ hardening-patch-5.0.5-0.4.2/sapi/cgi/cgi_main.c 2005-09-07 13:49:17.000000000 +0200
4617@@ -1419,11 +1419,19 @@
4618 SG(headers_sent) = 1;
4619 SG(request_info).no_headers = 1;
4620 }
4621+#if HARDENING_PATCH
4622+#if ZEND_DEBUG
4623+ 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());
4624+#else
4625+ 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());
4626+#endif
4627+#else
4628 #if ZEND_DEBUG
4629 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());
4630 #else
4631 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());
4632 #endif
4633+#endif
4634 php_end_ob_buffers(1 TSRMLS_CC);
4635 exit(1);
4636 break;
4637diff -Nura php-5.0.5/sapi/cli/php_cli.c hardening-patch-5.0.5-0.4.2/sapi/cli/php_cli.c
4638--- php-5.0.5/sapi/cli/php_cli.c 2005-03-22 16:09:20.000000000 +0100
4639+++ hardening-patch-5.0.5-0.4.2/sapi/cli/php_cli.c 2005-09-07 13:49:17.000000000 +0200
4640@@ -694,11 +694,19 @@
4641 if (php_request_startup(TSRMLS_C)==FAILURE) {
4642 goto err;
4643 }
4644+#if HARDENING_PATCH
4645+#if ZEND_DEBUG
4646+ 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());
4647+#else
4648+ 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());
4649+#endif
4650+#else
4651 #if ZEND_DEBUG
4652 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());
4653 #else
4654 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());
4655 #endif
4656+#endif
4657 php_end_ob_buffers(1 TSRMLS_CC);
4658 exit_status=1;
4659 goto out;
4660diff -Nura php-5.0.5/TSRM/TSRM.h hardening-patch-5.0.5-0.4.2/TSRM/TSRM.h
4661--- php-5.0.5/TSRM/TSRM.h 2005-03-11 12:12:07.000000000 +0100
4662+++ hardening-patch-5.0.5-0.4.2/TSRM/TSRM.h 2005-09-07 13:49:17.000000000 +0200
4663@@ -33,6 +33,13 @@
4664 # define TSRM_API
4665 #endif
4666
4667+#if HARDENING_PATCH
4668+# if HAVE_REALPATH
4669+# undef realpath
4670+# define realpath php_realpath
4671+# endif
4672+#endif
4673+
4674 /* Only compile multi-threading functions if we're in ZTS mode */
4675 #ifdef ZTS
4676
4677@@ -88,6 +95,7 @@
4678
4679 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
4680
4681+
4682 #ifdef __cplusplus
4683 extern "C" {
4684 #endif
4685diff -Nura php-5.0.5/TSRM/tsrm_virtual_cwd.c hardening-patch-5.0.5-0.4.2/TSRM/tsrm_virtual_cwd.c
4686--- php-5.0.5/TSRM/tsrm_virtual_cwd.c 2005-07-16 13:50:59.000000000 +0200
4687+++ hardening-patch-5.0.5-0.4.2/TSRM/tsrm_virtual_cwd.c 2005-09-07 13:49:17.000000000 +0200
4688@@ -184,6 +184,165 @@
4689 return p;
4690 }
4691
4692+#if HARDENING_PATCH
4693+CWD_API char *php_realpath(const char *path, char *resolved)
4694+{
4695+ struct stat sb;
4696+ char *p, *q, *s;
4697+ size_t left_len, resolved_len;
4698+ unsigned symlinks;
4699+ int serrno, slen;
4700+ int is_dir = 1;
4701+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
4702+
4703+ serrno = errno;
4704+ symlinks = 0;
4705+ if (path[0] == '/') {
4706+ resolved[0] = '/';
4707+ resolved[1] = '\0';
4708+ if (path[1] == '\0')
4709+ return (resolved);
4710+ resolved_len = 1;
4711+ left_len = strlcpy(left, path + 1, sizeof(left));
4712+ } else {
4713+ if (getcwd(resolved, PATH_MAX) == NULL) {
4714+ strlcpy(resolved, ".", PATH_MAX);
4715+ return (NULL);
4716+ }
4717+ resolved_len = strlen(resolved);
4718+ left_len = strlcpy(left, path, sizeof(left));
4719+ }
4720+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
4721+ errno = ENAMETOOLONG;
4722+ return (NULL);
4723+ }
4724+
4725+ /*
4726+ * Iterate over path components in `left'.
4727+ */
4728+ while (left_len != 0) {
4729+ /*
4730+ * Extract the next path component and adjust `left'
4731+ * and its length.
4732+ */
4733+ p = strchr(left, '/');
4734+ s = p ? p : left + left_len;
4735+ if (s - left >= sizeof(next_token)) {
4736+ errno = ENAMETOOLONG;
4737+ return (NULL);
4738+ }
4739+ memcpy(next_token, left, s - left);
4740+ next_token[s - left] = '\0';
4741+ left_len -= s - left;
4742+ if (p != NULL)
4743+ memmove(left, s + 1, left_len + 1);
4744+ if (resolved[resolved_len - 1] != '/') {
4745+ if (resolved_len + 1 >= PATH_MAX) {
4746+ errno = ENAMETOOLONG;
4747+ return (NULL);
4748+ }
4749+ resolved[resolved_len++] = '/';
4750+ resolved[resolved_len] = '\0';
4751+ }
4752+ if (next_token[0] == '\0')
4753+ continue;
4754+ else if (strcmp(next_token, ".") == 0)
4755+ continue;
4756+ else if (strcmp(next_token, "..") == 0) {
4757+ /*
4758+ * Strip the last path component except when we have
4759+ * single "/"
4760+ */
4761+ if (!is_dir) {
4762+ errno = ENOENT;
4763+ return (NULL);
4764+ }
4765+ if (resolved_len > 1) {
4766+ resolved[resolved_len - 1] = '\0';
4767+ q = strrchr(resolved, '/');
4768+ *q = '\0';
4769+ resolved_len = q - resolved;
4770+ }
4771+ continue;
4772+ }
4773+
4774+ /*
4775+ * Append the next path component and lstat() it. If
4776+ * lstat() fails we still can return successfully if
4777+ * there are no more path components left.
4778+ */
4779+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
4780+ if (resolved_len >= PATH_MAX) {
4781+ errno = ENAMETOOLONG;
4782+ return (NULL);
4783+ }
4784+ if (lstat(resolved, &sb) != 0) {
4785+ if (errno == ENOENT && p == NULL) {
4786+ errno = serrno;
4787+ return (resolved);
4788+ }
4789+ return (NULL);
4790+ }
4791+ if (S_ISLNK(sb.st_mode)) {
4792+ if (symlinks++ > MAXSYMLINKS) {
4793+ errno = ELOOP;
4794+ return (NULL);
4795+ }
4796+ slen = readlink(resolved, symlink, sizeof(symlink) - 1);
4797+ if (slen < 0)
4798+ return (NULL);
4799+ symlink[slen] = '\0';
4800+ if (symlink[0] == '/') {
4801+ resolved[1] = 0;
4802+ resolved_len = 1;
4803+ } else if (resolved_len > 1) {
4804+ /* Strip the last path component. */
4805+ resolved[resolved_len - 1] = '\0';
4806+ q = strrchr(resolved, '/');
4807+ *q = '\0';
4808+ resolved_len = q - resolved;
4809+ }
4810+
4811+ /*
4812+ * If there are any path components left, then
4813+ * append them to symlink. The result is placed
4814+ * in `left'.
4815+ */
4816+ if (p != NULL) {
4817+ if (symlink[slen - 1] != '/') {
4818+ if (slen + 1 >= sizeof(symlink)) {
4819+ errno = ENAMETOOLONG;
4820+ return (NULL);
4821+ }
4822+ symlink[slen] = '/';
4823+ symlink[slen + 1] = 0;
4824+ }
4825+ left_len = strlcat(symlink, left, sizeof(left));
4826+ if (left_len >= sizeof(left)) {
4827+ errno = ENAMETOOLONG;
4828+ return (NULL);
4829+ }
4830+ }
4831+ left_len = strlcpy(left, symlink, sizeof(left));
4832+ } else {
4833+ if (S_ISDIR(sb.st_mode)) {
4834+ is_dir = 1;
4835+ } else {
4836+ is_dir = 0;
4837+ }
4838+ }
4839+ }
4840+
4841+ /*
4842+ * Remove trailing slash except when the resolved pathname
4843+ * is a single "/".
4844+ */
4845+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
4846+ resolved[resolved_len - 1] = '\0';
4847+ return (resolved);
4848+}
4849+#endif
4850+
4851 CWD_API void virtual_cwd_startup(void)
4852 {
4853 char cwd[MAXPATHLEN];
4854@@ -321,8 +480,7 @@
4855 path = resolved_path;
4856 path_length = strlen(path);
4857 } else {
4858- /* disable for now
4859- return 1; */
4860+ return 1;
4861 }
4862 }
4863 } else { /* Concat current directory with relative path and then run realpath() on it */
4864@@ -348,9 +506,8 @@
4865 path = resolved_path;
4866 path_length = strlen(path);
4867 } else {
4868- /* disable for now
4869 free(tmp);
4870- return 1; */
4871+ return 1;
4872 }
4873 }
4874 free(tmp);
4875diff -Nura php-5.0.5/TSRM/tsrm_virtual_cwd.h hardening-patch-5.0.5-0.4.2/TSRM/tsrm_virtual_cwd.h
4876--- php-5.0.5/TSRM/tsrm_virtual_cwd.h 2005-07-16 13:50:59.000000000 +0200
4877+++ hardening-patch-5.0.5-0.4.2/TSRM/tsrm_virtual_cwd.h 2005-09-07 13:49:17.000000000 +0200
4878@@ -126,6 +126,22 @@
4879
4880 typedef int (*verify_path_func)(const cwd_state *);
4881
4882+#ifndef HAVE_STRLCPY
4883+CWD_API size_t php_strlcpy(char *dst, const char *src, size_t siz);
4884+#undef strlcpy
4885+#define strlcpy php_strlcpy
4886+#endif
4887+
4888+#ifndef HAVE_STRLCAT
4889+CWD_API size_t php_strlcat(char *dst, const char *src, size_t siz);
4890+#undef strlcat
4891+#define strlcat php_strlcat
4892+#endif
4893+
4894+
4895+#if HARDENING_PATCH
4896+CWD_API char *php_realpath(const char *path, char *resolved);
4897+#endif
4898 CWD_API void virtual_cwd_startup(void);
4899 CWD_API void virtual_cwd_shutdown(void);
4900 CWD_API char *virtual_getcwd_ex(size_t *length TSRMLS_DC);
4901diff -Nura php-5.0.5/Zend/zend_alloc.c hardening-patch-5.0.5-0.4.2/Zend/zend_alloc.c
4902--- php-5.0.5/Zend/zend_alloc.c 2005-08-18 17:14:23.000000000 +0200
4903+++ hardening-patch-5.0.5-0.4.2/Zend/zend_alloc.c 2005-09-07 13:49:17.000000000 +0200
4904@@ -64,6 +64,11 @@
4905 # define END_MAGIC_SIZE 0
4906 #endif
4907
4908+#if HARDENING_PATCH_MM_PROTECT
4909+# define CANARY_SIZE sizeof(unsigned int)
4910+#else
4911+# define CANARY_SIZE 0
4912+#endif
4913
4914 # if MEMORY_LIMIT
4915 # if ZEND_DEBUG
4916@@ -105,9 +110,17 @@
4917 if (p==AG(head)) { \
4918 AG(head) = p->pNext; \
4919 } else { \
4920+ if (p != p->pLast->pNext) { \
4921+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
4922+ exit(1); \
4923+ } \
4924 p->pLast->pNext = p->pNext; \
4925 } \
4926 if (p->pNext) { \
4927+ if (p != p->pNext->pLast) { \
4928+ zend_security_log(S_MEMORY, "linked list corrupt on efree() - heap corruption detected"); \
4929+ exit(1); \
4930+ } \
4931 p->pNext->pLast = p->pLast; \
4932 }
4933 #else
4934@@ -146,6 +159,12 @@
4935 DECLARE_CACHE_VARS();
4936 TSRMLS_FETCH();
4937
4938+#if HARDENING_PATCH_MM_PROTECT
4939+ if (size > LONG_MAX - sizeof(zend_mem_header) - MEM_HEADER_PADDING - END_MAGIC_SIZE - CANARY_SIZE) {
4940+ zend_security_log(S_MEMORY, "emalloc() - requested size would result in integer overflow");
4941+ exit(1);
4942+ }
4943+#endif
4944 CALCULATE_REAL_SIZE_AND_CACHE_INDEX(size);
4945
4946 #if !ZEND_DISABLE_MEMORY_CACHE
4947@@ -164,6 +183,10 @@
4948 AG(cache_stats)[CACHE_INDEX][1]++;
4949 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
4950 #endif
4951+#if HARDENING_PATCH_MM_PROTECT
4952+ p->canary = HG(canary_1);
4953+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
4954+#endif
4955 p->cached = 0;
4956 p->size = size;
4957 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
4958@@ -180,7 +203,7 @@
4959 AG(allocated_memory_peak) = AG(allocated_memory);
4960 }
4961 #endif
4962- p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE);
4963+ p = (zend_mem_header *) ZEND_DO_MALLOC(sizeof(zend_mem_header) + MEM_HEADER_PADDING + SIZE + END_MAGIC_SIZE + CANARY_SIZE);
4964 #if !ZEND_DISABLE_MEMORY_CACHE
4965 }
4966 #endif
4967@@ -212,7 +235,10 @@
4968 # endif
4969 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
4970 #endif
4971-
4972+#if HARDENING_PATCH_MM_PROTECT
4973+ p->canary = HG(canary_1);
4974+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
4975+#endif
4976 HANDLE_UNBLOCK_INTERRUPTIONS();
4977 return (void *)((char *)p + sizeof(zend_mem_header) + MEM_HEADER_PADDING);
4978 }
4979@@ -240,6 +266,10 @@
4980 }
4981 }
4982
4983+
4984+#if HARDENING_PATCH
4985+ zend_security_log(S_MEMORY, "Possible integer overflow catched by safe_emalloc()");
4986+#endif
4987 zend_error(E_ERROR, "Possible integer overflow in memory allocation (%zd * %zd + %zd)", nmemb, size, offset);
4988 return 0;
4989 }
4990@@ -248,9 +278,25 @@
4991
4992 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
4993 {
4994+#if HARDENING_PATCH_MM_PROTECT
4995+ unsigned int canary_2;
4996+#endif
4997 zend_mem_header *p = (zend_mem_header *) ((char *)ptr - sizeof(zend_mem_header) - MEM_HEADER_PADDING);
4998 DECLARE_CACHE_VARS();
4999 TSRMLS_FETCH();
5000+
5001+#if HARDENING_PATCH_MM_PROTECT
5002+ if (p->canary != HG(canary_1)) goto efree_canary_mismatch;
5003+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5004+ if (canary_2 != HG(canary_2)) {
5005+efree_canary_mismatch:
5006+ zend_security_log(S_MEMORY, "canary mismatch on efree() - heap overflow or double efree detected");
5007+ exit(1);
5008+ }
5009+ /* to catch double efree()s */
5010+ memset((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), 0, CANARY_SIZE);
5011+ p->canary = 0;
5012+#endif
5013
5014 #if defined(ZTS) && TSRM_DEBUG
5015 if (p->thread_id != tsrm_thread_id()) {
5016@@ -292,23 +338,35 @@
5017
5018 ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5019 {
5020- void *p;
5021- int final_size = size*nmemb;
5022+ char *p;
5023+ size_t _size = nmemb * size;
5024+
5025+ if (nmemb && (_size/nmemb!=size)) {
5026+#if HARDENING_PATCH
5027+ zend_security_log(S_MEMORY, "Possible integer overflow catched by ecalloc()");
5028+#endif
5029+ fprintf(stderr,"FATAL: ecalloc(): Unable to allocate %ld * %ld bytes\n", (long) nmemb, (long) size);
5030+#if ZEND_DEBUG && HAVE_KILL && HAVE_GETPID
5031+ kill(getpid(), SIGSEGV);
5032+#else
5033+ exit(1);
5034+#endif
5035+ }
5036
5037- HANDLE_BLOCK_INTERRUPTIONS();
5038- p = _emalloc(final_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
5039- if (!p) {
5040- HANDLE_UNBLOCK_INTERRUPTIONS();
5041- return (void *) p;
5042+ p = (char *) _emalloc(_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
5043+ if (p) {
5044+ memset(p, 0, _size);
5045 }
5046- memset(p, 0, final_size);
5047- HANDLE_UNBLOCK_INTERRUPTIONS();
5048- return p;
5049+
5050+ return ((void *)p);
5051 }
5052
5053
5054 ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
5055 {
5056+#if HARDENING_PATCH_MM_PROTECT
5057+ unsigned int canary_2;
5058+#endif
5059 zend_mem_header *p;
5060 zend_mem_header *orig;
5061 DECLARE_CACHE_VARS();
5062@@ -320,6 +378,16 @@
5063
5064 p = orig = (zend_mem_header *) ((char *)ptr-sizeof(zend_mem_header)-MEM_HEADER_PADDING);
5065
5066+#if HARDENING_PATCH_MM_PROTECT
5067+ if (p->canary != HG(canary_1)) goto erealloc_canary_mismatch;
5068+ memcpy(&canary_2, (((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + p->size + END_MAGIC_SIZE), CANARY_SIZE);
5069+ if (canary_2 != HG(canary_2)) {
5070+erealloc_canary_mismatch:
5071+ zend_security_log(S_MEMORY, "canary mismatch on erealloc() - heap overflow detected");
5072+ exit(1);
5073+ }
5074+#endif
5075+
5076 #if defined(ZTS) && TSRM_DEBUG
5077 if (p->thread_id != tsrm_thread_id()) {
5078 void *new_p;
5079@@ -343,7 +411,7 @@
5080 }
5081 #endif
5082 REMOVE_POINTER_FROM_LIST(p);
5083- p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE);
5084+ p = (zend_mem_header *) ZEND_DO_REALLOC(p, sizeof(zend_mem_header)+MEM_HEADER_PADDING+SIZE+END_MAGIC_SIZE+CANARY_SIZE);
5085 if (!p) {
5086 if (!allow_failure) {
5087 fprintf(stderr,"FATAL: erealloc(): Unable to allocate %ld bytes\n", (long) size);
5088@@ -365,6 +433,9 @@
5089 memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size), &mem_block_end_magic, sizeof(long));
5090 #endif
5091
5092+#if HARDENING_PATCH_MM_PROTECT
5093+ memcpy((((char *) p) + sizeof(zend_mem_header) + MEM_HEADER_PADDING + size + END_MAGIC_SIZE), &HG(canary_2), CANARY_SIZE);
5094+#endif
5095 p->size = size;
5096
5097 HANDLE_UNBLOCK_INTERRUPTIONS();
5098@@ -439,6 +510,10 @@
5099 {
5100 AG(head) = NULL;
5101
5102+#if HARDENING_PATCH_MM_PROTECT
5103+ HG(canary_1) = zend_canary();
5104+ HG(canary_2) = zend_canary();
5105+#endif
5106 #if MEMORY_LIMIT
5107 AG(memory_limit) = 1<<30; /* ridiculous limit, effectively no limit */
5108 AG(allocated_memory) = 0;
5109diff -Nura php-5.0.5/Zend/zend_alloc.h hardening-patch-5.0.5-0.4.2/Zend/zend_alloc.h
5110--- php-5.0.5/Zend/zend_alloc.h 2005-06-07 15:37:13.000000000 +0200
5111+++ hardening-patch-5.0.5-0.4.2/Zend/zend_alloc.h 2005-09-07 13:49:17.000000000 +0200
5112@@ -35,6 +35,9 @@
5113 #define MEM_BLOCK_CACHED_MAGIC 0xFB8277DCL
5114
5115 typedef struct _zend_mem_header {
5116+#if HARDENING_PATCH_MM_PROTECT
5117+ unsigned int canary;
5118+#endif
5119 #if ZEND_DEBUG
5120 long magic;
5121 char *filename;
5122diff -Nura php-5.0.5/Zend/zend_API.h hardening-patch-5.0.5-0.4.2/Zend/zend_API.h
5123--- php-5.0.5/Zend/zend_API.h 2005-06-27 19:42:06.000000000 +0200
5124+++ hardening-patch-5.0.5-0.4.2/Zend/zend_API.h 2005-09-07 13:49:17.000000000 +0200
5125@@ -47,6 +47,7 @@
5126 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
5127
5128 #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 },
5129+#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 },
5130
5131 #define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
5132 #define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
5133diff -Nura php-5.0.5/Zend/zend_builtin_functions.c hardening-patch-5.0.5-0.4.2/Zend/zend_builtin_functions.c
5134--- php-5.0.5/Zend/zend_builtin_functions.c 2005-06-27 19:42:06.000000000 +0200
5135+++ hardening-patch-5.0.5-0.4.2/Zend/zend_builtin_functions.c 2005-09-07 13:49:17.000000000 +0200
5136@@ -52,6 +52,9 @@
5137 static ZEND_FUNCTION(crash);
5138 #endif
5139 #endif
5140+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5141+static ZEND_FUNCTION(heap_overflow);
5142+#endif
5143 static ZEND_FUNCTION(get_included_files);
5144 static ZEND_FUNCTION(is_subclass_of);
5145 static ZEND_FUNCTION(is_a);
5146@@ -111,6 +114,9 @@
5147 ZEND_FE(crash, NULL)
5148 #endif
5149 #endif
5150+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5151+ ZEND_FE(heap_overflow, NULL)
5152+#endif
5153 ZEND_FE(get_included_files, NULL)
5154 ZEND_FALIAS(get_required_files, get_included_files, NULL)
5155 ZEND_FE(is_subclass_of, NULL)
5156@@ -991,6 +997,19 @@
5157
5158 #endif /* ZEND_DEBUG */
5159
5160+
5161+#if HARDENING_PATCH_MM_PROTECT_DEBUG
5162+ZEND_FUNCTION(heap_overflow)
5163+{
5164+ char *nowhere = emalloc(10);
5165+
5166+ memcpy(nowhere, "something1234567890", sizeof("something1234567890"));
5167+
5168+ efree(nowhere);
5169+}
5170+#endif
5171+
5172+
5173 /* {{{ proto array get_included_files(void)
5174 Returns an array with the file names that were include_once()'d */
5175 ZEND_FUNCTION(get_included_files)
5176diff -Nura php-5.0.5/Zend/zend.c hardening-patch-5.0.5-0.4.2/Zend/zend.c
5177--- php-5.0.5/Zend/zend.c 2005-07-22 09:33:27.000000000 +0200
5178+++ hardening-patch-5.0.5-0.4.2/Zend/zend.c 2005-09-07 14:19:23.000000000 +0200
5179@@ -54,6 +54,12 @@
5180 ZEND_API void (*zend_unblock_interruptions)(void);
5181 ZEND_API void (*zend_ticks_function)(int ticks);
5182 ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
5183+#if HARDENING_PATCH
5184+ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
5185+#endif
5186+#if HARDENING_PATCH_INC_PROTECT
5187+ZEND_API int (*zend_is_valid_include)(zval *z);
5188+#endif
5189 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
5190
5191 void (*zend_on_timeout)(int seconds TSRMLS_DC);
5192@@ -72,9 +78,289 @@
5193 return SUCCESS;
5194 }
5195
5196+#if HARDENING_PATCH
5197+static ZEND_INI_MH(OnUpdateHPHP_log_syslog)
5198+{
5199+ if (!new_value) {
5200+ EG(hphp_log_syslog) = S_ALL & ~S_SQL | S_MEMORY | S_INTERNAL;
5201+ } else {
5202+ EG(hphp_log_syslog) = atoi(new_value) | S_MEMORY | S_INTERNAL;
5203+ }
5204+ return SUCCESS;
5205+}
5206+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_facility)
5207+{
5208+ if (!new_value) {
5209+ EG(hphp_log_syslog_facility) = LOG_USER;
5210+ } else {
5211+ EG(hphp_log_syslog_facility) = atoi(new_value);
5212+ }
5213+ return SUCCESS;
5214+}
5215+static ZEND_INI_MH(OnUpdateHPHP_log_syslog_priority)
5216+{
5217+ if (!new_value) {
5218+ EG(hphp_log_syslog_priority) = LOG_ALERT;
5219+ } else {
5220+ EG(hphp_log_syslog_priority) = atoi(new_value);
5221+ }
5222+ return SUCCESS;
5223+}
5224+static ZEND_INI_MH(OnUpdateHPHP_log_sapi)
5225+{
5226+ if (!new_value) {
5227+ EG(hphp_log_sapi) = S_ALL & ~S_SQL | S_INTERNAL;
5228+ } else {
5229+ EG(hphp_log_sapi) = atoi(new_value) | S_INTERNAL;
5230+ }
5231+ return SUCCESS;
5232+}
5233+static ZEND_INI_MH(OnUpdateHPHP_log_script)
5234+{
5235+ if (!new_value) {
5236+ EG(hphp_log_script) = S_ALL & ~S_MEMORY;
5237+ } else {
5238+ EG(hphp_log_script) = atoi(new_value) & (~S_MEMORY) & (~S_INTERNAL);
5239+ }
5240+ return SUCCESS;
5241+}
5242+static ZEND_INI_MH(OnUpdateHPHP_log_scriptname)
5243+{
5244+ if (!new_value) {
5245+ EG(hphp_log_scriptname) = NULL;
5246+ } else {
5247+ if (EG(hphp_log_scriptname)) {
5248+ pefree(EG(hphp_log_scriptname),1);
5249+ }
5250+ EG(hphp_log_scriptname) = pestrdup(new_value,1);
5251+ }
5252+ return SUCCESS;
5253+}
5254+
5255+static ZEND_INI_MH(OnUpdateHPHP_eval_whitelist)
5256+{
5257+ char *s = NULL, *e, *val;
5258+ unsigned long dummy = 1;
5259+
5260+ if (!new_value) {
5261+eval_whitelist_destroy:
5262+ if (HG(eval_whitelist)) {
5263+ zend_hash_destroy(HG(eval_whitelist));
5264+ efree(HG(eval_whitelist));
5265+ }
5266+ HG(eval_whitelist) = NULL;
5267+ return SUCCESS;
5268+ }
5269+ if (!(*new_value)) {
5270+ goto eval_whitelist_destroy;
5271+ }
5272+
5273+ ALLOC_HASHTABLE(HG(eval_whitelist));
5274+ zend_hash_init(HG(eval_whitelist), 5, NULL, NULL, 0);
5275+
5276+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5277+ e = val;
5278+
5279+ while (*e) {
5280+ switch (*e) {
5281+ case ' ':
5282+ case ',':
5283+ if (s) {
5284+ *e = '\0';
5285+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5286+ s = NULL;
5287+ }
5288+ break;
5289+ default:
5290+ if (!s) {
5291+ s = e;
5292+ }
5293+ break;
5294+ }
5295+ e++;
5296+ }
5297+ if (s) {
5298+ zend_hash_add(HG(eval_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5299+ }
5300+ efree(val);
5301+
5302+ return SUCCESS;
5303+}
5304+
5305+static ZEND_INI_MH(OnUpdateHPHP_eval_blacklist)
5306+{
5307+ char *s = NULL, *e, *val;
5308+ unsigned long dummy = 1;
5309+
5310+ if (!new_value) {
5311+eval_blacklist_destroy:
5312+ if (HG(eval_blacklist)) {
5313+ zend_hash_destroy(HG(eval_blacklist));
5314+ efree(HG(eval_blacklist));
5315+ }
5316+ HG(eval_blacklist) = NULL;
5317+ return SUCCESS;
5318+ }
5319+ if (!(*new_value)) {
5320+ goto eval_blacklist_destroy;
5321+ }
5322+
5323+ ALLOC_HASHTABLE(HG(eval_blacklist));
5324+ zend_hash_init(HG(eval_blacklist), 5, NULL, NULL, 0);
5325+
5326+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5327+ e = val;
5328+
5329+ while (*e) {
5330+ switch (*e) {
5331+ case ' ':
5332+ case ',':
5333+ if (s) {
5334+ *e = '\0';
5335+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5336+ s = NULL;
5337+ }
5338+ break;
5339+ default:
5340+ if (!s) {
5341+ s = e;
5342+ }
5343+ break;
5344+ }
5345+ e++;
5346+ }
5347+ if (s) {
5348+ zend_hash_add(HG(eval_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5349+ }
5350+ efree(val);
5351+
5352+
5353+ return SUCCESS;
5354+}
5355+
5356+static ZEND_INI_MH(OnUpdateHPHP_func_whitelist)
5357+{
5358+ char *s = NULL, *e, *val;
5359+ unsigned long dummy = 1;
5360+
5361+ if (!new_value) {
5362+func_whitelist_destroy:
5363+ if (HG(func_whitelist)) {
5364+ zend_hash_destroy(HG(func_whitelist));
5365+ efree(HG(func_whitelist));
5366+ }
5367+ HG(func_whitelist) = NULL;
5368+ return SUCCESS;
5369+ }
5370+ if (!(*new_value)) {
5371+ goto func_whitelist_destroy;
5372+ }
5373+
5374+ ALLOC_HASHTABLE(HG(func_whitelist));
5375+ zend_hash_init(HG(func_whitelist), 5, NULL, NULL, 0);
5376+
5377+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5378+ e = val;
5379+
5380+ while (*e) {
5381+ switch (*e) {
5382+ case ' ':
5383+ case ',':
5384+ if (s) {
5385+ *e = '\0';
5386+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5387+ s = NULL;
5388+ }
5389+ break;
5390+ default:
5391+ if (!s) {
5392+ s = e;
5393+ }
5394+ break;
5395+ }
5396+ e++;
5397+ }
5398+ if (s) {
5399+ zend_hash_add(HG(func_whitelist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5400+ }
5401+ efree(val);
5402+
5403+ return SUCCESS;
5404+}
5405+
5406+static ZEND_INI_MH(OnUpdateHPHP_func_blacklist)
5407+{
5408+ char *s = NULL, *e, *val;
5409+ unsigned long dummy = 1;
5410+
5411+ if (!new_value) {
5412+func_blacklist_destroy:
5413+ if (HG(func_blacklist)) {
5414+ zend_hash_destroy(HG(func_blacklist));
5415+ efree(HG(func_blacklist));
5416+ }
5417+ HG(func_blacklist) = NULL;
5418+ return SUCCESS;
5419+ }
5420+ if (!(*new_value)) {
5421+ goto func_blacklist_destroy;
5422+ }
5423+
5424+ ALLOC_HASHTABLE(HG(func_blacklist));
5425+ zend_hash_init(HG(func_blacklist), 5, NULL, NULL, 0);
5426+
5427+ val = zend_str_tolower_dup(new_value, strlen(new_value));
5428+ e = val;
5429+
5430+ while (*e) {
5431+ switch (*e) {
5432+ case ' ':
5433+ case ',':
5434+ if (s) {
5435+ *e = '\0';
5436+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5437+ s = NULL;
5438+ }
5439+ break;
5440+ default:
5441+ if (!s) {
5442+ s = e;
5443+ }
5444+ break;
5445+ }
5446+ e++;
5447+ }
5448+ if (s) {
5449+ zend_hash_add(HG(func_blacklist), s, e-s+1, &dummy, sizeof(unsigned long), NULL);
5450+ }
5451+ efree(val);
5452+
5453+
5454+ return SUCCESS;
5455+}
5456+
5457+#endif
5458
5459 ZEND_INI_BEGIN()
5460 ZEND_INI_ENTRY("error_reporting", NULL, ZEND_INI_ALL, OnUpdateErrorReporting)
5461+#if HARDENING_PATCH
5462+ ZEND_INI_ENTRY("hphp.log.syslog", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog)
5463+ ZEND_INI_ENTRY("hphp.log.syslog.facility", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_facility)
5464+ ZEND_INI_ENTRY("hphp.log.syslog.priority", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_syslog_priority)
5465+ ZEND_INI_ENTRY("hphp.log.sapi", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_sapi)
5466+ ZEND_INI_ENTRY("hphp.log.script", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_script)
5467+ ZEND_INI_ENTRY("hphp.log.script.name", NULL, ZEND_INI_SYSTEM, OnUpdateHPHP_log_scriptname)
5468+ 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)
5469+
5470+ ZEND_INI_ENTRY("hphp.executor.eval.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_whitelist)
5471+ ZEND_INI_ENTRY("hphp.executor.eval.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_eval_blacklist)
5472+ ZEND_INI_ENTRY("hphp.executor.func.whitelist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_whitelist)
5473+ ZEND_INI_ENTRY("hphp.executor.func.blacklist", NULL, ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateHPHP_func_blacklist)
5474+
5475+ 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)
5476+ 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)
5477+ STD_ZEND_INI_BOOLEAN("hphp.multiheader", "0", ZEND_INI_PERDIR|ZEND_INI_SYSTEM, OnUpdateBool, hphp_multiheader, hardened_globals_struct, hardened_globals)
5478+#endif
5479 STD_ZEND_INI_BOOLEAN("zend.ze1_compatibility_mode", "0", ZEND_INI_ALL, OnUpdateBool, ze1_compatibility_mode, zend_executor_globals, executor_globals)
5480 ZEND_INI_END()
5481
5482@@ -476,6 +762,7 @@
5483 EG(user_error_handler) = NULL;
5484 EG(user_exception_handler) = NULL;
5485 EG(in_execution) = 0;
5486+ EG(in_code_type) = 0;
5487 EG(in_autoload) = NULL;
5488 EG(current_execute_data) = NULL;
5489 EG(current_module) = NULL;
5490@@ -545,6 +832,14 @@
5491 extern zend_scanner_globals language_scanner_globals;
5492 #endif
5493
5494+ /* Set up Hardening-Patch utility functions first */
5495+#if HARDENING_PATCH
5496+ zend_security_log = utility_functions->security_log_function;
5497+#endif
5498+#if HARDENING_PATCH_INC_PROTECT
5499+ zend_is_valid_include = utility_functions->is_valid_include;
5500+#endif
5501+
5502 #ifdef ZTS
5503 ts_allocate_id(&alloc_globals_id, sizeof(zend_alloc_globals), (ts_allocate_ctor) alloc_globals_ctor, (ts_allocate_dtor) alloc_globals_dtor);
5504 #else
5505@@ -747,6 +1042,7 @@
5506 }
5507 CG(unclean_shutdown) = 1;
5508 CG(in_compilation) = EG(in_execution) = 0;
5509+ EG(in_code_type) = 0;
5510 EG(current_execute_data) = NULL;
5511 longjmp(EG(bailout), FAILURE);
5512 }
5513diff -Nura php-5.0.5/Zend/zend_canary.c hardening-patch-5.0.5-0.4.2/Zend/zend_canary.c
5514--- php-5.0.5/Zend/zend_canary.c 1970-01-01 01:00:00.000000000 +0100
5515+++ hardening-patch-5.0.5-0.4.2/Zend/zend_canary.c 2005-09-07 13:49:17.000000000 +0200
5516@@ -0,0 +1,58 @@
5517+/*
5518+ +----------------------------------------------------------------------+
5519+ | Hardening-Patch for PHP |
5520+ +----------------------------------------------------------------------+
5521+ | Copyright (c) 2004-2005 Stefan Esser |
5522+ +----------------------------------------------------------------------+
5523+ | This source file is subject to version 2.02 of the PHP license, |
5524+ | that is bundled with this package in the file LICENSE, and is |
5525+ | available at through the world-wide-web at |
5526+ | http://www.php.net/license/2_02.txt. |
5527+ | If you did not receive a copy of the PHP license and are unable to |
5528+ | obtain it through the world-wide-web, please send a note to |
5529+ | license@php.net so we can mail you a copy immediately. |
5530+ +----------------------------------------------------------------------+
5531+ | Author: Stefan Esser <sesser@hardened-php.net> |
5532+ +----------------------------------------------------------------------+
5533+ */
5534+/* $Id: zend_canary.c,v 1.1 2004/11/26 12:45:41 ionic Exp $ */
5535+
5536+#include "zend.h"
5537+
5538+#include <stdio.h>
5539+#include <stdlib.h>
5540+
5541+
5542+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
5543+
5544+/* will be replaced later with more compatible method */
5545+ZEND_API unsigned int zend_canary()
5546+{
5547+ time_t t;
5548+ unsigned int canary;
5549+ int fd;
5550+
5551+ fd = open("/dev/urandom", 0);
5552+ if (fd != -1) {
5553+ int r = read(fd, &canary, sizeof(canary));
5554+ close(fd);
5555+ if (r == sizeof(canary)) {
5556+ return (canary);
5557+ }
5558+ }
5559+ /* not good but we never want to do this */
5560+ time(&t);
5561+ canary = *(unsigned int *)&t + getpid() << 16;
5562+ return (canary);
5563+}
5564+#endif
5565+
5566+
5567+/*
5568+ * Local variables:
5569+ * tab-width: 4
5570+ * c-basic-offset: 4
5571+ * End:
5572+ * vim600: sw=4 ts=4 fdm=marker
5573+ * vim<600: sw=4 ts=4
5574+ */
5575diff -Nura php-5.0.5/Zend/zend_compile.c hardening-patch-5.0.5-0.4.2/Zend/zend_compile.c
5576--- php-5.0.5/Zend/zend_compile.c 2005-07-19 09:33:24.000000000 +0200
5577+++ hardening-patch-5.0.5-0.4.2/Zend/zend_compile.c 2005-09-07 13:49:17.000000000 +0200
5578@@ -979,6 +979,13 @@
5579 op_array.prototype = NULL;
5580
5581 op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
5582+#if HARDENING_PATCH
5583+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
5584+ op_array.created_by_eval = 1;
5585+ } else {
5586+ op_array.created_by_eval = 0;
5587+ }
5588+#endif
5589
5590 if (is_method) {
5591 char *short_class_name = CG(active_class_entry)->name;
5592diff -Nura php-5.0.5/Zend/zend_compile.h hardening-patch-5.0.5-0.4.2/Zend/zend_compile.h
5593--- php-5.0.5/Zend/zend_compile.h 2005-06-24 10:45:43.000000000 +0200
5594+++ hardening-patch-5.0.5-0.4.2/Zend/zend_compile.h 2005-09-07 13:49:17.000000000 +0200
5595@@ -203,6 +203,9 @@
5596 zend_uint doc_comment_len;
5597
5598 void *reserved[ZEND_MAX_RESERVED_RESOURCES];
5599+#if HARDENING_PATCH
5600+ zend_bool created_by_eval;
5601+#endif
5602 };
5603
5604
5605@@ -281,6 +284,8 @@
5606 zval *object;
5607 union _temp_variable *Ts;
5608 zend_bool original_in_execution;
5609+ zend_uint original_in_code_type;
5610+ zend_uint execute_depth;
5611 zend_class_entry *calling_scope;
5612 struct _zend_execute_data *prev_execute_data;
5613 };
5614@@ -774,6 +779,7 @@
5615 #define ZEND_OVERLOADED_FUNCTION 3
5616 #define ZEND_EVAL_CODE 4
5617 #define ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
5618+#define ZEND_SANDBOX_CODE 6
5619
5620 #define ZEND_INTERNAL_CLASS 1
5621 #define ZEND_USER_CLASS 2
5622diff -Nura php-5.0.5/Zend/zend_constants.c hardening-patch-5.0.5-0.4.2/Zend/zend_constants.c
5623--- php-5.0.5/Zend/zend_constants.c 2004-07-13 21:22:11.000000000 +0200
5624+++ hardening-patch-5.0.5-0.4.2/Zend/zend_constants.c 2005-09-07 14:19:23.000000000 +0200
5625@@ -107,6 +107,73 @@
5626 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
5627
5628 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
5629+#if HARDENING_PATCH
5630+ REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
5631+ REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
5632+ REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
5633+ REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
5634+ REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
5635+ REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
5636+ REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
5637+ REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
5638+ REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
5639+
5640+ /* error levels */
5641+ REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
5642+ REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
5643+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
5644+ REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT);
5645+ REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
5646+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
5647+ REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
5648+ REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
5649+ /* facility: type of program logging the message */
5650+ REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
5651+ REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
5652+ REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
5653+ REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
5654+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
5655+ REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
5656+ REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
5657+#ifdef LOG_NEWS
5658+ /* No LOG_NEWS on HP-UX */
5659+ REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
5660+#endif
5661+#ifdef LOG_UUCP
5662+ /* No LOG_UUCP on HP-UX */
5663+ REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
5664+#endif
5665+#ifdef LOG_CRON
5666+ /* apparently some systems don't have this one */
5667+ REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
5668+#endif
5669+#ifdef LOG_AUTHPRIV
5670+ /* AIX doesn't have LOG_AUTHPRIV */
5671+ REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
5672+#endif
5673+#if !defined(PHP_WIN32) && !defined(NETWARE)
5674+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
5675+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
5676+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
5677+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
5678+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
5679+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
5680+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
5681+ REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
5682+#endif
5683+ /* options */
5684+ REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
5685+ REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
5686+ REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
5687+ REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
5688+#ifdef LOG_NOWAIT
5689+ REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
5690+#endif
5691+#ifdef LOG_PERROR
5692+ /* AIX doesn't have LOG_PERROR */
5693+ REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
5694+#endif
5695+#endif
5696
5697 /* true/false constants */
5698 {
5699diff -Nura php-5.0.5/Zend/zend_errors.h hardening-patch-5.0.5-0.4.2/Zend/zend_errors.h
5700--- php-5.0.5/Zend/zend_errors.h 2004-01-08 18:31:47.000000000 +0100
5701+++ hardening-patch-5.0.5-0.4.2/Zend/zend_errors.h 2005-09-07 14:19:23.000000000 +0200
5702@@ -38,6 +38,18 @@
5703 #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)
5704 #define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
5705
5706+#if HARDENING_PATCH
5707+#define S_MEMORY (1<<0L)
5708+#define S_VARS (1<<1L)
5709+#define S_FILES (1<<2L)
5710+#define S_INCLUDE (1<<3L)
5711+#define S_SQL (1<<4L)
5712+#define S_EXECUTOR (1<<5L)
5713+#define S_MISC (1<<30L)
5714+#define S_INTERNAL (1<<29)
5715+#define S_ALL (S_MEMORY | S_VARS | S_INCLUDE | S_FILES | S_MISC | S_SQL | S_EXECUTOR)
5716+#endif
5717+
5718 #endif /* ZEND_ERRORS_H */
5719
5720 /*
5721diff -Nura php-5.0.5/Zend/zend_execute_API.c hardening-patch-5.0.5-0.4.2/Zend/zend_execute_API.c
5722--- php-5.0.5/Zend/zend_execute_API.c 2005-09-02 09:46:39.000000000 +0200
5723+++ hardening-patch-5.0.5-0.4.2/Zend/zend_execute_API.c 2005-09-07 13:49:17.000000000 +0200
5724@@ -137,6 +137,7 @@
5725 EG(class_table) = CG(class_table);
5726
5727 EG(in_execution) = 0;
5728+ EG(in_code_type) = 0;
5729 EG(in_autoload) = NULL;
5730
5731 zend_ptr_stack_init(&EG(argument_stack));
5732@@ -725,6 +726,39 @@
5733 if (zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
5734 EX(function_state).function = NULL;
5735 }
5736+#if HARDENING_PATCH
5737+ else {
5738+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
5739+ if (HG(eval_whitelist) != NULL) {
5740+ if (!zend_hash_exists(HG(eval_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
5741+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", function_name_lc);
5742+ efree(function_name_lc);
5743+ zend_bailout();
5744+ }
5745+ } else if (HG(eval_blacklist) != NULL) {
5746+ if (zend_hash_exists(HG(eval_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
5747+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", function_name_lc);
5748+ efree(function_name_lc);
5749+ zend_bailout();
5750+ }
5751+ }
5752+ }
5753+
5754+ if (HG(func_whitelist) != NULL) {
5755+ if (!zend_hash_exists(HG(func_whitelist), function_name_lc, fci->function_name->value.str.len+1)) {
5756+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", function_name_lc);
5757+ efree(function_name_lc);
5758+ zend_bailout();
5759+ }
5760+ } else if (HG(func_blacklist) != NULL) {
5761+ if (zend_hash_exists(HG(func_blacklist), function_name_lc, fci->function_name->value.str.len+1)) {
5762+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", function_name_lc);
5763+ efree(function_name_lc);
5764+ zend_bailout();
5765+ }
5766+ }
5767+ }
5768+#endif
5769 efree(function_name_lc);
5770 }
5771
5772@@ -999,7 +1033,7 @@
5773 return retval;
5774 }
5775
5776-ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
5777+ZEND_API int zend_eval_string_ex_ex(char *str, zval *retval_ptr, char *string_name, int type TSRMLS_DC)
5778 {
5779 zval pv;
5780 zend_op_array *new_op_array;
5781@@ -1032,6 +1066,7 @@
5782 zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
5783 zend_op **original_opline_ptr = EG(opline_ptr);
5784
5785+ new_op_array->type = type;
5786 EG(return_value_ptr_ptr) = &local_retval_ptr;
5787 EG(active_op_array) = new_op_array;
5788 EG(no_extensions)=1;
5789@@ -1066,6 +1101,12 @@
5790 }
5791
5792
5793+ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
5794+{
5795+ return (zend_eval_string_ex_ex(str, retval_ptr, string_name, ZEND_EVAL_CODE TSRMLS_CC));
5796+}
5797+
5798+
5799 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
5800 {
5801 int result;
5802diff -Nura php-5.0.5/Zend/zend_execute.c hardening-patch-5.0.5-0.4.2/Zend/zend_execute.c
5803--- php-5.0.5/Zend/zend_execute.c 2005-09-01 15:21:56.000000000 +0200
5804+++ hardening-patch-5.0.5-0.4.2/Zend/zend_execute.c 2005-09-07 13:49:17.000000000 +0200
5805@@ -1374,6 +1374,7 @@
5806 efree(EX(Ts)); \
5807 } \
5808 EG(in_execution) = EX(original_in_execution); \
5809+ EG(in_code_type) = EX(original_in_code_type); \
5810 EG(current_execute_data) = EX(prev_execute_data); \
5811 return 1; /* CHECK_ME */
5812
5813@@ -1400,6 +1401,16 @@
5814 EX(original_in_execution) = EG(in_execution);
5815 EX(prev_execute_data) = EG(current_execute_data);
5816 EG(current_execute_data) = &execute_data;
5817+#if HARDENING_PATCH
5818+ EX(execute_depth) = 0;
5819+
5820+ if ((op_array->type == ZEND_EVAL_CODE || op_array->created_by_eval)&& EG(in_code_type) != ZEND_SANDBOX_CODE) {
5821+ EG(in_code_type) = ZEND_EVAL_CODE;
5822+ } else if (op_array->type == ZEND_SANDBOX_CODE) {
5823+ EG(in_code_type) = ZEND_SANDBOX_CODE;
5824+ op_array->type = ZEND_EVAL_CODE;
5825+ }
5826+#endif
5827
5828 EG(in_execution) = 1;
5829 if (op_array->start_op) {
5830@@ -1426,6 +1437,19 @@
5831 EX(function_state).function_symbol_table = NULL;
5832 #endif
5833
5834+#if HARDENING_PATCH
5835+ if (EX(prev_execute_data) == NULL) {
5836+ EX(execute_depth) = 0;
5837+ } else {
5838+ EX(execute_depth) = EX(prev_execute_data)->execute_depth + 1;
5839+ }
5840+
5841+ if (EG(hphp_executor_max_depth) > 0 && EX(execute_depth) > EG(hphp_executor_max_depth)) {
5842+ zend_security_log(S_EXECUTOR, "Maximum execution depth of %u violated", EG(hphp_executor_max_depth));
5843+ zend_bailout();
5844+ }
5845+#endif
5846+
5847 while (1) {
5848 #ifdef ZEND_WIN32
5849 if (EG(timed_out)) {
5850@@ -2680,6 +2704,37 @@
5851 efree(lcname);
5852 zend_error(E_ERROR, "Call to undefined function %s()", function_name_strval);
5853 }
5854+#if HARDENING_PATCH
5855+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
5856+ if (HG(eval_whitelist) != NULL) {
5857+ if (!zend_hash_exists(HG(eval_whitelist), lcname, function_name_strlen+1)) {
5858+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", lcname);
5859+ efree(lcname);
5860+ zend_bailout();
5861+ }
5862+ } else if (HG(eval_blacklist) != NULL) {
5863+ if (zend_hash_exists(HG(eval_blacklist), lcname, function_name_strlen+1)) {
5864+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", lcname);
5865+ efree(lcname);
5866+ zend_bailout();
5867+ }
5868+ }
5869+ }
5870+
5871+ if (HG(func_whitelist) != NULL) {
5872+ if (!zend_hash_exists(HG(func_whitelist), lcname, function_name_strlen+1)) {
5873+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", lcname);
5874+ efree(lcname);
5875+ zend_bailout();
5876+ }
5877+ } else if (HG(func_blacklist) != NULL) {
5878+ if (zend_hash_exists(HG(func_blacklist), lcname, function_name_strlen+1)) {
5879+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", lcname);
5880+ efree(lcname);
5881+ zend_bailout();
5882+ }
5883+ }
5884+#endif
5885
5886 efree(lcname);
5887 if (!is_const) {
5888@@ -2886,6 +2941,34 @@
5889 if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
5890 zend_error(E_ERROR, "Unknown function: %s()\n", fname->value.str.val);
5891 }
5892+#if HARDENING_PATCH
5893+ if (EG(in_code_type) == ZEND_EVAL_CODE) {
5894+ if (HG(eval_whitelist) != NULL) {
5895+ if (!zend_hash_exists(HG(eval_whitelist), fname->value.str.val, fname->value.str.len+1)) {
5896+ zend_security_log(S_EXECUTOR, "function outside of eval whitelist called: %s()", fname->value.str.val);
5897+ zend_bailout();
5898+ }
5899+ } else if (HG(eval_blacklist) != NULL) {
5900+ if (zend_hash_exists(HG(eval_blacklist), fname->value.str.val, fname->value.str.len+1)) {
5901+ zend_security_log(S_EXECUTOR, "function within eval blacklist called: %s()", fname->value.str.val);
5902+ zend_bailout();
5903+ }
5904+ }
5905+ }
5906+
5907+ if (HG(func_whitelist) != NULL) {
5908+ if (!zend_hash_exists(HG(func_whitelist), fname->value.str.val, fname->value.str.len+1)) {
5909+ zend_security_log(S_EXECUTOR, "function outside of whitelist called: %s()", fname->value.str.val);
5910+ zend_bailout();
5911+ }
5912+ } else if (HG(func_blacklist) != NULL) {
5913+ if (zend_hash_exists(HG(func_blacklist), fname->value.str.val, fname->value.str.len+1)) {
5914+ zend_security_log(S_EXECUTOR, "function within blacklist called: %s()", fname->value.str.val);
5915+ zend_bailout();
5916+ }
5917+ }
5918+#endif
5919+
5920 EX(object) = NULL;
5921 EX(calling_scope) = EX(function_state).function->common.scope;
5922
5923@@ -3573,7 +3656,12 @@
5924 int dummy = 1;
5925 zend_file_handle file_handle;
5926
5927+#if HARDENING_PATCH_INC_PROTECT
5928+ if (zend_is_valid_include(inc_filename)
5929+ && (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC))) {
5930+#else
5931 if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) {
5932+#endif
5933
5934 if (!file_handle.opened_path) {
5935 file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len);
5936@@ -3598,6 +3686,11 @@
5937 break;
5938 case ZEND_INCLUDE:
5939 case ZEND_REQUIRE:
5940+#if HARDENING_PATCH_INC_PROTECT
5941+ if (!zend_is_valid_include(inc_filename)) {
5942+ break;
5943+ }
5944+#endif
5945 new_op_array = compile_filename(opline->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
5946 break;
5947 case ZEND_EVAL: {
5948diff -Nura php-5.0.5/Zend/zend_extensions.c hardening-patch-5.0.5-0.4.2/Zend/zend_extensions.c
5949--- php-5.0.5/Zend/zend_extensions.c 2004-01-08 18:31:47.000000000 +0100
5950+++ hardening-patch-5.0.5-0.4.2/Zend/zend_extensions.c 2005-09-07 13:49:17.000000000 +0200
5951@@ -55,23 +55,44 @@
5952 return FAILURE;
5953 }
5954
5955+ /* check if module is compiled against Hardening-Patch */
5956+ if (extension_version_info->zend_extension_api_no < 1000000000) {
5957+ fprintf(stderr, "%s is not compiled with Hardening-Patch.\n"
5958+ "The Hardening-Patch version %d is installed.\n\n",
5959+ new_extension->name,
5960+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
5961+ DL_UNLOAD(handle);
5962+ return FAILURE;
5963+ }
5964+
5965+
5966+ /* check if module is compiled against correct Hardening-Patch version */
5967+ if (extension_version_info->zend_extension_api_no != HARDENING_PATCH_ZEND_EXTENSION_API_NO) {
5968+ fprintf(stderr, "%s requires Hardening-Patch version %d.\n"
5969+ "The Hardening-Patch version %d is installed.\n\n",
5970+ new_extension->name,
5971+ extension_version_info->zend_extension_api_no,
5972+ HARDENING_PATCH_ZEND_EXTENSION_API_NO);
5973+ DL_UNLOAD(handle);
5974+ return FAILURE;
5975+ }
5976
5977 /* allow extension to proclaim compatibility with any Zend version */
5978- 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)) {
5979- if (extension_version_info->zend_extension_api_no > ZEND_EXTENSION_API_NO) {
5980+ 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)) {
5981+ if (extension_version_info->real_zend_extension_api_no > ZEND_EXTENSION_API_NO) {
5982 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
5983 "The Zend Engine API version %d which is installed, is outdated.\n\n",
5984 new_extension->name,
5985- extension_version_info->zend_extension_api_no,
5986+ extension_version_info->real_zend_extension_api_no,
5987 ZEND_EXTENSION_API_NO);
5988 DL_UNLOAD(handle);
5989 return FAILURE;
5990- } else if (extension_version_info->zend_extension_api_no < ZEND_EXTENSION_API_NO) {
5991+ } else if (extension_version_info->real_zend_extension_api_no < ZEND_EXTENSION_API_NO) {
5992 fprintf(stderr, "%s requires Zend Engine API version %d.\n"
5993 "The Zend Engine API version %d which is installed, is newer.\n"
5994 "Contact %s at %s for a later version of %s.\n\n",
5995 new_extension->name,
5996- extension_version_info->zend_extension_api_no,
5997+ extension_version_info->real_zend_extension_api_no,
5998 ZEND_EXTENSION_API_NO,
5999 new_extension->author,
6000 new_extension->URL,
6001diff -Nura php-5.0.5/Zend/zend_extensions.h hardening-patch-5.0.5-0.4.2/Zend/zend_extensions.h
6002--- php-5.0.5/Zend/zend_extensions.h 2004-11-25 21:26:48.000000000 +0100
6003+++ hardening-patch-5.0.5-0.4.2/Zend/zend_extensions.h 2005-09-07 13:49:17.000000000 +0200
6004@@ -24,9 +24,11 @@
6005
6006 #include "zend_compile.h"
6007
6008-/* The first number is the engine version and the rest is the date.
6009+/* The first API number is a flag saying that Hardening-Patch is used.
6010+ * The second number is the engine version and the date.
6011 * This way engine 2 API no. is always greater than engine 1 API no..
6012 */
6013+#define HARDENING_PATCH_ZEND_EXTENSION_API_NO 1002050805
6014 #define ZEND_EXTENSION_API_NO 220040412
6015
6016 typedef struct _zend_extension_version_info {
6017@@ -34,6 +36,7 @@
6018 char *required_zend_version;
6019 unsigned char thread_safe;
6020 unsigned char debug;
6021+ int real_zend_extension_api_no;
6022 } zend_extension_version_info;
6023
6024
6025@@ -101,7 +104,7 @@
6026
6027
6028 #define ZEND_EXTENSION() \
6029- ZEND_EXT_API zend_extension_version_info extension_version_info = { ZEND_EXTENSION_API_NO, ZEND_VERSION, ZTS_V, ZEND_DEBUG }
6030+ 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 }
6031
6032 #define STANDARD_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6033 #define COMPAT_ZEND_EXTENSION_PROPERTIES NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1
6034diff -Nura php-5.0.5/Zend/zend_globals.h hardening-patch-5.0.5-0.4.2/Zend/zend_globals.h
6035--- php-5.0.5/Zend/zend_globals.h 2004-11-04 00:14:31.000000000 +0100
6036+++ hardening-patch-5.0.5-0.4.2/Zend/zend_globals.h 2005-09-07 13:49:17.000000000 +0200
6037@@ -174,6 +174,16 @@
6038
6039 int error_reporting;
6040 int orig_error_reporting;
6041+#if HARDENING_PATCH
6042+ int hphp_log_syslog;
6043+ int hphp_log_syslog_facility;
6044+ int hphp_log_syslog_priority;
6045+ int hphp_log_sapi;
6046+ int hphp_log_script;
6047+ char *hphp_log_scriptname;
6048+ zend_bool hphp_log_use_x_forwarded_for;
6049+ long hphp_executor_max_depth;
6050+#endif
6051 int exit_status;
6052
6053 zend_op_array *active_op_array;
6054@@ -191,6 +201,7 @@
6055 int ticks_count;
6056
6057 zend_bool in_execution;
6058+ zend_uint in_code_type;
6059 HashTable *in_autoload;
6060 zend_bool bailout_set;
6061 zend_bool full_tables_cleanup;
6062diff -Nura php-5.0.5/Zend/zend.h hardening-patch-5.0.5-0.4.2/Zend/zend.h
6063--- php-5.0.5/Zend/zend.h 2005-08-25 19:41:08.000000000 +0200
6064+++ hardening-patch-5.0.5-0.4.2/Zend/zend.h 2005-09-07 13:49:17.000000000 +0200
6065@@ -290,6 +290,7 @@
6066 /* Variable information */
6067 zvalue_value value; /* value */
6068 zend_uint refcount;
6069+ zend_ushort flags;
6070 zend_uchar type; /* active type */
6071 zend_uchar is_ref;
6072 };
6073@@ -359,6 +360,12 @@
6074 void (*on_timeout)(int seconds TSRMLS_DC);
6075 int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
6076 int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
6077+#if HARDENING_PATCH
6078+ void (*security_log_function)(int loglevel, char *fmt, ...);
6079+#endif
6080+#if HARDENING_PATCH_INC_PROTECT
6081+ int (*is_valid_include)(zval *z);
6082+#endif
6083 } zend_utility_functions;
6084
6085
6086@@ -497,6 +504,16 @@
6087 extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
6088 extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
6089 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
6090+#if HARDENING_PATCH
6091+extern ZEND_API void (*zend_security_log)(int loglevel, char *fmt, ...);
6092+#endif
6093+#if HARDENING_PATCH_INC_PROTECT
6094+extern ZEND_API int (*zend_is_valid_include)(zval *z);
6095+#endif
6096+
6097+#if HARDENING_PATCH_MM_PROTECT || HARDENING_PATCH_LL_PROTECT || HARDENING_PATCH_HASH_PROTECT
6098+ZEND_API unsigned int zend_canary(void);
6099+#endif
6100
6101
6102 ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
6103@@ -621,6 +638,11 @@
6104 #define ZEND_MAX_RESERVED_RESOURCES 4
6105
6106
6107+#if HARDENING_PATCH
6108+#include "hardened_globals.h"
6109+#include "php_syslog.h"
6110+#endif
6111+
6112 #endif /* ZEND_H */
6113
6114 /*
6115diff -Nura php-5.0.5/Zend/zend_hash.c hardening-patch-5.0.5-0.4.2/Zend/zend_hash.c
6116--- php-5.0.5/Zend/zend_hash.c 2005-04-25 08:11:00.000000000 +0200
6117+++ hardening-patch-5.0.5-0.4.2/Zend/zend_hash.c 2005-09-07 13:49:17.000000000 +0200
6118@@ -21,6 +21,18 @@
6119
6120 #include "zend.h"
6121
6122+#if HARDENING_PATCH_HASH_PROTECT
6123+ unsigned int zend_hash_canary = 0x1234567;
6124+ zend_bool zend_hash_canary_inited = 0;
6125+#endif
6126+
6127+#define CHECK_HASH_CANARY(hash) \
6128+ if (zend_hash_canary != (hash)->canary) { \
6129+ zend_security_log(S_MEMORY, "Zend HashTable canary was overwritten"); \
6130+ exit(1); \
6131+ }
6132+
6133+
6134 #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \
6135 (element)->pNext = (list_head); \
6136 (element)->pLast = NULL; \
6137@@ -138,6 +150,9 @@
6138 {
6139 uint i = 3;
6140 Bucket **tmp;
6141+#if HARDENING_PATCH_HASH_PROTECT
6142+ TSRMLS_FETCH();
6143+#endif
6144
6145 SET_INCONSISTENT(HT_OK);
6146
6147@@ -147,6 +162,13 @@
6148
6149 ht->nTableSize = 1 << i;
6150 ht->nTableMask = ht->nTableSize - 1;
6151+#if HARDENING_PATCH_HASH_PROTECT
6152+ if (zend_hash_canary_inited==0) {
6153+ zend_hash_canary = zend_canary();
6154+ zend_hash_canary_inited = 1;
6155+ }
6156+ ht->canary = zend_hash_canary;
6157+#endif
6158 ht->pDestructor = pDestructor;
6159 ht->arBuckets = NULL;
6160 ht->pListHead = NULL;
6161@@ -226,6 +248,9 @@
6162 }
6163 #endif
6164 if (ht->pDestructor) {
6165+#if HARDENING_PATCH_HASH_PROTECT
6166+ CHECK_HASH_CANARY(ht);
6167+#endif
6168 ht->pDestructor(p->pData);
6169 }
6170 UPDATE_DATA(ht, p, pData, nDataSize);
6171@@ -291,6 +316,9 @@
6172 }
6173 #endif
6174 if (ht->pDestructor) {
6175+#if HARDENING_PATCH_HASH_PROTECT
6176+ CHECK_HASH_CANARY(ht);
6177+#endif
6178 ht->pDestructor(p->pData);
6179 }
6180 UPDATE_DATA(ht, p, pData, nDataSize);
6181@@ -366,6 +394,9 @@
6182 }
6183 #endif
6184 if (ht->pDestructor) {
6185+#if HARDENING_PATCH_HASH_PROTECT
6186+ CHECK_HASH_CANARY(ht);
6187+#endif
6188 ht->pDestructor(p->pData);
6189 }
6190 UPDATE_DATA(ht, p, pData, nDataSize);
6191@@ -414,7 +445,7 @@
6192 IS_CONSISTENT(ht);
6193
6194 if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
6195- t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6196+ t = (Bucket **) perealloc(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
6197 if (t) {
6198 HANDLE_BLOCK_INTERRUPTIONS();
6199 ht->arBuckets = t;
6200@@ -424,6 +455,7 @@
6201 HANDLE_UNBLOCK_INTERRUPTIONS();
6202 return SUCCESS;
6203 }
6204+ zend_error(E_ERROR, "zend_hash_do_resize - out of memory");
6205 return FAILURE;
6206 }
6207 return SUCCESS;
6208@@ -487,6 +519,9 @@
6209 ht->pInternalPointer = p->pListNext;
6210 }
6211 if (ht->pDestructor) {
6212+#if HARDENING_PATCH_HASH_PROTECT
6213+ CHECK_HASH_CANARY(ht);
6214+#endif
6215 ht->pDestructor(p->pData);
6216 }
6217 if (!p->pDataPtr) {
6218@@ -516,6 +551,9 @@
6219 q = p;
6220 p = p->pListNext;
6221 if (ht->pDestructor) {
6222+#if HARDENING_PATCH_HASH_PROTECT
6223+ CHECK_HASH_CANARY(ht);
6224+#endif
6225 ht->pDestructor(q->pData);
6226 }
6227 if (!q->pDataPtr && q->pData) {
6228@@ -542,6 +580,9 @@
6229 q = p;
6230 p = p->pListNext;
6231 if (ht->pDestructor) {
6232+#if HARDENING_PATCH_HASH_PROTECT
6233+ CHECK_HASH_CANARY(ht);
6234+#endif
6235 ht->pDestructor(q->pData);
6236 }
6237 if (!q->pDataPtr && q->pData) {
6238@@ -571,6 +612,9 @@
6239 HANDLE_BLOCK_INTERRUPTIONS();
6240
6241 if (ht->pDestructor) {
6242+#if HARDENING_PATCH_HASH_PROTECT
6243+ CHECK_HASH_CANARY(ht);
6244+#endif
6245 ht->pDestructor(p->pData);
6246 }
6247 if (!p->pDataPtr) {
6248diff -Nura php-5.0.5/Zend/zend_hash.h hardening-patch-5.0.5-0.4.2/Zend/zend_hash.h
6249--- php-5.0.5/Zend/zend_hash.h 2004-01-08 18:31:47.000000000 +0100
6250+++ hardening-patch-5.0.5-0.4.2/Zend/zend_hash.h 2005-09-07 13:49:17.000000000 +0200
6251@@ -58,6 +58,9 @@
6252 } Bucket;
6253
6254 typedef struct _hashtable {
6255+#if HARDENING_PATCH_HASH_PROTECT
6256+ unsigned int canary;
6257+#endif
6258 uint nTableSize;
6259 uint nTableMask;
6260 uint nNumOfElements;
6261diff -Nura php-5.0.5/Zend/zend_language_scanner.l hardening-patch-5.0.5-0.4.2/Zend/zend_language_scanner.l
6262--- php-5.0.5/Zend/zend_language_scanner.l 2005-06-09 10:54:24.000000000 +0200
6263+++ hardening-patch-5.0.5-0.4.2/Zend/zend_language_scanner.l 2005-09-07 13:49:17.000000000 +0200
6264@@ -386,6 +386,13 @@
6265 compilation_successful=0;
6266 } else {
6267 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
6268+#if HARDENING_PATCH
6269+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6270+ op_array->created_by_eval = 1;
6271+ } else {
6272+ op_array->created_by_eval = 0;
6273+ }
6274+#endif
6275 CG(in_compilation) = 1;
6276 CG(active_op_array) = op_array;
6277 compiler_result = zendparse(TSRMLS_C);
6278diff -Nura php-5.0.5/Zend/zend_language_scanner.c hardening-patch-5.0.5-0.4.2/Zend/zend_language_scanner.c
6279--- php-5.0.5/Zend/zend_language_scanner.c 2005-09-05 13:16:27.000000000 +0200
6280+++ hardening-patch-5.0.5-0.4.2/Zend/zend_language_scanner.c 2005-09-07 13:49:17.000000000 +0200
6281@@ -3153,6 +3153,13 @@
6282 compilation_successful=0;
6283 } else {
6284 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
6285+#if HARDENING_PATCH
6286+ if (EG(in_code_type)==ZEND_EVAL_CODE) {
6287+ op_array->created_by_eval = 1;
6288+ } else {
6289+ op_array->created_by_eval = 0;
6290+ }
6291+#endif
6292 CG(in_compilation) = 1;
6293 CG(active_op_array) = op_array;
6294 compiler_result = zendparse(TSRMLS_C);
6295diff -Nura php-5.0.5/Zend/zend_llist.c hardening-patch-5.0.5-0.4.2/Zend/zend_llist.c
6296--- php-5.0.5/Zend/zend_llist.c 2004-01-08 18:31:47.000000000 +0100
6297+++ hardening-patch-5.0.5-0.4.2/Zend/zend_llist.c 2005-09-07 13:49:17.000000000 +0200
6298@@ -22,9 +22,34 @@
6299 #include "zend.h"
6300 #include "zend_llist.h"
6301 #include "zend_qsort.h"
6302+#include "zend_globals.h"
6303+
6304+#define CHECK_LIST_CANARY(list) \
6305+ if (HG(canary_3) != (list)->canary_h || HG(canary_4) != (list)->canary_t) { \
6306+ zend_security_log(S_MEMORY, "linked list canary was overwritten"); \
6307+ exit(1); \
6308+ }
6309+
6310+#define CHECK_LISTELEMENT_CANARY(elem) \
6311+ if (HG(canary_3) != (elem)->canary) { \
6312+ zend_security_log(S_MEMORY, "linked list element canary was overwritten"); \
6313+ exit(1); \
6314+ }
6315+
6316
6317 ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
6318 {
6319+#if HARDENING_PATCH_LL_PROTECT
6320+ TSRMLS_FETCH();
6321+
6322+ if (!HG(ll_canary_inited)) {
6323+ HG(canary_3) = zend_canary();
6324+ HG(canary_4) = zend_canary();
6325+ HG(ll_canary_inited) = 1;
6326+ }
6327+ l->canary_h = HG(canary_3);
6328+ l->canary_t = HG(canary_4);
6329+#endif
6330 l->head = NULL;
6331 l->tail = NULL;
6332 l->count = 0;
6333@@ -38,6 +63,11 @@
6334 {
6335 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
6336
6337+#if HARDENING_PATCH_LL_PROTECT
6338+ TSRMLS_FETCH();
6339+ CHECK_LIST_CANARY(l)
6340+ tmp->canary = HG(canary_3);
6341+#endif
6342 tmp->prev = l->tail;
6343 tmp->next = NULL;
6344 if (l->tail) {
6345@@ -56,6 +86,11 @@
6346 {
6347 zend_llist_element *tmp = pemalloc(sizeof(zend_llist_element)+l->size-1, l->persistent);
6348
6349+#if HARDENING_PATCH_LL_PROTECT
6350+ TSRMLS_FETCH();
6351+ CHECK_LIST_CANARY(l)
6352+ tmp->canary = HG(canary_3);
6353+#endif
6354 tmp->next = l->head;
6355 tmp->prev = NULL;
6356 if (l->head) {
6357@@ -93,10 +128,20 @@
6358 zend_llist_element *current=l->head;
6359 zend_llist_element *next;
6360
6361+#if HARDENING_PATCH_LL_PROTECT
6362+ TSRMLS_FETCH();
6363+ CHECK_LIST_CANARY(l)
6364+#endif
6365 while (current) {
6366+#if HARDENING_PATCH_LL_PROTECT
6367+ CHECK_LISTELEMENT_CANARY(current)
6368+#endif
6369 next = current->next;
6370 if (compare(current->data, element)) {
6371 DEL_LLIST_ELEMENT(current, l);
6372+#if HARDENING_PATCH_LL_PROTECT
6373+ current->canary = 0;
6374+#endif
6375 break;
6376 }
6377 current = next;
6378@@ -108,7 +153,14 @@
6379 {
6380 zend_llist_element *current=l->head, *next;
6381
6382+#if HARDENING_PATCH_LL_PROTECT
6383+ TSRMLS_FETCH();
6384+ CHECK_LIST_CANARY(l)
6385+#endif
6386 while (current) {
6387+#if HARDENING_PATCH_LL_PROTECT
6388+ CHECK_LISTELEMENT_CANARY(current)
6389+#endif
6390 next = current->next;
6391 if (l->dtor) {
6392 l->dtor(current->data);
6393@@ -133,7 +185,14 @@
6394 zend_llist_element *old_tail;
6395 void *data;
6396
6397+#if HARDENING_PATCH_LL_PROTECT
6398+ TSRMLS_FETCH();
6399+ CHECK_LIST_CANARY(l)
6400+#endif
6401 if ((old_tail = l->tail)) {
6402+#if HARDENING_PATCH_LL_PROTECT
6403+ CHECK_LISTELEMENT_CANARY(old_tail)
6404+#endif
6405 if (l->tail->prev) {
6406 l->tail->prev->next = NULL;
6407 }
6408@@ -159,9 +218,16 @@
6409 {
6410 zend_llist_element *ptr;
6411
6412+#if HARDENING_PATCH_LL_PROTECT
6413+ TSRMLS_FETCH();
6414+ CHECK_LIST_CANARY(src)
6415+#endif
6416 zend_llist_init(dst, src->size, src->dtor, src->persistent);
6417 ptr = src->head;
6418 while (ptr) {
6419+#if HARDENING_PATCH_LL_PROTECT
6420+ CHECK_LISTELEMENT_CANARY(ptr)
6421+#endif
6422 zend_llist_add_element(dst, ptr->data);
6423 ptr = ptr->next;
6424 }
6425@@ -172,11 +238,21 @@
6426 {
6427 zend_llist_element *element, *next;
6428
6429+#if HARDENING_PATCH_LL_PROTECT
6430+ TSRMLS_FETCH();
6431+ CHECK_LIST_CANARY(l)
6432+#endif
6433 element=l->head;
6434 while (element) {
6435+#if HARDENING_PATCH_LL_PROTECT
6436+ CHECK_LISTELEMENT_CANARY(element)
6437+#endif
6438 next = element->next;
6439 if (func(element->data)) {
6440 DEL_LLIST_ELEMENT(element, l);
6441+#if HARDENING_PATCH_LL_PROTECT
6442+ element->canary = 0;
6443+#endif
6444 }
6445 element = next;
6446 }
6447@@ -187,7 +263,13 @@
6448 {
6449 zend_llist_element *element;
6450
6451+#if HARDENING_PATCH_LL_PROTECT
6452+ CHECK_LIST_CANARY(l)
6453+#endif
6454 for (element=l->head; element; element=element->next) {
6455+#if HARDENING_PATCH_LL_PROTECT
6456+ CHECK_LISTELEMENT_CANARY(element)
6457+#endif
6458 func(element->data TSRMLS_CC);
6459 }
6460 }
6461@@ -199,6 +281,9 @@
6462 zend_llist_element **elements;
6463 zend_llist_element *element, **ptr;
6464
6465+#if HARDENING_PATCH_LL_PROTECT
6466+ CHECK_LIST_CANARY(l)
6467+#endif
6468 if (l->count <= 0) {
6469 return;
6470 }
6471@@ -208,6 +293,9 @@
6472 ptr = &elements[0];
6473
6474 for (element=l->head; element; element=element->next) {
6475+#if HARDENING_PATCH_LL_PROTECT
6476+ CHECK_LISTELEMENT_CANARY(element)
6477+#endif
6478 *ptr++ = element;
6479 }
6480
6481@@ -230,7 +318,13 @@
6482 {
6483 zend_llist_element *element;
6484
6485+#if HARDENING_PATCH_LL_PROTECT
6486+ CHECK_LIST_CANARY(l)
6487+#endif
6488 for (element=l->head; element; element=element->next) {
6489+#if HARDENING_PATCH_LL_PROTECT
6490+ CHECK_LISTELEMENT_CANARY(element)
6491+#endif
6492 func(element->data, arg TSRMLS_CC);
6493 }
6494 }
6495@@ -241,8 +335,14 @@
6496 zend_llist_element *element;
6497 va_list args;
6498
6499+#if HARDENING_PATCH_LL_PROTECT
6500+ CHECK_LIST_CANARY(l)
6501+#endif
6502 va_start(args, num_args);
6503 for (element=l->head; element; element=element->next) {
6504+#if HARDENING_PATCH_LL_PROTECT
6505+ CHECK_LISTELEMENT_CANARY(element)
6506+#endif
6507 func(element->data, num_args, args TSRMLS_CC);
6508 }
6509 va_end(args);
6510@@ -251,6 +351,10 @@
6511
6512 ZEND_API int zend_llist_count(zend_llist *l)
6513 {
6514+#if HARDENING_PATCH_LL_PROTECT
6515+ TSRMLS_FETCH();
6516+ CHECK_LIST_CANARY(l)
6517+#endif
6518 return l->count;
6519 }
6520
6521@@ -259,8 +363,15 @@
6522 {
6523 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
6524
6525+#if HARDENING_PATCH_LL_PROTECT
6526+ TSRMLS_FETCH();
6527+ CHECK_LIST_CANARY(l)
6528+#endif
6529 *current = l->head;
6530 if (*current) {
6531+#if HARDENING_PATCH_LL_PROTECT
6532+ CHECK_LISTELEMENT_CANARY(*current)
6533+#endif
6534 return (*current)->data;
6535 } else {
6536 return NULL;
6537@@ -272,8 +383,15 @@
6538 {
6539 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
6540
6541+#if HARDENING_PATCH_LL_PROTECT
6542+ TSRMLS_FETCH();
6543+ CHECK_LIST_CANARY(l)
6544+#endif
6545 *current = l->tail;
6546 if (*current) {
6547+#if HARDENING_PATCH_LL_PROTECT
6548+ CHECK_LISTELEMENT_CANARY(*current)
6549+#endif
6550 return (*current)->data;
6551 } else {
6552 return NULL;
6553@@ -285,9 +403,19 @@
6554 {
6555 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
6556
6557+#if HARDENING_PATCH_LL_PROTECT
6558+ TSRMLS_FETCH();
6559+ CHECK_LIST_CANARY(l)
6560+#endif
6561 if (*current) {
6562+#if HARDENING_PATCH_LL_PROTECT
6563+ CHECK_LISTELEMENT_CANARY(*current)
6564+#endif
6565 *current = (*current)->next;
6566 if (*current) {
6567+#if HARDENING_PATCH_LL_PROTECT
6568+ CHECK_LISTELEMENT_CANARY(*current)
6569+#endif
6570 return (*current)->data;
6571 }
6572 }
6573@@ -299,9 +427,19 @@
6574 {
6575 zend_llist_position *current = pos ? pos : &l->traverse_ptr;
6576
6577+#if HARDENING_PATCH_LL_PROTECT
6578+ TSRMLS_FETCH();
6579+ CHECK_LIST_CANARY(l)
6580+#endif
6581 if (*current) {
6582+#if HARDENING_PATCH_LL_PROTECT
6583+ CHECK_LISTELEMENT_CANARY(*current)
6584+#endif
6585 *current = (*current)->prev;
6586 if (*current) {
6587+#if HARDENING_PATCH_LL_PROTECT
6588+ CHECK_LISTELEMENT_CANARY(*current)
6589+#endif
6590 return (*current)->data;
6591 }
6592 }
6593diff -Nura php-5.0.5/Zend/zend_llist.h hardening-patch-5.0.5-0.4.2/Zend/zend_llist.h
6594--- php-5.0.5/Zend/zend_llist.h 2004-01-08 18:31:47.000000000 +0100
6595+++ hardening-patch-5.0.5-0.4.2/Zend/zend_llist.h 2005-09-07 13:49:17.000000000 +0200
6596@@ -23,6 +23,9 @@
6597 #define ZEND_LLIST_H
6598
6599 typedef struct _zend_llist_element {
6600+#if HARDENING_PATCH_LL_PROTECT
6601+ unsigned int canary;
6602+#endif
6603 struct _zend_llist_element *next;
6604 struct _zend_llist_element *prev;
6605 char data[1]; /* Needs to always be last in the struct */
6606@@ -35,6 +38,9 @@
6607 typedef void (*llist_apply_func_t)(void * TSRMLS_DC);
6608
6609 typedef struct _zend_llist {
6610+#if HARDENING_PATCH_LL_PROTECT
6611+ unsigned int canary_h; /* head */
6612+#endif
6613 zend_llist_element *head;
6614 zend_llist_element *tail;
6615 size_t count;
6616@@ -42,6 +48,9 @@
6617 llist_dtor_func_t dtor;
6618 unsigned char persistent;
6619 zend_llist_element *traverse_ptr;
6620+#if HARDENING_PATCH_LL_PROTECT
6621+ unsigned int canary_t; /* tail */
6622+#endif
6623 } zend_llist;
6624
6625 typedef zend_llist_element* zend_llist_position;
6626diff -Nura php-5.0.5/Zend/zend_modules.h hardening-patch-5.0.5-0.4.2/Zend/zend_modules.h
6627--- php-5.0.5/Zend/zend_modules.h 2005-03-16 00:47:12.000000000 +0100
6628+++ hardening-patch-5.0.5-0.4.2/Zend/zend_modules.h 2005-09-07 13:49:17.000000000 +0200
6629@@ -38,6 +38,7 @@
6630 extern struct _zend_arg_info fourth_arg_force_ref[5];
6631 extern struct _zend_arg_info all_args_by_ref[1];
6632
6633+#define HARDENING_PATCH_ZEND_MODULE_API_NO 1002050805
6634 #define ZEND_MODULE_API_NO 20041030
6635 #ifdef ZTS
6636 #define USING_ZTS 1
6637@@ -45,10 +46,10 @@
6638 #define USING_ZTS 0
6639 #endif
6640
6641-#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
6642-#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
6643+#define STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, NULL
6644+#define ZE2_STANDARD_MODULE_HEADER sizeof(zend_module_entry), HARDENING_PATCH_ZEND_MODULE_API_NO, ZEND_DEBUG, USING_ZTS, ini_entries
6645
6646-#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0
6647+#define STANDARD_MODULE_PROPERTIES_EX 0, 0, 0, NULL, 0, ZEND_MODULE_API_NO
6648
6649 #define STANDARD_MODULE_PROPERTIES \
6650 NULL, STANDARD_MODULE_PROPERTIES_EX
6651@@ -81,6 +82,7 @@
6652 unsigned char type;
6653 void *handle;
6654 int module_number;
6655+ unsigned int real_zend_api;
6656 };
6657
6658
6659diff -Nura php-5.0.5/Zend/zend_opcode.c hardening-patch-5.0.5-0.4.2/Zend/zend_opcode.c
6660--- php-5.0.5/Zend/zend_opcode.c 2004-06-06 10:37:12.000000000 +0200
6661+++ hardening-patch-5.0.5-0.4.2/Zend/zend_opcode.c 2005-09-07 13:49:17.000000000 +0200
6662@@ -92,6 +92,9 @@
6663 op_array->uses_this = 0;
6664
6665 op_array->start_op = NULL;
6666+#if HARDENING_PATCH
6667+ op_array->created_by_eval = 0;
6668+#endif
6669
6670 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
6671 }